简体   繁体   中英

Java8 Lambda compare two List and trasform to Map

Suppose I have two class:

class Key {
 private Integer id;
 private String key;
}

class Value {
  private Integer id;
  private Integer key_id;
  private String value;
}

Now I fill the first list as follows:

List<Key> keys = new ArrayLisy<>();
keys.add(new Key(1, "Name"));
keys.add(new Key(2, "Surname"));
keys.add(new Key(3, "Address"));

And the second one:

List<Value> values = new ArrayLisy<>();
values.add(new Value(1, 1, "Mark"));
values.add(new Value(2, 3, "Fifth Avenue"));
values.add(new Value(3, 2, "Fischer"));

Can you please tell me how can I rewrite the follow code:

for (Key k : keys) {
        for (Value v : values) {
            if (k.getId().equals(v.getKey_Id())) {
                map.put(k.getKey(), v.getValue());
                break;
        }
    }
}

Using Lambdas?

Thank you!

‐------UPDATE-------

Yes sure it works, I forget "using Lambdas" on the first post (now I added). I would like to rewrite the two nested for cicle with Lamdas.

Here is how you would do it using streams.

  • stream the keylist
  • stream an index for indexing the value list
  • filter matching ids
  • package the key instance key and the value instance value into a SimpleEntry.
  • then add that to a map.
Map<String, String> results = keys.stream()
        .flatMap(k -> IntStream.range(0, values.size())
                .filter(i -> k.getId() == values.get(i).getKey_id())
                .mapToObj(i -> new AbstractMap.SimpleEntry<>(
                        k.getKey(), values.get(i).getValue())))
        .collect(Collectors.toMap(Entry::getKey, Entry::getValue));

results.entrySet().forEach(System.out::println);

prints

Address=Fifth Avenue
Surname=Fischer
Name=Mark

Imo, your way is much clearer and easier to understand. Streams/w lambdas or method references are not always the best approach.

A hybrid approach might also be considered.

  • allocate a map.
  • iterate over the keys.
  • stream the values trying to find a match on key_id's and return first one found.
  • The value was found (isPresent) add to map.
Map<String,String> map = new HashMap<>();

for (Key k : keys) {
    Optional<Value> opt = values.stream()
            .filter(v -> k.getId() == v.getKey_id())
            .findFirst();
    if (opt.isPresent()) {
        map.put(k.getKey(), opt.get().getValue());
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM