Tomcat9.0.39在JDK11.0.10上运行。
或者在JDK1.8.0ď上运行Tomcat8.5.65。
以下代码使用JDK1.8.0ď编译,运行正常。
final Set<A> a = _a.stream().collect(Collectors.toSet());
a.removeIf(b ->
Objects.nonNull(b.getOne())
&& Objects.nonNull(b.getTwo())
&& Objects.nonNull(b.getThree())
&& Objects.nonNull(b.getFour())
);
然而 removeIf
部件不使用以下配置执行(下一个操作是在所有的 _a
列表):
tomcat 8.5.59在jdk 1.8.0_202-b08上运行。
Tomcat8.5.34在JDK1.8.0¿上运行。
为了达到预期的效果, removeIf
已被筛选器替换:
final Set<A> a = _a.stream()
.filter(b ->
Objects.isNull(b.getOne())
&& Objects.isNull(b.getTwo())
&& Objects.isNull(b.getThree())
&& Objects.isNull(b.getFour())
)
.collect(Collectors.toSet());
或与供应商:
final Set<A> a = _a.stream()
.collect(Collectors.toCollection(TreeSet::new));
a.removeIf(b ->
Objects.nonNull(b.getOne())
&& Objects.nonNull(b.getTwo())
&& Objects.nonNull(b.getThree())
&& Objects.nonNull(b.getFour())
);
我读过关于收藏家#toset或收藏家#tolist的文章:
返回将输入元素累积到新集合/列表中的收集器。无法保证返回的集合/列表的类型、可变性、序列化或线程安全性;如果需要对返回的集合/列表进行更多控制,请使用tocollection(supplier)。
但在这里,如果没有并行流,则流是通过终端操作在最终集合中收集的,而collection#removeif是在JDK1.8中引入的。
所以我的问题是:
为什么它在不同的jdk次要版本上表现不同?
(或者至少在jdk<=1.8.0ď的情况下,它不能像预期的那样工作)
问/答
如果替换_a.stream().collect(collectors.toset());使用新哈希集<>(\u a)?
同样,在工作配置上工作,不在另一个上工作,打印不应该留在集合中的元素。
final Set<A> a = new HashSet<>(_a);
这种行为是“随机的”(如标题所示),意味着这种情况有时发生,但并不总是发生;或者仅仅是出乎意料,这意味着这种情况总是发生在特定的jdk版本上,但您只是不知道为什么?
这种情况总是发生在特定的jdk版本上,但我只是不知道为什么。1.8.0ď271之前 removeIf
从不执行(多次尝试确保),在此版本之后或使用此版本时,它总是过滤元素(也多次尝试)。
实现equals和hashcode是否正确?
a类正在实施 java.lang.Comparable<A>
这样地:
/*
* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object o) {
boolean result = false;
if (o instanceof A) {
A a = (A o;
result =
getId1() == a.getId1()
&& getId2() == a.getId2()
&& getId3() == a.getId3();
}
return result;
}
/*
* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
StringBuilder sb = new StringBuilder();
sb.append(getId1());
sb.append(getId2());
sb.append(getId3());
return sb.hashCode();
}
/*
* (non-Javadoc)
* @see java.lang.Comparable#compareTo(java.lang.Object)
*/
@Override
public int compareTo(A a) {
return
getId1() == a.getId1()
&& getId2() == a.getId2()
&& getId3() == a.getId3()
? 1 : 0;
}
如何确定代码尚未执行?
我使用的第一种方法是生产数据库中的表,它更新了所有元素,而只更新了缩减集的元素。这显示了错误。然后,第二种方法我曾经确定是一个简单的 printf
这样,在对更新表的数据库方法进行注解之后。
a.stream()
.filter(b ->
Objects.nonNull(b.getOne())
|| Objects.nonNull(b.getTwo())
|| Objects.nonNull(b.getThree())
|| Objects.nonNull(b.getFour())
)
.forEach(a ->
System.out.printf(
"%nbad elements remaining in the set : %s%n",
a.getId1()
)
);
打印出来的结果,在不起作用的配置(生产)上是多种多样的:有时更新了300项,有时更新了400项。在工作配置(开发)上,没有打印任何内容。这指出了它在jdk上的工作方式不同的事实。
1条答案
按热度按时间2fjabf4q1#
筛选器和removeif predicate 在同一组条件上不匹配。
当你从
removeIf(nonNull && nonNull)
你需要什么filter(isNull || isNull)
要匹配相同的值:您还可以将 predicate 赋给变量,而filter中使用的 predicate 是
Predicate.not
: