相关疑难解决方法(0)

lambda表达式是否在每次执行时都在堆上创建一个对象?

当我使用Java 8的新语法糖迭代一个集合时,例如

myStream.forEach(item -> {
  // do something useful
});
Run Code Online (Sandbox Code Playgroud)

这不等同于下面的"旧语法"片段吗?

myStream.forEach(new Consumer<Item>() {
  @Override
  public void accept(Item item) {
    // do something useful
  }
});
Run Code Online (Sandbox Code Playgroud)

这是否意味着Consumer每次迭代集合时都会在堆上创建一个新的匿名对象?这需要多少堆空间?它有什么性能影响?这是否意味着我在迭代大型多级数据结构时应该使用旧样式for循环?

java lambda java-8

166
推荐指数
2
解决办法
3万
查看次数

如何序列化lambda?

我怎样才能优雅地序列化lambda?

例如,下面的代码抛出一个NotSerializableException.如何在不创建SerializableRunnable"虚拟"界面的情况下修复它?

public static void main(String[] args) throws Exception {
    File file = Files.createTempFile("lambda", "ser").toFile();
    try (ObjectOutput oo = new ObjectOutputStream(new FileOutputStream(file))) {
        Runnable r = () -> System.out.println("Can I be serialized?");
        oo.writeObject(r);
    }

    try (ObjectInput oi = new ObjectInputStream(new FileInputStream(file))) {
        Runnable  r = (Runnable) oi.readObject();
        r.run();
    }
}
Run Code Online (Sandbox Code Playgroud)

java lambda serialization java-8

152
推荐指数
4
解决办法
4万
查看次数

有没有办法比较lambdas?

假设我有一个使用lambda表达式(闭包)定义的对象列表.有没有办法检查它们,以便可以进行比较?

我最感兴趣的代码是

    List<Strategy> strategies = getStrategies();
    Strategy a = (Strategy) this::a;
    if (strategies.contains(a)) { // ...
Run Code Online (Sandbox Code Playgroud)

完整的代码是

import java.util.Arrays;
import java.util.List;

public class ClosureEqualsMain {
    interface Strategy {
        void invoke(/*args*/);
        default boolean equals(Object o) { // doesn't compile
            return Closures.equals(this, o);
        }
    }

    public void a() { }
    public void b() { }
    public void c() { }

    public List<Strategy> getStrategies() {
        return Arrays.asList(this::a, this::b, this::c);
    }

    private void testStrategies() {
        List<Strategy> strategies = getStrategies();
        System.out.println(strategies);
        Strategy a = (Strategy) …
Run Code Online (Sandbox Code Playgroud)

java lambda java-8

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

如何编译Java lambda函数?

Loop.times(5, () -> {
   System.out.println("looping");
});
Run Code Online (Sandbox Code Playgroud)

哪些有效编译到?

for(int i = 0; i < 5; i++)
    System.out.println("looping");
Run Code Online (Sandbox Code Playgroud)

或类似的东西

new CallableInterfaceImpl(){
    public void call(){
      for(int i = 0; i < 5; i++)
          System.out.println("looping");
    }
}.call();
Run Code Online (Sandbox Code Playgroud)

它会替换(内联类),还是实际创建一个匿名类?

java lambda java-8

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

JVM什么时候决定重用旧的lambda?

请考虑以下代码片段:

public static Object o = new Object();

public static Callable x1() {
    Object x = o;
    return () -> x;
}

public static Callable x2() {
    return () -> o;
}
Run Code Online (Sandbox Code Playgroud)

方法x2()将始终返回相同的lamba对象,而x1()始终会创建新的对象:

    System.out.println(x1());
    System.out.println(x1());
    System.out.println(x2());
    System.out.println(x2());
Run Code Online (Sandbox Code Playgroud)

会打印出这样的东西:

TestLambda$$Lambda$1/821270929@4a574795
TestLambda$$Lambda$1/821270929@f6f4d33
TestLambda$$Lambda$2/603742814@7adf9f5f
TestLambda$$Lambda$2/603742814@7adf9f5f
Run Code Online (Sandbox Code Playgroud)

哪里(在JVM规范中我猜?)是描述了这种lambda重用规则?JVM如何确定重用与否?

java lambda jvm java-8

21
推荐指数
3
解决办法
923
查看次数

两个确切的方法参考不相等

以下测试失败

@Test
public void test() {
    Function<String, Integer> foo = Integer::parseInt;
    Function<String, Integer> bar = Integer::parseInt;
    assertThat(foo, equalTo(bar));
}
Run Code Online (Sandbox Code Playgroud)

有没有办法让它通过?

编辑:我会尝试更清楚地说明我正在尝试做什么.

可以说我有这些课程:

class A {
  public int foo(Function<String, Integer> foo) {...}
}

class B {
  private final A a; // c'tor injected
  public int bar() {
    return a.foo(Integer::parseInt);
  }
}
Run Code Online (Sandbox Code Playgroud)

现在让我说我想为B编写单元测试:

@Test
public void test() {
  A a = mock(A.class);
  B b = new B(a);
  b.bar();
  verify(a).foo(Integer::parseInt);
}
Run Code Online (Sandbox Code Playgroud)

问题是测试失败,因为方法引用不相等.

java java-8

15
推荐指数
1
解决办法
3624
查看次数

如何删除用作侦听器的lambda表达式/方法句柄?

Java 8引入了lambda表达式,这是一件好事.但现在考虑重写这段代码:

class B implements PropertyChangeListener {
    void listenToA(A a) {
        a.addPropertyChangeListener(this);
    }

    void propertyChange(PropertyChangeEvent evt) {
        switch(evt.getPropertyName()) {
            case "Property1":
                doSomething();
                break;
            case "Property2":
                doSomethingElse();                case "Property1":
                doSomething;
                break;

                break;
    }

    void doSomething() { }
    void doSomethingElse() { }
}

class A {
    final PropertyChangeSupport pcs = new PropertyChangeSupport(this);

    void addPropertyChangeListener(PropertyChangeListener listener) {
        pcs.addPropertyChangeListener(listener);
    }

    void removePropertyChangeListener(PropertyChangeListener listener) {
        pcs.removePropertyChangeListener(listener);
    }
}
Run Code Online (Sandbox Code Playgroud)

随着lambda表达式和方法的引用,它已不再是需要有B落实PropertyChangeListner,我们可以写

class B {
    void listenToA(A a) {
        // using method …
Run Code Online (Sandbox Code Playgroud)

java lambda listener methodhandle

7
推荐指数
1
解决办法
2409
查看次数

标签 统计

java ×7

java-8 ×6

lambda ×6

jvm ×1

listener ×1

methodhandle ×1

serialization ×1