.forEach和.sort不起作用,无法在块中设置断点
我正在使用Java 8(内部版本1.8.0_25),Netbeans 8.0.2,并将Java
8的某些功能合并到现有应用程序中。排序和.forEach无法正常工作,因此我创建了一些测试代码以确保我了解lambda等,并诊断出问题。以下是新代码以及与我的系统中的数据进行交互的代码的组合:
public void test(Registration reg) {/* new code */
List<String> family = new ArrayList<>();
family.add("Mom");
family.add("Dad");
family.add("Brother");
family.add("Sister");
family.forEach(p -> System.out.println(p));
Collections.sort(family, (p1,p2) -> {
System.out.println(p1 + " <==> "+ p2);
return p1.compareToIgnoreCase(p2);
});
family.forEach(p -> System.out.println(p));
/* code to test with my system data */
List<RegistrationItem> item = new ArrayList<>();
List<RegistrationItem> regI = reg.getRegistrationItem();
regI.forEach(p -> {
System.out.println(p.toString());
item.add(p);
});
Collections.sort(regI, (r1,r2) -> {
System.out.println(r1.toString() + r2.toString());
return r1.getId().compareTo(r2.getId());
});
for (RegistrationItem r : regI) {
item.add(r);
}
}
注册是一个POJO,反映事件的数据,其中包括一个RegistrationItem(s)列表,这是另一个POJO细节。在此测试中,列表大小为4。
标有新代码的部分可以完美运行。它打印出列表,在排序时打印,然后打印排序后的列表。我还可以在期望的排序块内设置断点。
使用现有代码是另一回事。.forEach和.sort不起作用,我无法在Java
8块中设置断点。调试器将逐步执行代码,但似乎无法执行。当我进入for循环时,“
item”的大小仍为0。外观只是为了证明可以移动数据,该数据可以按预期工作,并且大小为4。
任何帮助,将不胜感激。
我很抱歉,可能不清楚。这只是测试代码,展示了自从更改为Java
8以来,我在数十个地方遇到的问题。比较器更改为lambda,并且for循环更改为.forEach,但没有一个起作用。此代码仅用于此发布。
在示例中,我已验证reg是否正确传递给测试方法。它的结构正确,带有正确结构的对象的regI大小为4。
- 新的Array列表“ item”只是为.forEach测试提供一个简单的容器
- .forEach将测试一段代码并设置一个断点。没用
- .sort旨在对同一容器中的列表进行重新排序。我没有使用流,因为我不想移动它。没用
- for循环是为了证明列表具有有效数据的老式方式,并且.forEach的意图应该起作用。它确实按预期工作
我假设我的环境或这段代码有问题,但是我自己无法识别它。
在用Holger和Stuart Marks建议的方法进行测试之后,很明显,这是与IndirectList和重写有关的相同问题。我的JRE和JDK都是Java
8,我已经升级到EclipseLink
2.5.2。我已经证明,使用lambdas和.forEach的比较器,Collections.sort会100%地出现此问题。这似乎是一个非常普遍的问题,令我惊讶的是,除了我的问题之外,其他问题没有引起更多的关注。
回答:
此问题的根本原因是在IndirectList
EclipseLink
JPA类中使用了错误的实现模式。(doc,source)在2.5版本家族中会发生此问题;它也可能在其他版本中出现。
问题在于,此类既是 子类Vector
, 又具有 对Vector
实例 的
引用。它尝试通过覆盖的所有方法来将所有方法调用委托给该实例Vector
。只要没有添加新方法,此方法就可以正常工作Vector
。
这发生在Java 8中。
Java的8增加了几个新 的默认方式 为Collection
,Iterable
和List
接口,包括:
forEach
parallelStream
removeIf
replaceAll
sort
spliterator
stream
通常,添加默认方法是安全的,因为必须根据其他现有方法来实现它们。但是,出于效率考虑,实现类覆盖默认方法通常是一个好主意。Java 8
Vector
实现添加了这些默认方法的多个替代。如果您有实际Vector
类的实例,则这些方法可以正常工作。本IndirectList
类不重写这些方法,所以代表团路径,它试图建立不起作用了这些方法。而是使用普通的Vector
实现。不幸的是,这些IndirectList
方法不能使超类状态保持最新,因此Vector
这些方法的实现都表现为好像Vector
是空的。
Vector
覆盖forEach
,removeIf
,replaceAll
,sort
,和spliterator
。在parallelStream
与stream
默认的方法是在以下方面实现的spliterator
,于是同样的事情发生在他们身上。本质上,如果在IndirectList
从EclipseLink
JPA检索的实现中使用集合上的新默认方法,则这些新方法都不起作用。
请注意,也会出现此问题Collections.sort(indirectList)
。此方法仅调用该indirectList.sort()
方法,因此遇到与上述完全相同的问题。
有关EclipseLink状态的更多信息,请参阅EclipseLink
JPA错误433075和446236。
有关此实现模式的陷阱的更多信息,请参见Joshua Bloch的书《 Effective Java,第二版 ,
以上是 .forEach和.sort不起作用,无法在块中设置断点 的全部内容, 来源链接: utcz.com/qa/406170.html