标签: method-reference

为什么方法引用可以使用非最终变量?

我对内部类和lambda表达有些困惑,我试着问一个问题,然后又出现了另一个疑问,并且可能更好地发布另一个问题,而不是评论前一个问题.

直截了当:我知道(谢谢Jon)这样的事情无法编译

public class Main {
    public static void main(String[] args) {
        One one = new One();

        F f = new F(){      //1
            public void foo(){one.bar();}   //compilation error
        };

        one = new One();
    }
}

class One { void bar() {} }
interface F { void foo(); }
Run Code Online (Sandbox Code Playgroud)

由于Java如何管理闭包,因为one不是[有效]最终等等.

但是,这怎么允许的呢?

public class Main {
    public static void main(String[] args) {
        One one = new One();

        F f = one::bar; //2

        one = …
Run Code Online (Sandbox Code Playgroud)

java lambda closures java-8 method-reference

32
推荐指数
3
解决办法
2021
查看次数

如何在静态导入中使用方法引用?

在java中使用map函数时,我可以执行以下操作:

import com.example.MyClass;

someStream.map(MyClass::myStaticMethod)
Run Code Online (Sandbox Code Playgroud)

但是在我的项目中我们有时会使用静态导入,当导入是静态的时候如何引用myStaticMethod呢?

我认为这会起作用,但它不会:

import static com.example.MyClass.myStaticMethod;

someStream.map(myStaticMethod); //does not compile
Run Code Online (Sandbox Code Playgroud)

为什么这不起作用?我是否仍然坚持使用第一个例子或是否有其他解决方案.

java lambda java-8 method-reference

30
推荐指数
1
解决办法
1827
查看次数

使用本地类时构造函数引用无效?

给出以下代码:

package com.gmail.oksandum.test;

import java.util.ArrayList;
import java.util.List;

public class Test {

    public static void main(String[] args) {
    }

    public void foo() {
        class LocalFoo {

            LocalFoo(String in) {
                //Some logic
            }

        }

        List<String> ls = new ArrayList<>();
        ls.stream().map(LocalFoo::new); //Line 21
    }

}
Run Code Online (Sandbox Code Playgroud)

我的IDE没有给我任何错误.也就是说,直到我尝试构建项目并运行它.当我这样做它给我一个编译器错误,如下所示:

Error:(21, 24) java: incompatible types: cannot infer type-variable(s) R
    (argument mismatch; invalid constructor reference
      cannot access constructor LocalFoo(java.lang.String)
        an enclosing instance of type com.gmail.oksandum.test.Test is not in scope)
Run Code Online (Sandbox Code Playgroud)

现在,我想,给出错误消息,如果foo()是静态的,这不会发生.而且非常正确,只有当foo()是实例方法时才会发生这种情况.只有当LocalFoo是实例方法中的本地类时才会发生,并且只有在使用构造函数引用时才会发生(即从不是常规方法引用).

更重要的是,如果我将第21行改为

ls.stream().map(str -> new LocalFoo(str));
Run Code Online (Sandbox Code Playgroud)

编译器突然没有错误.

所以回顾一下.如果我尝试在实例方法中声明的本地类上使用构造函数引用,编译器会抱怨无法访问构造函数,我很困惑.

如果有人能够阐明为什么会发生这种情况,我们将不胜感激.谢谢.

java lambda java-8 method-reference constructor-reference

28
推荐指数
1
解决办法
1702
查看次数

静态上下文无法访问收集器中的非静态

我有一群学生.首先,我想用标记对它们进行分组.然后我想进一步将这些集合分组到同名学生中.

   Map<Integer,Map<String,List<String>>> groupping = students.stream()
                                                        .collect(Collectors.groupingBy(Student::getMarks, 
                                                                Collectors.mapping(Student::getName,Collectors.toList())));
Run Code Online (Sandbox Code Playgroud)

我收到一个错误说,

非静态方法不能从静态上下文中引用.

是.我非常清楚,如果没有实例,我就无法引用非静态方法.但是对于所有这些流操作,我真的很困惑.

而不是如何解决这个问题; 我真的想知道这里发生了什么.您的任何投入都表示赞赏!

因为如果我写下面的分组是完全有效的;

    Map<Integer,List<Student>> m = students.stream().
            collect(Collectors.groupingBy(Student::getMarks));
Run Code Online (Sandbox Code Playgroud)

这是我的Student.java类(如果你需要的话)

public class Student {

    private String name;
    private int marks;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getMarks() {
        return marks;
    }

    public void setMarks(int marks) {
        this.marks = marks;
    }

    public Student(String name, int marks) {

        this.name = name;
        this.marks = marks;
    }

    @Override
    public String toString() { …
Run Code Online (Sandbox Code Playgroud)

collect java-8 java-stream method-reference

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

调用局部变量的Java 8方法引用

我正在学习Java 8,我遇到了一些我觉得有点奇怪的东西.

请考虑以下代码段:

private MyDaoClass myDao;

public void storeRelationships(Set<Relationship<ClassA, ClassB>> relationships) {
    RelationshipTransformer transformer = new RelationshipTransformerImpl();

    myDao.createRelationships(
            relationships.stream()
            .map((input) -> transformer.transformRelationship(input))
            .collect(Collectors.toSet())
    );
}
Run Code Online (Sandbox Code Playgroud)

基本上,我需要将调用的输入集映射relationships到不同的类型,以符合我正在使用的DAO的API.对于转换,我想使用RelationshipTransformerImpl我实例化为局部变量的现有类.

现在,这是我的问题:

如果我要修改上面的代码如下:

public void storeRelationships(Set<Relationship<ClassA, ClassB>> relationships) {
    RelationshipTransformer transformer = new RelationshipTransformerImpl();

    myDao.createRelationships(
            relationships.stream()
            .map((input) -> transformer.transformRelationship(input))
            .collect(Collectors.toSet())
    );

    transformer = null;  //setting the value of an effectively final variable
}
Run Code Online (Sandbox Code Playgroud)

我显然会得到一个编译错误,因为局部变量transformer不再是"有效的最终".但是,如果用方法引用替换lambda:

public void storeRelationships(Set<Relationship<ClassA, ClassB>> relationships) {
    RelationshipTransformer transformer = new RelationshipTransformerImpl();

    myDao.createRelationships(
            relationships.stream()
            .map(transformer::transformRelationship)
            .collect(Collectors.toSet()) …
Run Code Online (Sandbox Code Playgroud)

java lambda java-8 method-reference

25
推荐指数
3
解决办法
1539
查看次数

将java.util.function.Function转换为Interface

在这个(简化的)示例中,我可以MyInterface通过使用方法引用来创建我的对象apply,但是直接转换不起作用.

@Test
public void testInterfaceCast(){
    Function<String, Integer> func = Integer::parseInt;

    MyInterface legal = func::apply; // works
    MyInterface illegal = func; // error
}

public interface MyInterface extends Function<String, Integer>{}
Run Code Online (Sandbox Code Playgroud)

第二个赋值给出了编译器错误:

incompatible types: Function<String,Integer> cannot be converted to MyInterface
Run Code Online (Sandbox Code Playgroud)

这个问题

我可以做一些泛型魔法,能够投射Function<T, R>到界面吗?

java java-8 method-reference

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

无法解析org.eclipse.jdt.annotation.NonNull类型.它是从所需的.class文件间接引用的

当我使用Java 8方法引用双冒号operator(::)和new运算符(例如MyType::new)时,我在Spring of Spring Tool套件(STS)中遇到此错误:

无法解析org.eclipse.jdt.annotation.NonNull类型.它是从所需的.class文件间接引用的

如何摆脱这个错误?

java eclipse java-8 spring-tool-suite method-reference

24
推荐指数
3
解决办法
6041
查看次数

为什么invokeLater在主线程中执行?

我刚刚遇到这个"bug",但我不确定这是不是意图:代码:

public static Object someMethod(){
    assert SwingUtilities.isEventDispatchThread();
    return new Object();
}

public static void main(String[] args){
    SwingUtilities.invokeLater(() -> someMethod().toString());//First Example
    SwingUtilities.invokeLater(someMethod()::toString);//Second Example
}
Run Code Online (Sandbox Code Playgroud)

在第一个例子中someMethod是在swing线程上执行,但在第二个例子中它不是,虽然它应该在我看来.

这是一个错误还是这个?

java lambda multithreading java-8 method-reference

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

为什么Java 8为方法引用引入了新的"::"运算符?

在Java 8中,方法引用是使用::运算符完成的.

例如

// Class that provides the functionality via it's static method
public class AddableUtil {
  public static int addThemUp(int i1, int i2){
    return i1+i2;
  }
}

// Test class
public class AddableTest {
  // Lambda expression using static method on a separate class
  IAddable addableViaMethodReference = AddableUtil::addThemUp;
  ...
}
Run Code Online (Sandbox Code Playgroud)

你可以看到addableViaMethodReference现在的行为就像是一个别名AddableUtil::addThemUp.因此addableViaMethodReference()将执行相同的操作 AddableUtil.addThemUp()并返回相同的值.

他们为什么选择引入新的运营商而不是现有运营商?我的意思是,当函数名称结束时执行函数,()并在没有尾随时返回函数引用().

方法执行

AddableUtil.addThemUp();
Run Code Online (Sandbox Code Playgroud)

方法参考

AddableUtil.addThemUp;
Run Code Online (Sandbox Code Playgroud)

这不是更简单直观吗?AFAIK,AddableUtil.addThemUp当前不(Java 7)用于任何其他目的并抛出编译错误.为什么不利用这个机会而不是创建一个全新的运营商呢?

java java-8 method-reference

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

使用 Comparator.comparing(HashMap::get) 作为比较器时的意外行为

https://java-programming.mooc.fi/part-10/2-interface-comparable上做练习“文学”时,我在尝试对 HashMap 中的键值对进行排序时发现了一个非常奇怪的行为,而没有将任何内容复制到一个树形图。我应该通过创建 Book 类并将它们添加到 List 来添加书籍。但是我想在不创建新类的情况下尝试,所以选择了 HashMap。我的代码如下:

public class MainProgram {

public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);

    Map<String, Integer> bookshelf = new HashMap<>();
    while (true) {


        System.out.println("Input the name of the book, empty stops: ");
        String bookName = scanner.nextLine();
        if (bookName.equals("")) {
            break;
        }
        System.out.println("Input the age recommendation: ");
        int age = Integer.valueOf(scanner.nextLine());

        bookshelf.put(bookName, age);
    }

    System.out.println(bookshelf.size() + " book" + (bookshelf.size() > 1 ? "s" : "") + " in total."); …
Run Code Online (Sandbox Code Playgroud)

java sorting hashmap java-stream method-reference

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