我对内部类和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中使用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)
为什么这不起作用?我是否仍然坚持使用第一个例子或是否有其他解决方案.
给出以下代码:
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)
编译器突然没有错误.
所以回顾一下.如果我尝试在实例方法中声明的本地类上使用构造函数引用,编译器会抱怨无法访问构造函数,我很困惑.
如果有人能够阐明为什么会发生这种情况,我们将不胜感激.谢谢.
我有一群学生.首先,我想用标记对它们进行分组.然后我想进一步将这些集合分组到同名学生中.
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) 我正在学习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) 例
在这个(简化的)示例中,我可以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 8方法引用双冒号operator(::)和new运算符(例如MyType::new)时,我在Spring of Spring Tool套件(STS)中遇到此错误:
无法解析org.eclipse.jdt.annotation.NonNull类型.它是从所需的.class文件间接引用的
如何摆脱这个错误?
我刚刚遇到这个"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 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)用于任何其他目的并抛出编译错误.为什么不利用这个机会而不是创建一个全新的运营商呢?
在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) method-reference ×10
java ×9
java-8 ×9
lambda ×5
java-stream ×2
closures ×1
collect ×1
eclipse ×1
hashmap ×1
sorting ×1