【发布时间】:2014-10-22 15:42:19
【问题描述】:
鉴于我想过滤键值对象列表。
下面示例中的我的(文档)对象看起来像这样
{
"attributeEntityList" : [
{key: 'key1', value: 'somevalue1'},
{key: 'key2', value: 'somevalue2'},
{key: 'key3', value: 'somevalue3'}
]
}
当我传入以下键
["key1", "key2", "key3"]的列表时,我希望我的函数返回整个给定的属性列表。当我传入以下键
["key1", "key2"]的列表时,我希望我的函数返回具有给定键名的属性列表。当我传入以下键
["key1", "key2", "faultyKey"]的列表时,我希望我的函数返回一个空列表。
我的命令式解决方案看起来像这样,它工作正常:
private List<AttributeEntity> getAttributeEntities(List<String> keys, Document value) {
final List<AttributeEntity> documentAttributeList = value.getAttributeEntityList();
final List<AttributeEntity> resultList = new ArrayList<>();
for(String configKey: keys){
boolean keyInAttribute = false;
for(AttributeEntity documentAttribute : documentAttributeList){
if(configKey.equals(documentAttribute.getAttribute_key())){
keyInAttribute = true;
resultList.add(documentAttribute);
break;
}
}
if(!keyInAttribute){
resultList.clear();
break;
}
}
return resultList;
}
为了教育和娱乐(也许是更好的扩展),我想知道如何使用新的 Java 8 流式 API 将这段代码转换为解决方案。
这就是我想出的,将我之前的 Java8 代码转换为 Java8。
在我看来,它看起来更简洁,而且更短。但它没有,我期望它做什么:/
我真的很难实现我的要求的第三个要点。 它总是返回所有(找到的)属性,即使我传入一个不存在的键。
private List<AttributeEntity> getAttributeEntities(List<String> keys, Document value) {
final List<AttributeEntity> documentAttributeList = value.getAttributeList();
return documentAttributeList.stream()
.filter(attribute ->
keys.contains(attribute.getAttribute_key())
).collect(Collectors.toList());
}
我正在考虑实现我自己的自定义收集器。 由于我的收集器应该只返回列表,当收集的结果包含每个给定键至少一次时。
关于如何实现这一点的任何其他想法?
这个解决方案通过了我的测试。 但感觉就像本末倒置。
不再简洁、简洁、优雅。
private List<AttributeEntity> getAttributeEntities(List<String> keys, Document value) {
final List<AttributeEntity> documentAttributeList = value.getAttributeList();
return documentAttributeList.stream()
.filter(attribute ->
keys.contains(attribute.getAttribute_key())
)
.collect(Collectors.collectingAndThen(Collectors.toList(), new Function<List<AttributeEntity>, List<AttributeEntity>>() {
@Override
public List<AttributeEntity> apply(List<AttributeEntity> o) {
System.out.println("in finisher code");
if (keys.stream().allMatch(key -> {
return o.stream().filter(attrbiute -> attrbiute.getAttribute_key().equals(key)).findAny().isPresent();
})) {
return o;
} else {
return new ArrayList<AttributeEntity>();
}
}
}));
}
【问题讨论】:
-
我认为您的代码还可以,那么为什么要使用任何 Java8 功能呢?这不会让你的代码更容易
-
好的...在否决票之后。我只能猜测我做错了什么。没有提供我尝试过的示例。这看起来像
do my homework-question。我会解决我的问题 -
听起来你的老师告诉你写Java8的程序来学习Lambda,却没有想到Java7标准更适合你的代码
-
如果你使用来自 Java8 的工具,如
forEach方法,我只会看到多线程错误出现 -
"为了教育和娱乐(或许还有更好的扩展性),我想知道如何使用新的 Java 8 流式 API 将这段代码转换为解决方案 " 所以尝试用 lambdas 来实现。是什么阻止了你?我看不出你有什么问题(我假设你没有要求我们重写你的只是这样你就会看到它是如何完成的在你尝试之前,IMO 会关闭-关于堆栈溢出的主题)。