[英]Create a map from two different lists based on common conditions using Java 8 Streams
我有兩個這樣的列表實例:
List<NameAndAge> nameAndAgeList = new ArrayList<>();
nameAndAgeList.add(new NameAndAge("John", "28"));
nameAndAgeList.add(new NameAndAge("Paul", "30"));
nameAndAgeList.add(new NameAndAge("Adam", "31"));
List<NameAndSalary> nameAndSalaryList = new ArrayList<>();
nameAndSalaryList.add(new NameAndSalary("John", 1000));
nameAndSalaryList.add(new NameAndSalary("Paul", 1100));
nameAndSalaryList.add(new NameAndSalary("Adam", 1200));
NameAndAge
位置
class NameAndAge {
public String name;
public String age;
public NameAndAge(String name, String age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return name + ": " + age;
}
}
和NameAndSalary
是
private class NameAndSalary {
private String name;
private double salary;
public NameAndSalary(String name, double salary) {
this.name = name;
this.salary = salary;
}
@Override
public String toString() {
return name + ": " + salary;
}
}
現在,我想從第一個列表中創建一個帶有鍵作為NameAndAge
對象的映射,並從第二個列表中創建名稱為NameAndSalary
值,其中兩個對象中的名稱相等。
所以,當我打印地圖時,它應該如下所示:
{John: 28=John: 1000.0}
{Paul: 30=Paul: 1100.0}
{Adam: 31=Adam: 1200.0}
我已經嘗試過這樣做了,但是結束返回類型是'無效'所以我無所畏懼,因為我是Streams的新手。
nameAndAgeList
.forEach(n ->
nameAndSalaryList
.stream()
.filter(ns -> ns.name.equals(n.name))
.collect(Collectors.toList()));
有人可以建議如何使用Java Streams API實現這一目標嗎?
首先,假設您要創建HashMap
,您的密鑰類( NameAndAge
)必須覆蓋equals
和hashCode()
。
其次,為了提高效率,我建議你先從第二個List
創建一個Map<String,NameAndSalary>
:
Map<String,NameAndSalary> helper =
nameAndSalaryList.stream()
.collect(Collectors.toMap(NameAndSalary::getName,
Function.identity()));
最后,您可以創建所需的Map
:
Map<NameAndAge,NameAndSalary> output =
nameAndAgeList.stream()
.collect(Collectors.toMap(Function.identity(),
naa->helper.get(naa.getName())));
這也應該可以解決問題:
Map<NameAndAge, NameAndSalary> map = new HashMap<>();
nameAndAgeList.forEach(age -> {
NameAndSalary salary = nameAndSalaryList.stream().filter(
s -> age.getName().equals(s.getName())).
findFirst().
orElseThrow(IllegalStateException::new);
map.put(age, salary);
});
請注意,如果找不到匹配的名稱,它將拋出IllegalStateException
。
這應該也有效
List<String> commonNames = nameAndAgeList
.stream()
.filter(na ->
nameAndSalaryList.anyMatch((ns) -> ns.getName().equals(na.getName()))
.collect(Collectors.toList());
Map<NameAndAge, NameAndSalary> map =
commonNames.stream().collect(Collectors.toMap(name ->
nameAndAgeList.get(name), name -> nameAndSalaryList.get(name)));
沒有創建任何中間對象,不使用forEach
,一個襯墊:
Map<NameAndAge, NameAndSalary> resultMap1 = nameAndAgeList.stream()
.map(nameAndAge -> nameAndSalaryList.stream()
.filter(nameAndSalary -> nameAndAge.getName().equals(nameAndSalary.getName()))
.map(nameAndSalary -> new SimpleEntry<>(nameAndAge, nameAndSalary))
.collect(Collectors.toList()).get(0))
.collect(Collectors.toMap(simpleEntry -> simpleEntry.getKey(), simpleEntry -> simpleEntry.getValue()));
您必須將getter
函數添加到域類中。 直接訪問屬性可能不是一個好主意。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.