Issue
I create a record User:
public record User(String name, int age, List<String> skills, boolean isActive) {
}
and a list of users:
private static List<User> prepareData() {
List<User> users = new ArrayList<>();
users.add(new User("Kamil", 35, List.of("Java", "Python", "JavaScript"), true));
users.add(new User("Mariusz", 36, List.of("Java", "C++", "C#"), true));
users.add(new User("Dominik", 30, List.of("Java", "Dart", "Python"), false));
users.add(new User("Paulina", 36, List.of("PHP", "SQL", "Python"), false));
users.add(new User("RafaĆ", 40, List.of("C#", "Dart"), true));
users.add(new User("Agnieszka", 29, List.of("Java", "Scala", "Kotlin", "Haskell", "Clojure"), false));
users.add(new User("Weronika", 43, List.of("Python", "C#", "VBA"), true));
return users;
}
Now I need to find a user who knows the most technologies (using stream!) and display his name and a list of technologies. I've been trying to get my head around how I can sort a list in a stream. I've tried with Comparator method but it throws an error:
users.stream()
.sorted(Comparator.comparing(User::skills))
Any idea how to do that?
Solution
"... Now I need to find a user who knows the most technologies (using stream!) and display his name and a list of technologies. ..."
There is the possibility that more than one User, will have the same amount of skills.
For this, utilize a TreeMap Collector; where the last entry will be a List of User objects, with the most skills.
users = users.stream()
.collect(
Collectors.groupingBy(
x -> x.skills().size(),
TreeMap::new,
Collectors.toList()))
.lastEntry()
.getValue();
And optimally, extend the ArrayList class, to encapsulate the add method.
class UsersList extends ArrayList<User> {
boolean add(String name, int age, List<String> skills, boolean isActive) {
return super.add(new User(name, age, skills, isActive));
}
}
Output
User[name=Agnieszka, age=29, skills=[Java, Scala, Kotlin, Haskell, Clojure], isActive=false]
Although, this approach is fairly un-intuitive.
Typically, stream operations are used for aggregating, or producing, data—e.g., mapping, filtering, etc.—and, not necessarily for calculating values.
While the functionality is abstracted, it's not what is plausibly, pragmatic, in terms of design constructs, and scalable interfaces.
With that, I recommend using a basic for-loop iteration.
List<User> list = new ArrayList<>();
User u;
int i, m = users.get(0).skills().size(), n = users.size(), t;
for (i = 1; i < n; i++)
if ((t = users.get(i).skills().size()) > m) m = t;
for (i = 0; i < n; i++)
if ((u = users.get(i)).skills().size() == m) list.add(u);
Or, a ListIterator.
int m = users.get(0).skills().size(), t;
ListIterator<User> li = users.listIterator(1);
while (li.hasNext())
if ((t = li.next().skills().size()) > m) m = t;
li = users.listIterator();
while (li.hasNext())
if (li.next().skills().size() != m) li.remove();
Answered By - Reilas
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.