如何将一个函数作为参数传递给另一个函数
How to pass a function as an parameter to another function
我想将一个函数作为参数传递给另一个函数。例如:
void myFunction(boolean coondition, void function())
{
if(condition) {
function();
}
}
在 Java 8 这可能吗?
是的,这是可能的。假设您的函数什么都不做,只需传递一个 Runnable
.
void myFunction(boolean condition, Runnable function)
{
if(condition) {
function.run();
}
}
假设你有一个名为function
的函数(void
可以替换为return类型,不会被使用):
private void function() {/*whatever*/}
你可以使用 lambda 表达式这样调用它
myFunction(true, () -> function());
或者像这样在 Java 1.1-1.7
myFunction(true, new Runnable(){public void run(){function();}});
不,你不能传递方法。
但是有一个简单的解决方法:传递一个 Runnable。
void myFunction(boolean coondition, Runnable function)
{
if(condition) {
function.run();
}
}
并这样称呼它:(使用旧语法)
myFunction(condition, new Runnable() {
@Override
public void run() {
otherFunction();
}
});
或在 Java 8 中使用新的 lambda 语法(上面的内容主要是 shorthand):
myFunction(condition, () -> {otherFunction();}}
在Java中,几乎所有东西都是对象(但原始类型除外)。但是您可以使用 functional interfaces 来处理 函数 。
在 Java 8 之前,已经有通过实例化匿名 类:
经常使用功能接口的用例
- callbacks/listeners 喜欢 ActionListener
- 或 Comparator 对集合进行排序。
如果你想传递一个函数作为参数,你有很多表达方式:
假设您想要在初始值满足某些条件(例如这是一个偶数)时应用某些函数(例如对值进行平方):
// Return the square of a number
static Function<Integer, Integer> square = new Function<Integer, Integer>() {
@Override
public Integer apply(Integer t) {
return t*t;
}
};
// Return true is the parameter is an even number
static Predicate<Integer> isEven = new Predicate<Integer>() {
@Override
public boolean test(Integer t) {
return (t % 2) == 0;
}
};
// A generic function that prints for each x of the list
// xtrans(x) only if pred(x) is true.
public static <T, R> void printIf(Predicate<T> pred, Function<T, R> xtrans, List<T> xs) {
for (T x : xs) {
if (pred.test(x)) {
System.out.print(xtrans.apply(x));
System.out.print(" ");
}
}
}
你可以测试一下:
public static void main(String[] args) {
List<Integer> ints = IntStream.range(0, 10)
.boxed()
.collect(Collectors.toList());
printIf(isEven, square, ints);
}
=> 0 4 16 36 64
这也可以用 lambdas 写成:
public static void main(String[] args) {
List<Integer> ints = IntStream.range(0, 10).boxed().collect(Collectors.toList());
Predicate<Integer> even = x -> (x % 2) == 0;
Function<Integer, Integer> square = x -> x*x;
printIf(even, square, ints);
}
或直接:
printIf(x -> (x % 2)==0, x -> x*x, ints);
并且您还可以将成员方法用作 函数,前提是它们具有函数式接口签名。
// Wrap a random integer between 0 and 10
public class Foo {
static Random gen = new Random();
int bar = gen.nextInt(10);
public void println() { System.out.println(bar); }
public int getBar() { return bar; }
}
// Execute doTo(x) if pred(x) is true
public static <T> void doToIf(Predicate<T> pred, Consumer<T> doTo, T x) {
if (pred.test(x)) {
doTo.accept(x);
}
}
在 10 个 Foo 对象的列表上测试它:
public static void main(String[] args) {
List<Foo> foos = IntStream.range(0, 10)
.mapToObj(i -> new Foo())
.collect(Collectors.toList());
for (Foo foo : foos) {
doToIf((Foo x) -> x.getBar() % 2 == 0, Foo::println, foo);
}
}
=> 6
2
0
0
4
可以缩短为:
public static void main(String[] args) {
IntStream.range(0, 10)
.mapToObj(i -> new Foo())
.filter((Foo x) -> x.getBar() % 2 == 0)
.forEach(Foo::println);
}
我想将一个函数作为参数传递给另一个函数。例如:
void myFunction(boolean coondition, void function())
{
if(condition) {
function();
}
}
在 Java 8 这可能吗?
是的,这是可能的。假设您的函数什么都不做,只需传递一个 Runnable
.
void myFunction(boolean condition, Runnable function)
{
if(condition) {
function.run();
}
}
假设你有一个名为function
的函数(void
可以替换为return类型,不会被使用):
private void function() {/*whatever*/}
你可以使用 lambda 表达式这样调用它
myFunction(true, () -> function());
或者像这样在 Java 1.1-1.7
myFunction(true, new Runnable(){public void run(){function();}});
不,你不能传递方法。
但是有一个简单的解决方法:传递一个 Runnable。
void myFunction(boolean coondition, Runnable function)
{
if(condition) {
function.run();
}
}
并这样称呼它:(使用旧语法)
myFunction(condition, new Runnable() {
@Override
public void run() {
otherFunction();
}
});
或在 Java 8 中使用新的 lambda 语法(上面的内容主要是 shorthand):
myFunction(condition, () -> {otherFunction();}}
在Java中,几乎所有东西都是对象(但原始类型除外)。但是您可以使用 functional interfaces 来处理 函数 。 在 Java 8 之前,已经有通过实例化匿名 类:
经常使用功能接口的用例- callbacks/listeners 喜欢 ActionListener
- 或 Comparator 对集合进行排序。
如果你想传递一个函数作为参数,你有很多表达方式:
假设您想要在初始值满足某些条件(例如这是一个偶数)时应用某些函数(例如对值进行平方):
// Return the square of a number
static Function<Integer, Integer> square = new Function<Integer, Integer>() {
@Override
public Integer apply(Integer t) {
return t*t;
}
};
// Return true is the parameter is an even number
static Predicate<Integer> isEven = new Predicate<Integer>() {
@Override
public boolean test(Integer t) {
return (t % 2) == 0;
}
};
// A generic function that prints for each x of the list
// xtrans(x) only if pred(x) is true.
public static <T, R> void printIf(Predicate<T> pred, Function<T, R> xtrans, List<T> xs) {
for (T x : xs) {
if (pred.test(x)) {
System.out.print(xtrans.apply(x));
System.out.print(" ");
}
}
}
你可以测试一下:
public static void main(String[] args) {
List<Integer> ints = IntStream.range(0, 10)
.boxed()
.collect(Collectors.toList());
printIf(isEven, square, ints);
}
=> 0 4 16 36 64
这也可以用 lambdas 写成:
public static void main(String[] args) {
List<Integer> ints = IntStream.range(0, 10).boxed().collect(Collectors.toList());
Predicate<Integer> even = x -> (x % 2) == 0;
Function<Integer, Integer> square = x -> x*x;
printIf(even, square, ints);
}
或直接:
printIf(x -> (x % 2)==0, x -> x*x, ints);
并且您还可以将成员方法用作 函数,前提是它们具有函数式接口签名。
// Wrap a random integer between 0 and 10
public class Foo {
static Random gen = new Random();
int bar = gen.nextInt(10);
public void println() { System.out.println(bar); }
public int getBar() { return bar; }
}
// Execute doTo(x) if pred(x) is true
public static <T> void doToIf(Predicate<T> pred, Consumer<T> doTo, T x) {
if (pred.test(x)) {
doTo.accept(x);
}
}
在 10 个 Foo 对象的列表上测试它:
public static void main(String[] args) {
List<Foo> foos = IntStream.range(0, 10)
.mapToObj(i -> new Foo())
.collect(Collectors.toList());
for (Foo foo : foos) {
doToIf((Foo x) -> x.getBar() % 2 == 0, Foo::println, foo);
}
}
=> 6 2 0 0 4
可以缩短为:
public static void main(String[] args) {
IntStream.range(0, 10)
.mapToObj(i -> new Foo())
.filter((Foo x) -> x.getBar() % 2 == 0)
.forEach(Foo::println);
}