Joe
Joe

Reputation: 326

Nested loop conversion to Java Stream

I have a List<Person> persons. I need to iterate a list of numbers and set a custom number to each person eg person.setCustomNumber(), as follows:

Code Looks like below:

public static void main(String[] args) {

    List<Long> customNumnbers = new ArrayList<>();
    customNumnbers.add(100000l);
    customNumnbers.add(100001l);
    customNumnbers.add(100002l);
    customNumnbers.add(100003l);
    customNumnbers.add(100004l);
    customNumnbers.add(100005l);
    customNumnbers.add(100006l);
    customNumnbers.add(100007l);
    customNumnbers.add(100008l);
    
    List<Person> persons = new ArrayList<>();
    persons.add(new Person("Robert"));
    persons.add(new Person("Jim"));
    persons.add(new Person("Mark"));
    persons.add(new Person("Beto"));
    persons.add(new Person("Reando"));
    
    Map<String, Long> map = new HashMap<>();
    List<Long> possibleNumbers = customNumnbers.subList(0, persons.size());
    int n = 0;
    while(n != possibleNumbers.size()) {    
        for (int j = 0; j < persons.size(); j++) {
            persons.get(j).setCustomNumer(possibleNumbers.get(n));
            map.put(persons.get(j).getName(), persons.get(j).getCustomNumer());
            n++;
        }

    }
    map.entrySet().stream().forEach(System.out::println);
}

class Person {
    private Long id;
    private String name;
    private Long customNumer;
    // relevant constructor, getters and setters
}

I want to re-write this logic in java streams and return a new map of Name and Custom number for each like Map<String, Long> map.

Upvotes: 1

Views: 83

Answers (2)

Nikolas
Nikolas

Reputation: 44378

The whole thing can be simplified using IntStream.range(int, int).

// assure the runtime exception is not thrown due to exceeding any of the lists size
int n= Math.min(customNumnbers.size(), persons.size());  

Map<String, Long> map = IntStream.range(0, n) // iterate indixes 0..n
    .boxed()                                  // Stream<Integer> rather than IntStream
    .collect(Collectors.toMap(                // collect to a Map<String, Long>
        i -> persons.get(i).getName(),        // .. Person's name as a key from persons
        customNumbers::get));                 // .. the Long as a value from customNumbers

Btw. you have a typo in customNumnbers that should be customNumbers - I fixed it in my solution.

Upvotes: 1

Andrew Vershinin
Andrew Vershinin

Reputation: 1968

You can assign numbers in a loop:

int assignableCount = Math.min(persons.size(), possibleNumbers.size());
for (int i = 0; i < assignableCount; i++)
    persons.get(i).setCustomNumber(possibleNumbers.get(i));

And then use streams to build the map:

Map<String, Long> map = persons.stream()
    .collect(Collectors.toMap(Person::getName, Person::getCustomNumber);

Upvotes: 1

Related Questions