我正在探索Java 8源代码,发现代码的这一特定部分非常令人惊讶:
//defined in IntPipeline.java
@Override
public final OptionalInt reduce(IntBinaryOperator op) {
return evaluate(ReduceOps.makeInt(op));
}
@Override
public final OptionalInt max() {
return reduce(Math::max); //this is the gotcha line
}
//defined in Math.java
public static int max(int a, int b) {
return (a >= b) ? a : b;
}
Run Code Online (Sandbox Code Playgroud)
是Math::max什么样的方法指针?普通static方法如何转换为IntBinaryOperator?
我正在寻找一种通过引用传递方法的方法.我知道Java不会将方法作为参数传递,但是,我想获得一个替代方案.
我被告知接口是将方法作为参数传递的替代方法,但我不明白接口如何通过引用充当方法.如果我理解正确,接口只是一组未定义的抽象方法.我不希望每次都发送需要定义的接口,因为几种不同的方法可以使用相同的参数调用相同的方法.
我想要完成的是类似的事情:
public void setAllComponents(Component[] myComponentArray, Method myMethod) {
for (Component leaf : myComponentArray) {
if (leaf instanceof Container) { //recursive call if Container
Container node = (Container) leaf;
setAllComponents(node.getComponents(), myMethod);
} //end if node
myMethod(leaf);
} //end looping through components
}
Run Code Online (Sandbox Code Playgroud)
调用如:
setAllComponents(this.getComponents(), changeColor());
setAllComponents(this.getComponents(), changeSize());
Run Code Online (Sandbox Code Playgroud) 阅读Java-8规范,我不断看到对"SAM类型"的引用.我无法找到明确解释这是什么.
什么是SAM类型以及什么是何时可以使用的示例场景?
我知道界面就像100%纯抽象类.所以,它不能有方法实现.但是,我看到了一个奇怪的代码.有人能解释一下吗?
代码片段:
interface Whoa {
public static void doStuff() {
System.out.println("This is not default implementation");
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:
我的IDE是Intellij Idea 13.1.项目SDK是java 7 <1.7.0_25>.IDE未显示任何编译器错误.但是,当我在命令行编译代码时,我收到以下消息.
Run Code Online (Sandbox Code Playgroud)Whoa.java:2: error: modifier static not allowed here public static void doStuff() { ^
我来自JavaScript,其中回调非常简单.我试图将它们实现到JAVA中,但没有成功.
我有一个Parent类:
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Server {
ExecutorService workers = Executors.newFixedThreadPool(10);
private ServerConnections serverConnectionHandler;
public Server(int _address) {
System.out.println("Starting Server...");
serverConnectionHandler = new ServerConnections(_address);
serverConnectionHandler.newConnection = function(Socket _socket) {
System.out.println("A function of my child class was called.");
};
workers.execute(serverConnectionHandler);
System.out.println("Do something else...");
}
}
Run Code Online (Sandbox Code Playgroud)
然后我有一个从父级调用的子类:
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
public class ServerConnections implements Runnable {
private int serverPort;
private ServerSocket mainSocket;
public ServerConnections(int _serverPort) {
serverPort = _serverPort;
} …Run Code Online (Sandbox Code Playgroud) 我已经遇到了一些代码,我不能在这里分享,但它声明的方法WITHIN另一种方法的放慢参数列表.我甚至都不知道这是可能的.我真的不明白为什么这样做.有人可以向我解释一下你作为程序员可能会做的一些可能的用途吗?(注意:因为我无法显示代码,所以我不希望在上下文中解释一般)
我有一堂有很多方法的课程。在另一个类中,我需要编写一个处理输入值的方法。对于该方法,我想传递我想要调用的类的方法。1.8 之后的 Java 如何做到这一点?
已经有类似的问题了,但这些问题通常假设我们可以使用具有单个方法的接口,因此可以使用 lambda 表达式等。
class MyClass {
public Object myToString(String a) {
return new String(a);
}
public Object myToString(String a, String b) {
return new String(a + ", " + b);
}
public Object mySum(int a) {
return new Integer(a);
}
public Object mySum(int a, int b) {
return new Integer(a + b);
}
}
class Test {
public Object handleInputs(MyClass myClass, MethodAsParameter theMethod, List<Object> inputs) {
if (type of inputs are Strings) {
myClass.myToString(inputs.get(0));
} else …Run Code Online (Sandbox Code Playgroud) 我有一个Kotlin代码:
fun showAdWithCallback(callback:() -> Unit) {
if (AdsPrefs.shouldShowInterstitialAd()) {
mInterstitialAd.show()
this.callback = callback
} else {
callback()
}
}
Run Code Online (Sandbox Code Playgroud)
现在,我想从Java类中调用此方法。我对如何称呼它感到困惑。这是我尝试过的
showAdWithCallback(() -> {
return null;
});
Run Code Online (Sandbox Code Playgroud)
但是它显示以下错误。
我有以下方法:
public String getAllDangerousProductsName(Offer offer){
return offer.getOfferRows().stream()
.filter(row -> row.isDangerousGood())
.map(row -> row.getItemInformation().getOfferTexts().getName())
.collect(Collectors.joining(","));
}
Run Code Online (Sandbox Code Playgroud)
我想为 row.isBulkyGood() 重用这个方法。我目前正在做的是
public String getAllBulkyProductsName(Offer offer){
return offer.getOfferRows().stream()
.filter(row -> row.isBulkyGood())
.map(row -> row.getItemInformation().getOfferTexts().getName())
.collect(Collectors.joining(","));
}
Run Code Online (Sandbox Code Playgroud)
...这基本上是代码重复。有没有办法可以将函数作为方法参数传递来优化它,以便对两种过滤条件都有一种方法?
我阅读了关于将函数作为参数传递的下一个答案.
不过,我不明白这个想法.我的函数可以得到任何函数:sin(x),cos(x)等.
据我所知,我可以创建一个界面,例如:
public interface functionI<T> {
}
Run Code Online (Sandbox Code Playgroud)
这将包装它.
现在我有我的功能:
public void needToDo(functionI<Integer> a, int x0Par, int hPar){
}
Run Code Online (Sandbox Code Playgroud)
(needToDo,例如,需要替换函数n x0par和hPar的x,并找到Max.如果我得到sin(x),我需要找到sin(x0Par)和(sin(hPar))的最大值.
我不明白我在我的功能中如何使用它.当我得到函数时,我怎么知道该怎么做,可以是任何东西(多项式,sin(x)等)
在 Java 中,我想定义一个规范化函数,该函数将一个数字作为输入,但其行为由多个参数定义。
本质上,在 Lisp 中的 Java 等价物是:
(define (normalizeVal min max floor ceiling)
(lambda (x) (/ (* (- ceiling floor) (- x min)) (+ (- max min) floor))))
Run Code Online (Sandbox Code Playgroud)
在伪代码中,我想:
function parsing(data, normalizeValFunc) {
for (datum in data):
normalizeValFunc(datum);
}
var input = userData;
var min, max, floor, ceiling = /* Calculate min, max, floor, and ceiling */
var output = parsing(input, normalizeValFunc(min, max, floor, ceiling));
Run Code Online (Sandbox Code Playgroud)
在 Java 中将函数作为参数传递可能很棘手,因为函数在 Java 中不是一等对象。(也许 Java 8 Lambda 表达式会改变这一点?)其他问题解决了在 Java …
可能重复:
Java中函数指针的最接近的替代是什么?
我只是有一种情况,如果你可以在c或c ++中使用类似于函数指针的功能,那就太好了.我能想到的最好的事情是组合Runnables并在不同的线程中启动它们.建议?
我的collect()函数调用Foo.f().我想让Foo.f()自己成为我的功能参数.这在Java中可行吗?
Foo.f()或Foo.g()(或任何其他函数Foo返回a String)传递给我的函数?.
class Foo {
public String f() { return "f"; }
public String g() { return "g"; }
// ...
}
public List<String> collect(List<Foo> foos)
{
List<String> result = new ArrayList<String>();
for (final Foo foo: foos) {
result.add(foo.f()); // I want Foo.f to be a parameter
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
更新
我想指出的事实是,我不只是调用相同的函数,而是调用集合中f所有项的成员函数List<Foo>.