0
@Data
class Person {

    private String fname;
    private String lname;

    private List<String> friends;
    private List<BigDecimal> ratings;

    ...
}

@Data
class People {

    private List<Person> people;

    ...
}

suppose i have the above classes, and need to figure out what is the most number of friends any one person has. I know the pre-streams way of doing it... by looping over every element in the list and checking if friends.size() is greater than the currently stored number of longest list. is there a way to streamline the code with streams? something like this answer?

StillLearningToCode
  • 2,271
  • 4
  • 27
  • 46

3 Answers3

7

Compute the max Person contained in People according to a comparator that relies on the size of Person.getFriends() :

Optional<Person> p = people.getPeople()
                           .stream()
                           .max(Comparator.comparingInt(p -> p.getFriends()
                                                           .size()));

Note that you could also retrieve only the max of friends without the Person associated to :

OptionalInt maxFriends = people.getPeople()
                               .stream()
                               .mapToInt(p -> p.getFriends()
                                               .size())
                               .max();
davidxxx
  • 125,838
  • 23
  • 214
  • 215
  • 1) favour `Comparator.comparingInt` instead of `Comparator.comparing` when comparing ints. 2) the last one can be significantly improved to `OptionalInt max = people.getPeople().stream().mapToInt(p -> p.getFriends().size()).max();` – Ousmane D. Jul 24 '18 at 18:06
1

You can declare the following method in Person class:

public int getNumberOfFriends(){
   return friends.size();
}

and then use it in a stream like this:

Optional <Person> personWithMostFriends = people.stream().max(Comparator.comparingInt(Person::getNumberOfFriends));

With this approach you will get the Person object with the most friends, not only the maximum number of friends as someone suggested.

NiVeR
  • 9,644
  • 4
  • 30
  • 35
  • 1
    favour `Comparator.comparingInt` instead of `Comparator.comparing` when comparing ints – Ousmane D. Jul 24 '18 at 18:10
  • 1
    Also, avoid calling `get()` straight from an optional result unless you're sure the source is _definitely_ not empty. leverage the `orElse`, `ifPresent` et al. – Ousmane D. Jul 24 '18 at 18:11
  • @Aominè Yeah, I should've mentioned that. Thank you. – NiVeR Jul 24 '18 at 18:12
  • I understand up-voting / accepting another correct answer, but down-voting another correct answer ..why? – NiVeR Jul 24 '18 at 19:40
1

Your question already answered. but i add this for one thing. if your list of person size large and if you have multi-core pc and you want to used this efficiently then use parallelstream().

To get person:

Person person = people.getPeople()
.parallelStream()
.max(Comparator.comparingInt(p-> p.getFriends().size()))
.orElse(null);

To get size:

int size = people.getPeople()
.parallelStream()
.mapToInt(p -> p.getFriends().size())
.max().orElse(0);
GolamMazid Sajib
  • 8,698
  • 6
  • 21
  • 39