.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%地出现此问题。这似乎是一个非常普遍的问题,令我惊讶的是,除了我的问题之外,其他问题没有引起更多的关注。

回答:

此问题的根本原因是在IndirectListEclipseLink

JPA类中使用了错误的实现模式。(doc,source)在2.5版本家族中会发生此问题;它也可能在其他版本中出现。

问题在于,此类既是 子类Vector又具有Vector实例

引用。它尝试通过覆盖的所有方法来将所有方法调用委托给该实例Vector。只要没有添加新方法,此方法就可以正常工作Vector

这发生在Java 8中。

Java的8增加了几个新 的默认方式CollectionIterableList接口,包括:

  • forEach
  • parallelStream
  • removeIf
  • replaceAll
  • sort
  • spliterator
  • stream

通常,添加默认方法是安全的,因为必须根据其他现有方法来实现它们。但是,出于效率考虑,实现类覆盖默认方法通常是一个好主意。Java 8

Vector实现添加了这些默认方法的多个替代。如果您有实际Vector类的实例,则这些方法可以正常工作。本IndirectList类不重写这些方法,所以代表团路径,它试图建立不起作用了这些方法。而是使用普通的Vector实现。不幸的是,这些IndirectList方法不能使超类状态保持最新,因此Vector这些方法的实现都表现为好像Vector是空的。

Vector覆盖forEachremoveIfreplaceAllsort,和spliterator。在parallelStreamstream默认的方法是在以下方面实现的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

回到顶部