Find maximum and minimum of custom objects in Java
Given a list of custom objects, find the maximum and minimum value of a field among custom objects using stream in Java.
1. Using Stream.max()
method
The idea is to convert the list of objects into a stream of objects and then use the Stream#max()
method that accepts a Comparator
to compare objects based on a field value and returns an Optional
containing the maximum object in the stream.
Similarly, we can use the Stream#min()
method to find the minimum object in the stream.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
import java.util.Arrays; import java.util.Comparator; import java.util.List; // `User` class having `name` and `age` private fields class User { private String name; private Integer age; public User(String name, Integer age) { this.name = name; this.age = age; } public Integer getAge() { return age; } // other getters and setters @Override public String toString() { return "[" + name + ", " + String.valueOf(age) + "]"; } } // Find the maximum and minimum value of a field among custom objects // using stream in Java 8 and above class Main { public static void main(String[] args) { List<User> users = Arrays.asList(new User("George", 15), new User("Tom", 10), new User("Mike", 12)); // get a user with the minimum age User user1 = users.stream() .min(Comparator.comparingInt(User::getAge)) .get(); System.out.println("User with minimum age: " + user1); // get a user with the maximum age User user2 = users.stream() .max(Comparator.comparingInt(User::getAge)) .get(); System.out.println("User with maximum age: " + user2); } } |
Output:
User with minimum age: [Tom, 10]
User with maximum age: [George, 15]
We can also pass a lambda function as a comparator, as shown below:
1 2 3 4 5 6 7 8 9 10 11 |
// get a user with the minimum age User user1 = users.stream() .min((x, y) -> x.getAge() - y.getAge()) //.min((x, y) -> Integer.compare(x.getAge(), y.getAge())) .get(); // get a user with the maximum age User user2 = users.stream() .max((x, y) -> x.getAge() - y.getAge()) //.max((x, y) -> Integer.compare(x.getAge(),y.getAge())) .get(); |
2. Using Collectors
We can also use Collectors
to find the maximum or minimum object in the list.
Collectors#maxBy()
returns a Collector
that produces the maximal object according to a given Comparator
. Similarly, Collectors#maxBy()
returns a Collector
that produces the minimal object according to a given Comparator
.
1 2 3 4 5 6 7 8 9 |
// get a user with the minimum age User user1 = users.stream() .collect(Collectors.minBy(Comparator.comparingInt(User::getAge))) .get(); // get a user with the maximum age User user2 = users.stream() .collect(Collectors.maxBy(Comparator.comparingInt(User::getAge))) .get(); |
We can also pass a lambda function as a comparator, as shown below:
1 2 3 4 5 6 7 8 9 |
// get a user with the minimum age User user1 = users.stream() .collect(Collectors.minBy((x, y) -> x.getAge() - y.getAge())) .get(); // get a user with the maximum age User user2 = users.stream() .collect(Collectors.maxBy((x, y) -> x.getAge() - y.getAge())) .get(); |
3. Using Stream.reduce()
method
We can also perform a reduction operation on stream elements using the Stream.reduce()
method that returns an Optional
describing the reduced object.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
import java.util.Arrays; import java.util.List; // `User` class having `name` and `age` private fields class User { private String name; private Integer age; public User(String name, Integer age) { this.name = name; this.age = age; } public Integer getAge() { return age; } // other getters and setters @Override public String toString() { return "[" + name + ", " + String.valueOf(age) + "]"; } } // Custom class class Compare { public static User min(User a, User b) { return a.getAge() < b.getAge() ? a : b; } public static User max(User a, User b) { return a.getAge() > b.getAge() ? a : b; } } // Find the maximum and minimum value of a field among custom objects // using stream in Java 8 and above class Main { public static void main(String[] args) { List<User> users = Arrays.asList(new User("George", 15), new User("Tom", 10), new User("Mike", 12)); // get a user with the minimum age User user1 = users.stream() .reduce(Compare::min) .get(); System.out.println("User with minimum age: " + user1); // get a user with the maximum age User user2 = users.stream() .reduce(Compare::max) .get(); System.out.println("User with maximum age: " + user2); } } |
Instead of creating a custom class for reduction operation and passing method reference, we can directly pass a lambda function, as shown below:
1 2 3 4 5 6 7 8 9 |
// get a user with the minimum age User user1 = users.stream() .reduce((a, b) -> a.getAge() < b.getAge() ? a : b) .get(); // get a user with the maximum age User user2 = users.stream() .reduce((a, b) -> a.getAge() > b.getAge() ? a : b) .get(); |
We can also use the overloaded version of the reduce()
method, which performs a reduction on the stream elements, using the provided identity value and an associative accumulation method and returns the reduced value.
1 2 3 4 5 6 7 8 9 |
// get a user with the minimum age User user1 = users.stream() .reduce(new User("Dummmy", Integer.MAX_VALUE), (a, b) -> a.getAge() < b.getAge() ? a : b); // get a user with the maximum age User user2 = users.stream() .reduce(new User("Dummmy", Integer.MIN_VALUE), (a, b) -> a.getAge() > b.getAge() ? a : b); |
That’s all about finding the maximum and minimum of custom objects in Java.
Thanks for reading.
To share your code in the comments, please use our online compiler that supports C, C++, Java, Python, JavaScript, C#, PHP, and many more popular programming languages.
Like us? Refer us to your friends and support our growth. Happy coding :)