【问题标题】:Non-static method cannot be referenced from a static context inside Collectors.toMap不能从 Collectors.toMap 内的静态上下文中引用非静态方法
【发布时间】:2019-01-07 21:40:56
【问题描述】:

我有一个学生列表,我想将其转换为Map<String, Integer>,其中映射键应该是学生的名字。为了使代码示例简单,我将映射值指定为1

final Map<String, Integer> map = someStudents.stream().collect(
        Collectors.toMap(Student::getFirstName, 1));

编译器抱怨:

不能从静态上下文引用非静态方法 getFirstName()

有什么想法吗?我很困惑,因为许多示例都使用相同的方法来传递对非静态方法的引用。为什么编译器会在这里看到静态上下文?

【问题讨论】:

  • 可惜这个错误报错地方太多次了
  • 这很有趣@Eugene。
  • Emdee,你能发布完整的代码吗?

标签: java java-stream


【解决方案1】:

The value mapper should be a function,即:

.collect(Collectors.toMap(Student::getFirstName, s -> 1));

函数s -&gt; 1 本质上将学生作为输入,并在此特定情况下为地图值返回1

以下代码无效,因为字面值 1 不是函数。

.collect(Collectors.toMap(Student::getFirstName, 1));

【讨论】:

  • 您对第二个参数是正确的,但第一个参数必须通过对象引用访问。或者,getFirstName 必须是静态的。
  • @mnmopazem Student::getFirstName 没有错,实际上它等同于student -&gt; student.getFirstName(),它确实是一个对象引用。
  • 使用类名访问静态成员。在这种情况下,类名是Student,注意大小写。
  • @mnmopazem “或者,getFirstName 必须是静态的。”如果getFirstName 被定义为static String getFirstName() {...} 它会产生一个编译错误,首先是你不能在静态方法中访问实例字段,其次是在toMap 收集器中。该方法可以是 static 并且仍然有效的唯一情况是,如果您将其定义为 --> static String getFirstName(Student s) { return s.getFirstName(); },当您可以简单地将实例 getter 方法定义为 public String getFirstName() { return firstName; } 时,我不建议这样做
  • 这很有趣,因为编译器错误与方法引用访问类型相矛盾。可能是,OP 在不同的线路上有错误?!你怎么看?
【解决方案2】:

首先,您使用类名 -Student(好像它是一个静态成员)而不是使用对象引用来访问 getFirstNameJava tutorial - Method Refrences.
其次,toMap方法的第二个参数必须是Function类型。

所以,正确的说法是:
someStudents.stream().collect( Collectors.toMap( student -&gt; student.getFirstName(), student -&gt; 1 ) );

编辑:
或者,它也可以由@Aomine 发布。两个答案都是正确的。有关更多信息,请参阅 @Aomine 的答案中的 cmets。

编辑 2:
虽然,@Aomine 和这个答案给出了预期的结果,但请注意第一个参数的差异。

【讨论】:

  • Student::getFirstName student -&gt; student.getFirstName()是一回事
  • 不,它不同。为简单起见,让讨论从您的答案开始...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多