标签: method-reference

如何在Java 8中将[TypeArguments]与构造函数引用一起使用?

Java语言规范Java 8的第15.13节描述了这种形式的方法参考语法,用于创建构造函数引用:

    ClassType :: [TypeArguments] new
Run Code Online (Sandbox Code Playgroud)

例如:

    String s = "abc";
    UnaryOperator<String> test0 = String::new; // String(String) constructor.
    String s0 = test0.apply(s);
    System.out.println("s0 = " + s0); // Prints "abc".

    char[] chars = {'x','y','z'};
    Function<char[], String> test1 = String::new; // String(char[]) constructor.
    String s1 = test1.apply(chars);
    System.out.println("s1 = " + s1); // Prints "xyz"
Run Code Online (Sandbox Code Playgroud)

一切正常,但似乎绝对任何东西(不包括原语)也可以为[TypeArguments]提供,一切仍然有效:

这是一个愚蠢的例子来证明这一点:

    Function<String, String> test2 = String::<LocalDateTime, Thread[]>new; // Compiles !!!???
    String s2 = test2.apply("123");
    System.out.println("s2 = " + s2); // Prints "123"
Run Code Online (Sandbox Code Playgroud)

提出几个问题: …

java-8 method-reference constructor-reference

2
推荐指数
1
解决办法
145
查看次数

在流操作中使用方法引用和函数对象之间的区别?

当使用Java 8流时,我经常发现我需要重构一个多语句lambda表达式.我将用一个简单的例子来说明这一点.假设我已经开始编写这段代码:

Stream.of(1, 3).map(i -> {
    if (i == 1) {
        return "I";
    } else if (i == 3) {
        return "E";
    }
    return "";
}).forEach(System.out::println);
Run Code Online (Sandbox Code Playgroud)

现在我不太喜欢map通话中的大型lambda表达式.因此,我想把它重构出来.我看到两个选项,要么我Function在我的班级中创建一个实例:

private static Function<Integer, String> mapper = i -> {
    if (i == 1) {
        return "I";
    } else if (i == 3) {
        return "E";
    }
    return "";
};
Run Code Online (Sandbox Code Playgroud)

并像这样使用它:

Stream.of(1, 3).map(mapper).forEach(System.out::println);
Run Code Online (Sandbox Code Playgroud)

或者我只是制作一个方法:

private static String map(Integer i) {
    if (i == 1) {
        return "I";
    } else if …
Run Code Online (Sandbox Code Playgroud)

java lambda java-8 method-reference

2
推荐指数
2
解决办法
309
查看次数

Java7:等效于在函数调用中指定方法引用

我想编写一个在适当的对象上调用指定方法的方法。
需要注意的是,我希望在不更改调用方法的类(例如,实现接口)的情况下执行此操作。

我在C的函数指针中找到了想要的东西,但对于Java 7却没有找到。

这里是一些伪代码:

public class A {
    ... constructor ...

    public String aToString(){
        return "A";
    }
}

public class B {
    ... constructor ...

    public String bToString(){
        return "B";
    }
}
/* T::<String>mymethod stands for "Method with identifier 'mymethod'
 * in Class T with return type String"
 */
public class ServiceClass {
    public static void genericToString(Collection<T> c, 
                                       MethodPointer T::<String>mymethod){
        for(int i=0,i<c.length,i++) {
            System.out.println(c.get(i).mymethod());

        }
    }

    public static void main(){
        ArrayList<A> listA = new ArrayList<A>();
        listA.add(new A());
        ServiceClass.genericToStringOutput(listA, A::<String>aToString); …
Run Code Online (Sandbox Code Playgroud)

java java-7 method-reference

2
推荐指数
1
解决办法
1288
查看次数

使用比较器对流排序的方法

我不明白为什么code1工作但code2不编译.请解释.

//Code1:
    Stream<String> s = Stream.of("AA", "BB");
    s.sorted(Comparator.reverseOrder())
            .forEach(System.out::print);

//Code2:
    Stream<String> s = Stream.of("AA", "BB");
    s.sorted(Comparator::reverseOrder)
            .forEach(System.out::print);
Run Code Online (Sandbox Code Playgroud)

两者之间的区别是code2使用Comparator.reverseOrder()code1使用Comparator::reverseOrder

java java-stream method-reference

2
推荐指数
2
解决办法
1294
查看次数

是否可以使用方法引用和接口的静态方法?

这是我的第一个代码:

public class MethodReference {
    public static void main (String []args) {
        Stream<String> s = Stream.of("brown bear", "grizzly");
        s.sorted(Comparator.reverseOrder()).forEach(System.out::print);
        //...
    }
}
Run Code Online (Sandbox Code Playgroud)

结果:灰熊熊

这是我的第二个代码:

public class MethodReference {
    public static void main (String []args) {
        Stream<String> s = Stream.of("brown bear", "grizzly");
        s.sorted(Comparator::reverseOrder()).forEach(System.out::print);
        //...
    }
}
Run Code Online (Sandbox Code Playgroud)

结果:编译器错误

我的问题:为什么第二个代码中存在编译器错误?我不能将方法参考用于功能接口的静态方法吗?

我知道我不能使用方法引用和函数接口的默认方法.我知道我可以在5种情况下使用类的方法引用:

  • 类:: STATICMETHOD

  • 类:: instanceMethod

  • 例如:: instanceMethod

  • 类::新

功能界面

  • 接口:: abstractMethod

非常感谢!

java lambda method-reference

2
推荐指数
1
解决办法
76
查看次数

Kotlin setOnClickListener 使用方法引用不起作用

我尝试以与 Java 中相同的方式使用方法引用:

button.setOnClickListener(this::clickListener);
Run Code Online (Sandbox Code Playgroud)

使用科特林:

button.setOnClickListener {this::clickListener}
Run Code Online (Sandbox Code Playgroud)

但是这在 Kotlin 中不起作用,解决方案是使用 labmda 表达式实际调用函数:

button.setOnClickListener {clickListener()}
Run Code Online (Sandbox Code Playgroud)

为什么 Kotlin 在这种情况下不接受方法引用?和Java的原理不一样吗?

java android kotlin method-reference

2
推荐指数
2
解决办法
4563
查看次数

为什么我不能使用LinkedList :: new?

假设我有一个HashMap作为Map<Integer, List<Integer>> map = new HashMap<>();

现在List<Integer> values = computeIfAbsent(key, ArrayList::new);可以正常工作,但是List<Integer> values = computeIfAbsent(key, LinkedList::new);会引发编译错误。

我可以在ArrayList和LinkedList中看到no-arg构造函数。我在这里想念的是什么,有人可以解释这种现象吗?

java java-8 method-reference

2
推荐指数
1
解决办法
100
查看次数

将使用者与不同的参数或不同的参数编号组合

假设我们的方法接收输入 String并返回一些List output。此输出是一些生成器的结果,其中一些生成器取决于输入,而有些则不取决于输入-它们只是添加预定义的值。我想将这些生成器实现为一些函数接口的列表(例如,Consumer),然后将它们组合到一个Consumer中,然后将其应用于输入String。

因此,我将能够轻松,独立地更换小型发电机。但是问题在于,并非我的所有生成器都需要输入 String作为参数,而我只是出于一个原因就将这个参数传递给了它-能够将此类使用者与其他使用者组合在一起。

public class ConsumersTest {

private static <T, U> BiConsumer<T, U> combine(List<BiConsumer<T, U>> consumers) {
    return consumers.stream().reduce((arg1, arg2) -> {}, BiConsumer::andThen);
}

List<String> generate(String input) {
    ArrayList<String> output = new ArrayList<>();
    combine(getGenerators()).accept(input, output);
    return output;
}

private List<BiConsumer<String, List<String>>> getGenerators() {
    return Arrays.asList(
            this::addFirstDependent,
            this::addSecondIndependent
    );
}

private void addFirstDependent(String input, List<String> output) {
    if (input.contains("some string")) {
        output.add("First-Dependent");
    }
}

private void addSecondIndependent(String input, List<String> output) {
    output.add("Predefined Output");
}}
Run Code Online (Sandbox Code Playgroud)

是否可以将不同的消费者合并到一个保护伞下并在一个地方应用?还是这是一个坏主意,而不是正确的方法?

java lambda java-8 functional-interface method-reference

2
推荐指数
1
解决办法
73
查看次数

带有方法参考的 Java 8 比较器

试图理解方法引用,但我很难理解。坚持比较器示例。

为了让我的大脑更轻松,我一直从基础开始(匿名类实现 >> laba 表达式 >> 方法引用)它是方法引用和比较器示例,我无法让它工作。

我想排序的 POJO(从一些互联网示例中提取 - mkyong)

public class Fruit{
   private int quantity;
   private String name;
   ....
}
Run Code Online (Sandbox Code Playgroud)

创建要使用的测试数据:

Fruit[] fruits = new Fruit[3];
Fruit pineapple = new Fruit("pineapple",10);
Fruit orange= new Fruit("orange",4);
Fruit kiwi= new Fruit("kiwi",15);

fruits[0] = pineapple;
fruits[1] = orange;
fruits[2] = kiwi;
Run Code Online (Sandbox Code Playgroud)

匿名排序类实现:

Comparator<Fruit> anonymousSortByname = new Comparator<Fruit>(){
     public int compare(Fruit f1,Fruit f2){
        return f1.getName().compareTo(f2.getName());
     }
};
Run Code Online (Sandbox Code Playgroud)

排序 :

Arrays.sort(fruits,anonymousSortByname);
Run Code Online (Sandbox Code Playgroud)

既然这可行,我已经明白匿名类可以转换为 lambda 表达式(前提是它们是功能接口等......)

Lambda 实现:

Comparator<Fruit> lambdaSortByname = 
 (Fruit f1,Fruit f2) -> …
Run Code Online (Sandbox Code Playgroud)

lambda java-8 method-reference

2
推荐指数
1
解决办法
2978
查看次数

为什么方法引用与带有不同数量args的功能接口兼容?

我了解,如果所引用的方法与功能接口具有相同数量的args并返回相同的类型,则可以使用方法引用来实现功能接口,但是为什么在某些情况下,所引用的方法与功能接口具有不同数量的args但仍然兼容吗?

我有一个简单的BiConsumer,我尝试使用方法引用来实现它。我知道只要args的数量匹配,我也可以使用lambda表达式。我将显示代码以清楚地说明它。

我有一个BiConsumer<ArrayList<String>, ? super String>我要实现的。

Lambda表达式的实现方式是:

BiConsumer<ArrayList<String>, ? super String> b = (firstArg,secondArg) -> firstArg.add(secondArg); 由于它们都带有2个输入参数,因此没有问题。

但是为什么BiConsumer<ArrayList<String>, ? super String> a = ArrayList::add;也兼容?addArrayList上的方法仅需要1个输入args,而功能接口则需要2个。

任何答案将不胜感激。谢谢!

java java-8 functional-interface method-reference

2
推荐指数
2
解决办法
91
查看次数