2

I have two List objects from which i want to create the Map object using java8.

List<Person> personList =..;  //pid,personName,personAge;
List<Address> addressList =..;//pid,location,homeAddress;
 
HashMap<String, String> map = new HashMap<>();

I want to iterate both the list and generate the map by storing pid from personList and location from addressList as key and value pairs using streams.

personList.stream().filter(..)//how to iterate the second List?

Below is the sample map object it should look

  map.put(pid,location);

Note: Both personList and addressList are not of same size.

7
  • 4
    it is not clear what you are trying to put in the Map Commented Aug 25, 2021 at 18:46
  • Can you provide an example of how the hash map looks with some Person, Address objects for reference? Commented Aug 25, 2021 at 18:47
  • The pid's are the same ID for the address or the person? Commented Aug 25, 2021 at 18:58
  • Yes, address and person has the same pids for reference. Commented Aug 25, 2021 at 18:59
  • 1
    Can you demonstrate the desired behavior using a traditional loop instead of streams? Commented Aug 25, 2021 at 19:09

3 Answers 3

5

Stream API does not iterate on collections; it rather creates a stream from the source, and you cannot source one stream from two different resources.

You can use a circumventing approach, and this will do what you're looking for:

List<Person> personList = ...;  //pid, personName, personAge;
List<Address> addressList = ...;//pid, location, homeAddress;

HashMap<String, String> map = new HashMap<>();

//get the size of smaller list, as lists are of different sizes.
int size = Math.min(personList.size(), addressList.size());

IntStream.range(0, size)
        .mapToObj(e -> new SimpleEntry<>(personList.get(e).getPid(), addressList.get(e).getLocation()))
        .forEach(e -> map.put(e.getKey(), e.getValue()));

Notes:

  1. Make sure you provide appropriate getters in Person and Address;
  2. import java.util.AbstractMap.SimpleEntry;
Sign up to request clarification or add additional context in comments.

1 Comment

ForEach can be removed: HashMap<String, String> map = IntStream.range(0, size) .mapToObj(e -> new SimpleEntry<>(personList.get(e).getPid(), addressList.get(e).getLocation())) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
3

It seems that two steps are needed here:

  1. Build a map <pid, location> on the basis of addressList
  2. Iterate through personList and use person.pid to map to the address.

In general case, a person may have several addresses which also may be duplicated, so final map may look as <pid, Set<location>>.

// 1. map pid to set of addresses
Map<String, Set<String>> addresses = addressList
        .stream()
        .collect(Collectors.groupingBy(
            Address::getPid, 
            Collectors.mapping(Address::getLocation, Collectors.toSet())
        ));

// 2. map person ids to addresses
Map<String, Set<String>> personAddresses = personList
        .stream()
        .collect(Collectors.toMap(
            Person::getPid,
            person -> addresses.get(person.getPid()), // Set<location>
            (addr1, addr2) -> addr1 // resolve possible conflicts
        ));

If it is guaranteed that the pid/addresses pairs are unique and map <pid, location> can be created, the above code may be simplified:

// 1. map pid to single address
Map<String, String> addressMap = addressList
        .stream()
        .collect(Collectors.toMap(
            Address::getPid, 
            Address::getLocation
        ));

// 2. map person ids to addresses
Map<String, String> personAddress = personList
        .stream()
        .collect(Collectors.toMap(
            Person::getPid,
            // single location, provide default value
            person -> addressMap.getOrDefault(person.getPid(), "Unknown address")
        ));

Comments

0

I would recommend you do it as follows:

  • first stream the addressList to create an address map which has the pid as the key and the address as the value.
  • then stream the personList, mapping to the id and filtering on the existence of that id in the address map.

This has two advantages.

  • The contents of personList and addressList may be in any order.
  • Only those ids in personList will be used, ignoring any other ids in the addressList. So the lists are not required to be one-to-one or even the same size.

First, I used two records (classes would also work exactly the same way) to house some data. For this demo, only the pertinent information is included.

record Person(String getPid) {
};
record Address(String getPid, String getLocation) {
};

Next, I create lists with the test data. Both lists will contain id's not in the other.

List<Person> personList = List.of(new Person("id1"),
        new Person("id2"), new Person("id3"), new Person("id6"));
List<Address> addressList =
        List.of(new Address("id3", "Utah"),
                new Address("id1", "Idaho"),
                new Address("id2", "Virginia"),
                new Address("id5", "New York"));

Now create a map of pid to address. If two addresses exist for the same id, only the first encountered is used.

Map<String, Address> addressMap =
        addressList.stream().collect(Collectors
                .toMap(Address::getPid, address -> address,
                        (ad1,ad2)->ad1));

Now create the final map.

  • stream the personList and pull out the ids
  • now filter to ensure the given id is in the address map.
  • and enter the id and the location for given id in the map
Map<String, String> result = personList.stream()
        .map(Person::getPid).filter(addressMap::containsKey)
        .collect(Collectors.toMap(id -> id,
                id -> addressMap.get(id).getLocation));

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

For the test data, the following is printed.

id2=Virginia
id1=Idaho
id3=Utah

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.