使用Java Lambda根据公共属性连接两个列表并收集另一个属性

4

我有两个列表

List<SampleClassOne> listOne;
List<SampleClassTwo> listTwo;

public class SampleClassOne{
  private String myProperty;
  private String myOtherProperty
  //ommiting getters-setters
}

public class SampleClassTwo{
  private String myProperty;
  private String someOtherProperty
  //ommiting getters-setters
}

我想要做这件事

List<String> someOtherPropertyList;

for(SampleClassOne One : listOne) {
    for(SampleClassTwo two : listTwo) {
        if (one.getMyProperty().equals(two.getMyProperty())){
            someOtherPropertyList.add(two.getSomeOtherProperty());             
        }
    }
}

return someOtherPropertyList;

我是否可以使用Lambda表达式来高效地完成“我想做这件事”之后的所有操作?

4个回答

4

我建议考虑性能,并按照以下方式编写:

Collection<String> myPropertiesFromListOne = listOne.stream()
            .map(SampleClassOne::getMyProperty)
            .collect(Collectors.toSet()); // removes duplicated elements

 List<String> someOtherPropertyList = listTwo.stream()
            .filter(sampleClassTwo ->
                 myPropertiesFromListOne.contains(sampleClassTwo.getMyProperty())
            )
            .map(SampleClassTwo::getSomeOtherProperty)
            .collect(Collectors.toList());

1
不要害怕使用更短的变量名,这样谓词可能适合一行;-) - Holger
1
感谢@Holger的评论,你是对的。这段代码仅用于演示,如果您想看看我如何编写代码,请参阅我的API文档中的真实世界示例 http-request - Beno

2

虽然不是特别高效,但你可以使用流(streams)来更具声明性地实现:

List<String> someOtherPropertyList = listTwo.stream()
        .filter(two -> listOne.stream()
                .map(SampleClassOne::getMyProperty)
                .anyMatch(two.getMyProperty()::equals))
        .map(SampleClassTwo::getSomeOtherProperty)
        .collect(Collectors.toList());

1

类似这样的(我希望我没有漏掉任何括号,因为我还没有编译它)

listTwo.stream()
      .filter(left -> listOne.stream()
            .anyMatch(right -> left.getMyProperty().equals(right.getMyProperty())))
      .map(SampleClassTwo::getSomeOtherProperty)
      .collect(Collectors.toList());  

0
在重写哈希函数以返回 myProperty 的哈希值时,您可以执行以下操作。(可能比迭代列表更高效。)
new HashSet<>(listOne).addAll(listTwo)
                      .stream()
                      .forEach(someOtherPropertyList.add(someOtherProperty));
return someOtherPropertyList;

首先,你不能使用 new HashSet<>(listOne).addAll(listTwo),否则会出现编译错误,因为 listOne 和 listTwo 的泛型类型不兼容。 其次,方法 addAll 返回一个布尔值。 - Beno

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接