我有一个非常简单的代码片段,我希望将其转换为Java 8的list流方法。任何帮助都将不胜感激。
我有两个集合,一个是一组字符串,另一个是一个简单的POJO列表,它本身包含一个字符串列表。相关代码如下:
POJO示例
public class SimplePojo {
private long id;
private String name;
private List<String> desiredStringList;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<String> getDesiredStringList() {
return desiredStringList;
}
public void setDesiredStringList(List<String> desiredStringList) {
this.desiredStringList= desiredStringList;
}
}我想要转换的比较
Set<String> someStrings // Contains a list of strings that needs to be compared
List<SimplePojo> pojoObjectList // Contains list of SimplePojo objects
/* Each of someStrings need to be compared to each of SimplePojo.name property
and corresponding actions which is List object needs to be populated as a separate list
Below is the code snippet which has a mixture of Java 8 stream and regular For-Each loop
*/
Set<String> desiredStrings = new HashSet<String>();
for(String s : someStrings) {
List<String> interimDesiredStrings = pojoObjectList.stream()
.filter(o -> StringUtils.equals(s, o.getName()))
.flatMap(o -> o.getDesiredStringList().stream())
.collect(Collectors.toList());
desiredStrings.addAll(interimDesiredStrings);
}发布于 2017-01-30 21:54:28
这很好地说明了,过度使用第三方实用函数会导致什么。
您正在使用StringUtils.equals,没有迹象表明这是Apache Commons版本还是Spring版本(或者另一个具有这样功能的库)。或者你为什么要使用这种特殊的方法。
在Apache的情况下,这将是合理的,如果它至少是版本3,并且getName()被声明为返回CharSequence,在Spring情况下,它是完全不合理的。除了在Apache中支持CharSequence之外,这两种变体的存在都只是为了静默地处理null,但是如果您真正关心的是处理null,那么使用标准的Objects.equals将立即澄清您的意图。也许,即使是null也不是你所关心的。
这之所以如此重要,是因为您的任务可以很容易地使用标准相等语义实现
Set<String> desiredStrings = pojoObjectList.stream()
.filter(o -> someStrings.contains(o.getName()))
.flatMap(o -> o.getDesiredStringList().stream())
.collect(Collectors.toSet());假设someStrings引用的Set具有合理的查找效率(与大多数Set实现一样),这将比嵌套迭代的效率高得多。
请注意,如果someStrings引用的Set不支持null,这将意味着null名称不是“所需的”,因此,如果getName()可以返回null,则将筛选器更改为
.filter(o -> o.getName()!=null && someStrings.contains(o.getName()))会以一种清晰的方式解决这个问题。
发布于 2017-01-28 11:59:10
为什么不检查一下对象列表,只检查名称是否在要匹配的名称集中?
Set<String> desiredStrings = pojoObjectList.stream()
.filter(o -> someStrings.contains(o.getName()))
.flatMap(o -> o.getDesiredStringList().stream())
.collect(toSet());https://stackoverflow.com/questions/41903932
复制相似问题