考虑到我想过滤键值对象列表。
我的(文档)-对象从下面的例子看起来像这样
{
"attributeEntityList" : [
{key: 'key1', value: 'somevalue1'},
{key: 'key2', value: 'somevalue2'},
{key: 'key3', value: 'somevalue3'}
]
}
>
当我传入以下键的列表时,[“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;
}
为了教育和乐趣(也许还有更好的扩展),我想知道如何使用新的Java8流媒体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>();
}
}
}));
}
我想出了一个办法。
我不知道这是否是最优雅的解决方案,但至少它是有效的,我可以对此进行推理。
private List<AttributeEntity> getAttributeEntities(List<String> keys, Document value) {
final List<AttributeEntity> documentAttributeList = value.getAttributeList();
boolean allKeysPresentInAnyAttribute = keys.stream()
.allMatch(key ->
documentAttributeList.stream()
.filter(attrbiute ->
attrbiute.getAttribute_key().equals(key)
)
.findAny()
.isPresent()
);
if (allKeysPresentInAnyAttribute) {
return documentAttributeList.stream()
.filter(attribute ->
keys.contains(attribute.getAttribute_key())
)
.collect(Collectors.toList());
}
return new ArrayList<>();
}
任何提示或意见非常感谢。
如果一个文档永远不能有多个同名属性,我想你可以这样做(手头没有编译器可以尝试):
Map<String, AttributeEntity> filteredMap=value.getAttributeEntityList().stream()
.filter(at->keys.contains(at.getKey()))
.collect(toMap(at->at.getKey(), at->at));
return filteredMap.keySet().containsAll(keys)
? new ArrayList<>(filteredMap.values())
: new ArrayList<>();
如果允许每个名称具有多个属性,则必须使用groupingBy而不是toMap。当然,你可以用CollectingAnd重写这个,但我认为它不那么清晰。
首先,我必须说,我对Java 8的特性也很陌生,所以我对所有东西都不熟悉,也不太习惯函数式编程。我尝试了一种不同的方法,将其分为一些方法。
这是:
public class Main {
private static List<AttributeEntity> documentAttributeList;
static {
documentAttributeList = new ArrayList<>();
documentAttributeList.add(new AttributeEntity("key1", "value1"));
documentAttributeList.add(new AttributeEntity("key2", "value2"));
documentAttributeList.add(new AttributeEntity("key3", "value3"));
}
public static void main(String[] args) {
Main main = new Main();
List<AttributeEntity> attributeEntities = main.getAttributeEntities(Arrays.asList("key1", "key2"));
for (AttributeEntity attributeEntity : attributeEntities) {
System.out.println(attributeEntity.getKey());
}
}
private List<AttributeEntity> getAttributeEntities(List<String> keys) {
if(hasInvalidKey(keys)){
return new ArrayList<>();
} else {
return documentAttributeList.stream().filter(attribute -> keys.contains(attribute.getKey())).collect(toList());
}
}
private boolean hasInvalidKey(List<String> keys) {
List<String> attributeKeys = getAttributeKeys();
return keys.stream().anyMatch(key -> !attributeKeys.contains(key));
}
private List<String> getAttributeKeys() {
return documentAttributeList.stream().map(attribute -> attribute.getKey()).collect(toList());
}
}
如何在lambda表达式中将对象设置为另一个?我犯了错误
我试着取一个数字列表,过滤掉偶数,然后平方这些偶数,这样原始列表中的偶数就平方了。这是我的代码: 我尝试了一些其他的方法,但这是我目前所处的位置
这个问题有一个关于如何使用多行lambda表达式对List进行排序的答案: 不幸的是,这似乎不适用于原始数组: 如何在Arrays.sort()中使用多行lambda表达式对原始数组进行排序? 我对任何其他方法(不必使用)都很好,只要它使用lambda表达式(没有比较器)。
你好我想对新创建的LinkedList进行升序排序,列表中的所有元素都是随机装箱的。我的任务是用比较器对它们进行排序,但我不允许编写实现比较器的类,而是应该用lambda表达式对其进行排序。这是我目前的代码: 到目前为止,我尝试使用集合和列表中的排序方法,但无法进一步帮助我。非常感谢您提前帮助我。
我试图用Lamdas简化我的对象创建。 如下所示:
有人知道一种方法(如果可能的话也可以使用lodash)通过对象键对对象数组进行分组,然后根据分组创建新的对象数组吗?例如,我有一个汽车对象数组: 我想制作一个由分组的新汽车对象数组: