源代码(当然项目还有很多其他类)
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Stream;
public class Test {
public static void main(String[] args) {
Map<Integer, Integer> src = new HashMap<>();
Map<Integer, List<Integer>> dst = new HashMap<>();
Optional<Object> f = dst.values().stream().flatMap((Function<List<Integer>, Stream<?>>) integers -> integers.stream()).filter(b -> !src.containsKey(b)).findFirst();
f.ifPresent(b -> {
throw new IllegalStateException("exception [" + b + "]");
});
}
}
1.将项目复制到不同的路径
d:\用户\壳\文件\工作场所\ BAK \ 1
d:\用户\壳\文件\工作场所\ BAK \ 2
2.在两个路径中执行mvn包
3.检查类文件
在 d:\ Users \ shell \ Documents \ workplace \ bak \ 1 \ data \ target \ classes
执行命令javap -ppublic class Test {
public Test();
public static void main(java.lang.String[]);
private static void lambda$main$84(java.lang.Object);
private static boolean lambda$main$83(java.util.Map, java.lang.Object);
private static java.util.stream.Stream lambda$main$82(java.util.List);
}
在 d:\ Users \ shell \ Documents \ workplace \ bak \ 2 \ data \ target \ classes
执行命令javap -ppublic class Test {
public Test();
public static void main(java.lang.String[]);
private static void lambda$main$75(java.lang.Object);
private static boolean lambda$main$74(java.util.Map, java.lang.Object);
private static java.util.stream.Stream lambda$main$73(java.util.List);
}
为什么lambda函数的数量不同?
有什么方法可以让它们变得相同吗?
答案 0 :(得分:13)
查看javac源代码,您可能会注意到the corresponding counter(附加到lambda方法名称)被定义为$ grep -w -f f1 f2
2015-10-30,1234,zxcfgdk,kyfz
2015-10-30,2567,askjfkj,aaaa
$ grep -v -w -f f1 f2
2015-10-30,8888,bsjfjah,iojk
中的一个实例字段,该字段在整个编译过程中被重用。它会在每次lambda事件中递增。所以如果我只编译你的类,我会从0开始编号:
LambdaAnalyzerPreprocessor
但是,如果我再创建一个类
> javac Test.java
> javap -p Test
Compiled from "Test.java"
public class Test {
public Test();
public static void main(java.lang.String[]);
private static void lambda$main$2(java.lang.Object);
private static boolean lambda$main$1(java.util.Map, java.lang.Object);
private static java.util.stream.Stream lambda$main$0(java.util.List);
}
将它们编译在一起我会看到计数器递增:
public class Test2 {
Runnable r = () -> {};
}
所以这不是maven问题,这就是javac编译器的工作原理。
如果您肯定需要稳定的编译结果,我建议您尝试使用Eclipse Compiler for Java。似乎没有这样的问题:
> javac Test2.java Test.java
> javap -p Test
Compiled from "Test.java"
public class Test {
public Test();
public static void main(java.lang.String[]);
private static void lambda$main$3(java.lang.Object);
private static boolean lambda$main$2(java.util.Map, java.lang.Object);
private static java.util.stream.Stream lambda$main$1(java.util.List);
}
关于如何将ecj与maven集成,请参阅this question。
答案 1 :(得分:0)
FWIW,这曾经是由 OpenJDK 中的错误引起的。已于 2016 年 12 月修复:https://bugs.openjdk.java.net/browse/JDK-8067422
<块引用>目前,当生成 lambda 名称(对于不可序列化的 lambda)时,确切的名称取决于当前 javac 实例到目前为止生成的(不可序列化的)lamdbas 的数量。原因是 lambda 名称的计数器不是每个文件,而是每个 javac 实例。例如,考虑:
public class L1 {
private Runnable r = () -> { };
}
public class L2 {
private Runnable r = () -> { };
}
doing: javac L1.java L2.java
将使 L1 的 lambda 使用 lambda$new$0
和 L2 的 lambda$new$1
,而:javac L2.java L1.java
将导致相反的名称分配。
问题似乎很简单:LambdaToMethod.LambdaAnalyzerPreprocessor.lambdaCount
在开始新的顶级之前没有重置。