.forEach和.sort不工作,不能在块中设置断点 [英] .forEach and .sort don't work and cannot set breakpoints in blocks

查看:1122
本文介绍了.forEach和.sort不工作,不能在块中设置断点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用Java 8(build 1.8.0_25),Netbeans 8.0.2,并将一些Java 8功能集成到现有应用程序中。排序和.forEach不工作,所以我已经创建了一些测试代码,以确保我理解lambdas等,并诊断问题。下面是新的代码以及与系统中的数据交互的代码:

  public void test ){
/ * 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));

/ *用我的系统数据测试的代码* /
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,作为另一POJO细节的注册项列表。在此测试中,列表大小为4.



标记为新代码的部分完美地工作。它打印出列表,打印排序,它们打印排序的列表。我也可以在排序的块中设置断点,这是我期望的。



使用现有的代码是另一回事。 .forEach和.sort不工作,我不能在java 8块中设置断点。调试器步骤到代码,但它似乎不像它执行。当我到达循环,item仍然有一个大小为0.看起来只是在那里,以证明数据可以移动的工作原理和结果的大小为4。



任何帮助将不胜感激。






我道歉我可能不清楚。这只是测试代码演示一个问题,我经历了几十个地方,因为更改为java 8.比较器更改为lambdas和for循环.forEach和无人正在工作。



在此示例中,我已验证reg是否正确传递给测试方法。它的结构正确,regI的大小为4,结构化对象正确。




  • 新的数组列表item用于.forEach测试的简单容器

  • .forEach是用一段代码测试并设置断点。它不起作用。

  • .sort用于在同一容器中重新排列列表。我没有使用流,因为我不想移动它。它不工作

  • for循环是为了证明列表具有有效数据的旧时尚方式,并且.forEach的意图应该工作。它会按预期工作



我假设我的环境或此代码有问题,但无法自行识别



在使用Holger和Stuart Marks建议的方法进行测试后,很清楚这是与IndirectList相关的问题和覆盖。我的JRE和JDK都是Java 8,我已经升级到EclipseLink 2.5.2。我已经证明问题发生100%的时间与比较器,Collections.sort与lambdas和.forEach。这似乎是一个非常普遍的问题,我感到惊讶的是,除了我的另一个问题没有吸引更多的关注比1仰。

解决方案

这个问题的根本原因是在EclipseLink JPA的 IndirectList 类中使用有缺陷的实现模式。 ( doc source )这个问题发生在2.5版本家庭;



问题是这个类子类 Vector Vector 实例有引用。它尝试通过覆盖 Vector 的所有方法,将所有方法调用委托给该实例。这工作正常,只要没有新的方法添加到 Vector



这发生在Java 8。 / p>

Java 8向集合添加了几个新的默认方法 > Iterable 列表接口,包括:




  • forEach

  • parallelStream

  • removeIf

  • replaceAll
  • > sort
    > > stream


通常,添加默认方法是安全的,按照其他现有方法实施。然而,为了效率的原因,实现类来覆盖默认方法通常是个好主意。 Java 8 Vector 实现添加了对这些默认方法的几个覆盖。如果你有一个实际的 Vector 类的实例,这些工作正常。 IndirectList 类不会覆盖这些方法,因此它尝试设置的委派路径对这些方法不起作用。而是使用普通的 Vector 实现。不幸的是, IndirectList 方法不保持超类状态为最新,因此 Vector 方法的实现all表现为向量为空。



向量覆盖 forEach removeIf replaceAll sort spliterator parallelStream 默认方法是以 spliterator ,所以同样的事情发生在他们。基本上,如果在从EclipseLink JPA检索的 IndirectList 实现中使用这些方法,集合上的新默认方法都不会工作。



请注意,这个问题也会发生在 Collections.sort(indirectList)。这个方法只是调用 indirectList.sort()方法,所以遇到与上述完全一样的问题。



此问题的一些潜在解决方法列在此答案中。



有关EclipseLink状态的更多信息,请参阅EclipseLink JPA错误 433075 446236



有关陷阱的更多信息,请参阅Joshua Bloch的有效的Java,第二版 项目16:有利于继承的组合


I am using Java 8 (build 1.8.0_25), Netbeans 8.0.2 and am incorporating some of the Java 8 features into an existing app. Sorting and .forEach is not working so I have created some test code to ensure I understand lambdas, etc. and to diagnose the problem. Below is a mix of new code as well as code to interact with the data from my system:

  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);
    }
}

Registration is a POJO reflecting data for an event which includes a List of RegistrationItem(s) which is another POJO of details. In this test the list size is 4.

The section labelled new code works perfectly. It prints out the list, prints as it sorts and them prints the sorted list. I can also set breakpoints inside the block of the sort which is what I would expect.

The working with existing code is another matter. The .forEach and .sort don't work and I can not set breakpoints in the java 8 blocks. The debugger steps to the code but it doesn't seem like it executes. When I get to the for loop, "item" still has a size of 0. The look is just there to prove that the data can be moved which works as expected and results in a size of 4.

Any help would be appreciated.


I apologize I probably wasn't clear. This is just test code demonstrating a problem I am experiencing in dozens of places since changing to java 8. comparators were changed to lambdas and for loops to .forEach and none are working. This code has no purpose other than for this posting.

In the example, I have verified that reg is passed correctly to the test method. It is structured correctly and regI has a size of 4 with correctly structured objects.

  • The new Array list "item" is just to provide a simple container for the .forEach test
  • The .forEach is to test with a block of code and setting a breakpoint. It doesn't work.
  • The .sort is intended to re-order the list in the same container. I didn't use streams as I don't want to move it. It doesn't work
  • The for loop is to prove the old fashion way that the list has valid data and the intent of the .forEach should have worked. It DOES work as expected

I assume I have something wrong in my environment or this code but have been unable to identify it on my own.

After testing with the approach suggested by Holger and Stuart Marks, it is pretty clear that this is the same problem related to IndirectList and overrides. My JRE and JDK are both Java 8 and I have upgraded to EclipseLink 2.5.2. I have proven the problem to occur 100% of the time with comparator, Collections.sort with lambdas and .forEach. This seems like a very pervasive problem and I am surprised the other question has not attracted more attention than 1 uptick besides mine.

解决方案

The root cause of this problem is the use of a flawed implementation pattern in the IndirectList class of EclipseLink JPA. (doc, source) This problem occurs in the 2.5 release family; it may also occur in other versions.

The problem is that this class both subclasses Vector and has a reference to a Vector instance. It attempts to delegate all method calls to that instance by overriding all of the methods of Vector. This works fine, as long as no new methods are added to Vector.

This happened in Java 8.

Java 8 added several new default methods to the Collection, Iterable, and List interfaces, including:

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

Typically, adding default methods is safe, since they must be implemented in terms of other existing methods. However, it is usually a good idea for implementing classes to override default methods for reasons of efficiency. The Java 8 Vector implementation added several overrides of these default methods. These work fine if you have an instance of the actual Vector class. The IndirectList class doesn't override these methods, so the delegation path that it attempted to set up doesn't work for these methods. Instead, the ordinary Vector implementations are used. Unfortunately, the IndirectList methods don't keep the superclass state up to date, so the Vector implementations of the methods all behave as if the Vector is empty.

Vector overrides forEach, removeIf, replaceAll, sort, and spliterator. The parallelStream and stream default methods are implemented in terms of spliterator, so the same thing happens to them. Essentially, none of the new default methods on collections will work if they are used on an IndirectList implementation retrieved from EclipseLink JPA.

Note that this problem also occurs with Collections.sort(indirectList). This method simply calls the indirectList.sort() method, so it encounters exactly the same problem as described above.

Some potential workarounds for this problem are listed in this answer.

For further information about the status of EclipseLink, see EclipseLink JPA bugs 433075 and 446236.

For further information about the pitfalls of this implementation pattern, see Joshua Bloch's book Effective Java, Second Edition, Item 16: Favor Composition over Inheritance.

这篇关于.forEach和.sort不工作,不能在块中设置断点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆