Java 8 lambda filtering based on condition as well as order
up vote
12
down vote
favorite
I was trying to filter a list based on multiple conditions, sorting.
class Student{
private int Age;
private String className;
private String Name;
public Student(int age, String className, String name) {
Age = age;
this.className = className;
Name = name;
}
public int getAge() {
return Age;
}
public void setAge(int age) {
Age = age;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
}
Now if I have a list of that, say
List<Student> students = new ArrayList<>();
students.add(new Student(24, "A", "Smith"));
students.add(new Student(24, "A", "John"));
students.add(new Student(30, "A", "John"));
students.add(new Student(20, "B", "John"));
students.add(new Student(24, "B", "Prince"));
How would I be able to get a list of the oldest students with a distinct name?
In C# this would be quite simple by using System.Linq GroupBy then comparing and then flattening with select, I'm not too sure how I could achieve the same in Java.
java lambda java-8 java-stream
add a comment |
up vote
12
down vote
favorite
I was trying to filter a list based on multiple conditions, sorting.
class Student{
private int Age;
private String className;
private String Name;
public Student(int age, String className, String name) {
Age = age;
this.className = className;
Name = name;
}
public int getAge() {
return Age;
}
public void setAge(int age) {
Age = age;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
}
Now if I have a list of that, say
List<Student> students = new ArrayList<>();
students.add(new Student(24, "A", "Smith"));
students.add(new Student(24, "A", "John"));
students.add(new Student(30, "A", "John"));
students.add(new Student(20, "B", "John"));
students.add(new Student(24, "B", "Prince"));
How would I be able to get a list of the oldest students with a distinct name?
In C# this would be quite simple by using System.Linq GroupBy then comparing and then flattening with select, I'm not too sure how I could achieve the same in Java.
java lambda java-8 java-stream
7
students.stream().collect(groupingBy(...))
.
– Andy Turner
yesterday
Do you only want a list of the oldest and only the oldest ones?
– michaeak
yesterday
Please tell what is the desired result. I.e. How the map/list/whatever looks like.
– michaeak
yesterday
add a comment |
up vote
12
down vote
favorite
up vote
12
down vote
favorite
I was trying to filter a list based on multiple conditions, sorting.
class Student{
private int Age;
private String className;
private String Name;
public Student(int age, String className, String name) {
Age = age;
this.className = className;
Name = name;
}
public int getAge() {
return Age;
}
public void setAge(int age) {
Age = age;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
}
Now if I have a list of that, say
List<Student> students = new ArrayList<>();
students.add(new Student(24, "A", "Smith"));
students.add(new Student(24, "A", "John"));
students.add(new Student(30, "A", "John"));
students.add(new Student(20, "B", "John"));
students.add(new Student(24, "B", "Prince"));
How would I be able to get a list of the oldest students with a distinct name?
In C# this would be quite simple by using System.Linq GroupBy then comparing and then flattening with select, I'm not too sure how I could achieve the same in Java.
java lambda java-8 java-stream
I was trying to filter a list based on multiple conditions, sorting.
class Student{
private int Age;
private String className;
private String Name;
public Student(int age, String className, String name) {
Age = age;
this.className = className;
Name = name;
}
public int getAge() {
return Age;
}
public void setAge(int age) {
Age = age;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
}
Now if I have a list of that, say
List<Student> students = new ArrayList<>();
students.add(new Student(24, "A", "Smith"));
students.add(new Student(24, "A", "John"));
students.add(new Student(30, "A", "John"));
students.add(new Student(20, "B", "John"));
students.add(new Student(24, "B", "Prince"));
How would I be able to get a list of the oldest students with a distinct name?
In C# this would be quite simple by using System.Linq GroupBy then comparing and then flattening with select, I'm not too sure how I could achieve the same in Java.
java lambda java-8 java-stream
java lambda java-8 java-stream
asked yesterday
The 0bserver
15710
15710
7
students.stream().collect(groupingBy(...))
.
– Andy Turner
yesterday
Do you only want a list of the oldest and only the oldest ones?
– michaeak
yesterday
Please tell what is the desired result. I.e. How the map/list/whatever looks like.
– michaeak
yesterday
add a comment |
7
students.stream().collect(groupingBy(...))
.
– Andy Turner
yesterday
Do you only want a list of the oldest and only the oldest ones?
– michaeak
yesterday
Please tell what is the desired result. I.e. How the map/list/whatever looks like.
– michaeak
yesterday
7
7
students.stream().collect(groupingBy(...))
.– Andy Turner
yesterday
students.stream().collect(groupingBy(...))
.– Andy Turner
yesterday
Do you only want a list of the oldest and only the oldest ones?
– michaeak
yesterday
Do you only want a list of the oldest and only the oldest ones?
– michaeak
yesterday
Please tell what is the desired result. I.e. How the map/list/whatever looks like.
– michaeak
yesterday
Please tell what is the desired result. I.e. How the map/list/whatever looks like.
– michaeak
yesterday
add a comment |
4 Answers
4
active
oldest
votes
up vote
13
down vote
Use the toMap
collector:
Collection<Student> values = students.stream()
.collect(toMap(Student::getName,
Function.identity(),
BinaryOperator.maxBy(Comparator.comparingInt(Student::getAge))))
.values();
Explanation
We're using this overload of toMap
:
toMap(Function<? super T,? extends K> keyMapper,
Function<? super T,? extends U> valueMapper,
BinaryOperator<U> mergeFunction)
Student::getName
above is thekeyMapper
function used to extract the values for the map keys.
Function.identity()
above is thevalueMapper
function used to extract the values for the map values whereFunction.identity()
simply returns the elements in the source them selves i.e. theStudent
objects.
BinaryOperator.maxBy(Comparator.comparingInt(Student::getAge))
above is the merge function used to "decide which Student object to return in the case of a key collission i.e. when two given students have the same name" in this case taking the oldestStudent
.- Finally, invoking
values()
returns us a collection of students.
The equivalent C# code being:
var values = students.GroupBy(s => s.Name, v => v,
(a, b) => b.OrderByDescending(e => e.Age).Take(1))
.SelectMany(x => x);
Explanation (for those unfamiliar with .NET)
We're using this extension method of GroupBy
:
System.Collections.Generic.IEnumerable<TResult> GroupBy<TSource,TKey,TElement,TResult>
(this System.Collections.Generic.IEnumerable<TSource> source,
Func<TSource,TKey> keySelector,
Func<TSource,TElement> elementSelector,
Func<TKey,System.Collections.Generic.IEnumerable<TElement>,TResult> resultSelector);
s => s.Name
above is thekeySelector
function used to extract the value to group by.
v => v
above is theelementSelector
function used to extract the values i.e. theStudent
objects them selves.
b.OrderByDescending(e => e.Age).Take(1)
above is theresultSelector
which given anIEnumerable<Student>
represented asb
takes the oldest student.- Finally, we apply
.SelectMany(x => x);
to collapse the resultingIEnumerable<IEnumerable<Student>>
into aIEnumerable<Student>
.
Nice answer. Just wanted to say that usingv -> v
instead ofFunction.identity()
would make the code more similar to the C# equivalent and so easier to compare.
– Luis G.
yesterday
add a comment |
up vote
4
down vote
Or without streams:
Map<String, Student> map = new HashMap<>();
students.forEach(x -> map.merge(x.getName(), x, (oldV, newV) -> oldV.getAge() > newV.getAge() ? oldV : newV));
Collection<Student> max = map.values();
Thought of this while starting of from your initial suggestion, but then an additionalMap
here, but doesmap.merge
save us compared totoMap
?
– nullpointer
yesterday
3
@nullpointer This should have been my answer (I'm supposedly thewithout streams guy
here), so I feel I can answer your question... Actually,Collectors.toMap
usesMap.merge
under the hood. It even says so in the docs:mergeFunction - a merge function, used to resolve collisions between values associated with the same key, as supplied to Map.merge(Object, Object, BiFunction)
.
– Federico Peralta Schaffner
yesterday
add a comment |
up vote
1
down vote
If you need a grouping only sorted, it is quite simple:
Map<String, List<Student>> collect = students.stream() // stream capabilities
.sorted(Comparator.comparingInt(Student::getAge).reversed()) // sort by age, descending
.collect(Collectors.groupingBy(Student::getName)); // group by name.
Output in collect:
- Prince=[Student [Age=24, className=B, Name=Prince]],
- Smith=[Student [Age=24, className=A, Name=Smith]],
- John=[Student [Age=30, className=A, Name=John], Student [Age=24, className=A, Name=John], Student [Age=20, className=B, Name=John]]
add a comment |
up vote
1
down vote
Just to mix and merge the other solutions, you could alternatively do :
Map<String, Student> nameToStudentMap = new HashMap<>();
Set<Student> finalListOfStudents = students.stream()
.map(x -> nameToStudentMap.merge(x.getName(), x, (a, b) -> a.getAge() > b.getAge() ? a : b))
.collect(Collectors.toSet());
3
This violates the requirement of statelessness on the parameter ofStream.map
.
– Andy Turner
yesterday
add a comment |
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
13
down vote
Use the toMap
collector:
Collection<Student> values = students.stream()
.collect(toMap(Student::getName,
Function.identity(),
BinaryOperator.maxBy(Comparator.comparingInt(Student::getAge))))
.values();
Explanation
We're using this overload of toMap
:
toMap(Function<? super T,? extends K> keyMapper,
Function<? super T,? extends U> valueMapper,
BinaryOperator<U> mergeFunction)
Student::getName
above is thekeyMapper
function used to extract the values for the map keys.
Function.identity()
above is thevalueMapper
function used to extract the values for the map values whereFunction.identity()
simply returns the elements in the source them selves i.e. theStudent
objects.
BinaryOperator.maxBy(Comparator.comparingInt(Student::getAge))
above is the merge function used to "decide which Student object to return in the case of a key collission i.e. when two given students have the same name" in this case taking the oldestStudent
.- Finally, invoking
values()
returns us a collection of students.
The equivalent C# code being:
var values = students.GroupBy(s => s.Name, v => v,
(a, b) => b.OrderByDescending(e => e.Age).Take(1))
.SelectMany(x => x);
Explanation (for those unfamiliar with .NET)
We're using this extension method of GroupBy
:
System.Collections.Generic.IEnumerable<TResult> GroupBy<TSource,TKey,TElement,TResult>
(this System.Collections.Generic.IEnumerable<TSource> source,
Func<TSource,TKey> keySelector,
Func<TSource,TElement> elementSelector,
Func<TKey,System.Collections.Generic.IEnumerable<TElement>,TResult> resultSelector);
s => s.Name
above is thekeySelector
function used to extract the value to group by.
v => v
above is theelementSelector
function used to extract the values i.e. theStudent
objects them selves.
b.OrderByDescending(e => e.Age).Take(1)
above is theresultSelector
which given anIEnumerable<Student>
represented asb
takes the oldest student.- Finally, we apply
.SelectMany(x => x);
to collapse the resultingIEnumerable<IEnumerable<Student>>
into aIEnumerable<Student>
.
Nice answer. Just wanted to say that usingv -> v
instead ofFunction.identity()
would make the code more similar to the C# equivalent and so easier to compare.
– Luis G.
yesterday
add a comment |
up vote
13
down vote
Use the toMap
collector:
Collection<Student> values = students.stream()
.collect(toMap(Student::getName,
Function.identity(),
BinaryOperator.maxBy(Comparator.comparingInt(Student::getAge))))
.values();
Explanation
We're using this overload of toMap
:
toMap(Function<? super T,? extends K> keyMapper,
Function<? super T,? extends U> valueMapper,
BinaryOperator<U> mergeFunction)
Student::getName
above is thekeyMapper
function used to extract the values for the map keys.
Function.identity()
above is thevalueMapper
function used to extract the values for the map values whereFunction.identity()
simply returns the elements in the source them selves i.e. theStudent
objects.
BinaryOperator.maxBy(Comparator.comparingInt(Student::getAge))
above is the merge function used to "decide which Student object to return in the case of a key collission i.e. when two given students have the same name" in this case taking the oldestStudent
.- Finally, invoking
values()
returns us a collection of students.
The equivalent C# code being:
var values = students.GroupBy(s => s.Name, v => v,
(a, b) => b.OrderByDescending(e => e.Age).Take(1))
.SelectMany(x => x);
Explanation (for those unfamiliar with .NET)
We're using this extension method of GroupBy
:
System.Collections.Generic.IEnumerable<TResult> GroupBy<TSource,TKey,TElement,TResult>
(this System.Collections.Generic.IEnumerable<TSource> source,
Func<TSource,TKey> keySelector,
Func<TSource,TElement> elementSelector,
Func<TKey,System.Collections.Generic.IEnumerable<TElement>,TResult> resultSelector);
s => s.Name
above is thekeySelector
function used to extract the value to group by.
v => v
above is theelementSelector
function used to extract the values i.e. theStudent
objects them selves.
b.OrderByDescending(e => e.Age).Take(1)
above is theresultSelector
which given anIEnumerable<Student>
represented asb
takes the oldest student.- Finally, we apply
.SelectMany(x => x);
to collapse the resultingIEnumerable<IEnumerable<Student>>
into aIEnumerable<Student>
.
Nice answer. Just wanted to say that usingv -> v
instead ofFunction.identity()
would make the code more similar to the C# equivalent and so easier to compare.
– Luis G.
yesterday
add a comment |
up vote
13
down vote
up vote
13
down vote
Use the toMap
collector:
Collection<Student> values = students.stream()
.collect(toMap(Student::getName,
Function.identity(),
BinaryOperator.maxBy(Comparator.comparingInt(Student::getAge))))
.values();
Explanation
We're using this overload of toMap
:
toMap(Function<? super T,? extends K> keyMapper,
Function<? super T,? extends U> valueMapper,
BinaryOperator<U> mergeFunction)
Student::getName
above is thekeyMapper
function used to extract the values for the map keys.
Function.identity()
above is thevalueMapper
function used to extract the values for the map values whereFunction.identity()
simply returns the elements in the source them selves i.e. theStudent
objects.
BinaryOperator.maxBy(Comparator.comparingInt(Student::getAge))
above is the merge function used to "decide which Student object to return in the case of a key collission i.e. when two given students have the same name" in this case taking the oldestStudent
.- Finally, invoking
values()
returns us a collection of students.
The equivalent C# code being:
var values = students.GroupBy(s => s.Name, v => v,
(a, b) => b.OrderByDescending(e => e.Age).Take(1))
.SelectMany(x => x);
Explanation (for those unfamiliar with .NET)
We're using this extension method of GroupBy
:
System.Collections.Generic.IEnumerable<TResult> GroupBy<TSource,TKey,TElement,TResult>
(this System.Collections.Generic.IEnumerable<TSource> source,
Func<TSource,TKey> keySelector,
Func<TSource,TElement> elementSelector,
Func<TKey,System.Collections.Generic.IEnumerable<TElement>,TResult> resultSelector);
s => s.Name
above is thekeySelector
function used to extract the value to group by.
v => v
above is theelementSelector
function used to extract the values i.e. theStudent
objects them selves.
b.OrderByDescending(e => e.Age).Take(1)
above is theresultSelector
which given anIEnumerable<Student>
represented asb
takes the oldest student.- Finally, we apply
.SelectMany(x => x);
to collapse the resultingIEnumerable<IEnumerable<Student>>
into aIEnumerable<Student>
.
Use the toMap
collector:
Collection<Student> values = students.stream()
.collect(toMap(Student::getName,
Function.identity(),
BinaryOperator.maxBy(Comparator.comparingInt(Student::getAge))))
.values();
Explanation
We're using this overload of toMap
:
toMap(Function<? super T,? extends K> keyMapper,
Function<? super T,? extends U> valueMapper,
BinaryOperator<U> mergeFunction)
Student::getName
above is thekeyMapper
function used to extract the values for the map keys.
Function.identity()
above is thevalueMapper
function used to extract the values for the map values whereFunction.identity()
simply returns the elements in the source them selves i.e. theStudent
objects.
BinaryOperator.maxBy(Comparator.comparingInt(Student::getAge))
above is the merge function used to "decide which Student object to return in the case of a key collission i.e. when two given students have the same name" in this case taking the oldestStudent
.- Finally, invoking
values()
returns us a collection of students.
The equivalent C# code being:
var values = students.GroupBy(s => s.Name, v => v,
(a, b) => b.OrderByDescending(e => e.Age).Take(1))
.SelectMany(x => x);
Explanation (for those unfamiliar with .NET)
We're using this extension method of GroupBy
:
System.Collections.Generic.IEnumerable<TResult> GroupBy<TSource,TKey,TElement,TResult>
(this System.Collections.Generic.IEnumerable<TSource> source,
Func<TSource,TKey> keySelector,
Func<TSource,TElement> elementSelector,
Func<TKey,System.Collections.Generic.IEnumerable<TElement>,TResult> resultSelector);
s => s.Name
above is thekeySelector
function used to extract the value to group by.
v => v
above is theelementSelector
function used to extract the values i.e. theStudent
objects them selves.
b.OrderByDescending(e => e.Age).Take(1)
above is theresultSelector
which given anIEnumerable<Student>
represented asb
takes the oldest student.- Finally, we apply
.SelectMany(x => x);
to collapse the resultingIEnumerable<IEnumerable<Student>>
into aIEnumerable<Student>
.
edited yesterday
answered yesterday
Aomine
34.3k62859
34.3k62859
Nice answer. Just wanted to say that usingv -> v
instead ofFunction.identity()
would make the code more similar to the C# equivalent and so easier to compare.
– Luis G.
yesterday
add a comment |
Nice answer. Just wanted to say that usingv -> v
instead ofFunction.identity()
would make the code more similar to the C# equivalent and so easier to compare.
– Luis G.
yesterday
Nice answer. Just wanted to say that using
v -> v
instead of Function.identity()
would make the code more similar to the C# equivalent and so easier to compare.– Luis G.
yesterday
Nice answer. Just wanted to say that using
v -> v
instead of Function.identity()
would make the code more similar to the C# equivalent and so easier to compare.– Luis G.
yesterday
add a comment |
up vote
4
down vote
Or without streams:
Map<String, Student> map = new HashMap<>();
students.forEach(x -> map.merge(x.getName(), x, (oldV, newV) -> oldV.getAge() > newV.getAge() ? oldV : newV));
Collection<Student> max = map.values();
Thought of this while starting of from your initial suggestion, but then an additionalMap
here, but doesmap.merge
save us compared totoMap
?
– nullpointer
yesterday
3
@nullpointer This should have been my answer (I'm supposedly thewithout streams guy
here), so I feel I can answer your question... Actually,Collectors.toMap
usesMap.merge
under the hood. It even says so in the docs:mergeFunction - a merge function, used to resolve collisions between values associated with the same key, as supplied to Map.merge(Object, Object, BiFunction)
.
– Federico Peralta Schaffner
yesterday
add a comment |
up vote
4
down vote
Or without streams:
Map<String, Student> map = new HashMap<>();
students.forEach(x -> map.merge(x.getName(), x, (oldV, newV) -> oldV.getAge() > newV.getAge() ? oldV : newV));
Collection<Student> max = map.values();
Thought of this while starting of from your initial suggestion, but then an additionalMap
here, but doesmap.merge
save us compared totoMap
?
– nullpointer
yesterday
3
@nullpointer This should have been my answer (I'm supposedly thewithout streams guy
here), so I feel I can answer your question... Actually,Collectors.toMap
usesMap.merge
under the hood. It even says so in the docs:mergeFunction - a merge function, used to resolve collisions between values associated with the same key, as supplied to Map.merge(Object, Object, BiFunction)
.
– Federico Peralta Schaffner
yesterday
add a comment |
up vote
4
down vote
up vote
4
down vote
Or without streams:
Map<String, Student> map = new HashMap<>();
students.forEach(x -> map.merge(x.getName(), x, (oldV, newV) -> oldV.getAge() > newV.getAge() ? oldV : newV));
Collection<Student> max = map.values();
Or without streams:
Map<String, Student> map = new HashMap<>();
students.forEach(x -> map.merge(x.getName(), x, (oldV, newV) -> oldV.getAge() > newV.getAge() ? oldV : newV));
Collection<Student> max = map.values();
edited yesterday
answered yesterday
Eugene
67.2k997160
67.2k997160
Thought of this while starting of from your initial suggestion, but then an additionalMap
here, but doesmap.merge
save us compared totoMap
?
– nullpointer
yesterday
3
@nullpointer This should have been my answer (I'm supposedly thewithout streams guy
here), so I feel I can answer your question... Actually,Collectors.toMap
usesMap.merge
under the hood. It even says so in the docs:mergeFunction - a merge function, used to resolve collisions between values associated with the same key, as supplied to Map.merge(Object, Object, BiFunction)
.
– Federico Peralta Schaffner
yesterday
add a comment |
Thought of this while starting of from your initial suggestion, but then an additionalMap
here, but doesmap.merge
save us compared totoMap
?
– nullpointer
yesterday
3
@nullpointer This should have been my answer (I'm supposedly thewithout streams guy
here), so I feel I can answer your question... Actually,Collectors.toMap
usesMap.merge
under the hood. It even says so in the docs:mergeFunction - a merge function, used to resolve collisions between values associated with the same key, as supplied to Map.merge(Object, Object, BiFunction)
.
– Federico Peralta Schaffner
yesterday
Thought of this while starting of from your initial suggestion, but then an additional
Map
here, but does map.merge
save us compared to toMap
?– nullpointer
yesterday
Thought of this while starting of from your initial suggestion, but then an additional
Map
here, but does map.merge
save us compared to toMap
?– nullpointer
yesterday
3
3
@nullpointer This should have been my answer (I'm supposedly the
without streams guy
here), so I feel I can answer your question... Actually, Collectors.toMap
uses Map.merge
under the hood. It even says so in the docs: mergeFunction - a merge function, used to resolve collisions between values associated with the same key, as supplied to Map.merge(Object, Object, BiFunction)
.– Federico Peralta Schaffner
yesterday
@nullpointer This should have been my answer (I'm supposedly the
without streams guy
here), so I feel I can answer your question... Actually, Collectors.toMap
uses Map.merge
under the hood. It even says so in the docs: mergeFunction - a merge function, used to resolve collisions between values associated with the same key, as supplied to Map.merge(Object, Object, BiFunction)
.– Federico Peralta Schaffner
yesterday
add a comment |
up vote
1
down vote
If you need a grouping only sorted, it is quite simple:
Map<String, List<Student>> collect = students.stream() // stream capabilities
.sorted(Comparator.comparingInt(Student::getAge).reversed()) // sort by age, descending
.collect(Collectors.groupingBy(Student::getName)); // group by name.
Output in collect:
- Prince=[Student [Age=24, className=B, Name=Prince]],
- Smith=[Student [Age=24, className=A, Name=Smith]],
- John=[Student [Age=30, className=A, Name=John], Student [Age=24, className=A, Name=John], Student [Age=20, className=B, Name=John]]
add a comment |
up vote
1
down vote
If you need a grouping only sorted, it is quite simple:
Map<String, List<Student>> collect = students.stream() // stream capabilities
.sorted(Comparator.comparingInt(Student::getAge).reversed()) // sort by age, descending
.collect(Collectors.groupingBy(Student::getName)); // group by name.
Output in collect:
- Prince=[Student [Age=24, className=B, Name=Prince]],
- Smith=[Student [Age=24, className=A, Name=Smith]],
- John=[Student [Age=30, className=A, Name=John], Student [Age=24, className=A, Name=John], Student [Age=20, className=B, Name=John]]
add a comment |
up vote
1
down vote
up vote
1
down vote
If you need a grouping only sorted, it is quite simple:
Map<String, List<Student>> collect = students.stream() // stream capabilities
.sorted(Comparator.comparingInt(Student::getAge).reversed()) // sort by age, descending
.collect(Collectors.groupingBy(Student::getName)); // group by name.
Output in collect:
- Prince=[Student [Age=24, className=B, Name=Prince]],
- Smith=[Student [Age=24, className=A, Name=Smith]],
- John=[Student [Age=30, className=A, Name=John], Student [Age=24, className=A, Name=John], Student [Age=20, className=B, Name=John]]
If you need a grouping only sorted, it is quite simple:
Map<String, List<Student>> collect = students.stream() // stream capabilities
.sorted(Comparator.comparingInt(Student::getAge).reversed()) // sort by age, descending
.collect(Collectors.groupingBy(Student::getName)); // group by name.
Output in collect:
- Prince=[Student [Age=24, className=B, Name=Prince]],
- Smith=[Student [Age=24, className=A, Name=Smith]],
- John=[Student [Age=30, className=A, Name=John], Student [Age=24, className=A, Name=John], Student [Age=20, className=B, Name=John]]
edited yesterday
answered yesterday
michaeak
690315
690315
add a comment |
add a comment |
up vote
1
down vote
Just to mix and merge the other solutions, you could alternatively do :
Map<String, Student> nameToStudentMap = new HashMap<>();
Set<Student> finalListOfStudents = students.stream()
.map(x -> nameToStudentMap.merge(x.getName(), x, (a, b) -> a.getAge() > b.getAge() ? a : b))
.collect(Collectors.toSet());
3
This violates the requirement of statelessness on the parameter ofStream.map
.
– Andy Turner
yesterday
add a comment |
up vote
1
down vote
Just to mix and merge the other solutions, you could alternatively do :
Map<String, Student> nameToStudentMap = new HashMap<>();
Set<Student> finalListOfStudents = students.stream()
.map(x -> nameToStudentMap.merge(x.getName(), x, (a, b) -> a.getAge() > b.getAge() ? a : b))
.collect(Collectors.toSet());
3
This violates the requirement of statelessness on the parameter ofStream.map
.
– Andy Turner
yesterday
add a comment |
up vote
1
down vote
up vote
1
down vote
Just to mix and merge the other solutions, you could alternatively do :
Map<String, Student> nameToStudentMap = new HashMap<>();
Set<Student> finalListOfStudents = students.stream()
.map(x -> nameToStudentMap.merge(x.getName(), x, (a, b) -> a.getAge() > b.getAge() ? a : b))
.collect(Collectors.toSet());
Just to mix and merge the other solutions, you could alternatively do :
Map<String, Student> nameToStudentMap = new HashMap<>();
Set<Student> finalListOfStudents = students.stream()
.map(x -> nameToStudentMap.merge(x.getName(), x, (a, b) -> a.getAge() > b.getAge() ? a : b))
.collect(Collectors.toSet());
edited yesterday
answered yesterday
nullpointer
37.5k1072145
37.5k1072145
3
This violates the requirement of statelessness on the parameter ofStream.map
.
– Andy Turner
yesterday
add a comment |
3
This violates the requirement of statelessness on the parameter ofStream.map
.
– Andy Turner
yesterday
3
3
This violates the requirement of statelessness on the parameter of
Stream.map
.– Andy Turner
yesterday
This violates the requirement of statelessness on the parameter of
Stream.map
.– Andy Turner
yesterday
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53635022%2fjava-8-lambda-filtering-based-on-condition-as-well-as-order%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
7
students.stream().collect(groupingBy(...))
.– Andy Turner
yesterday
Do you only want a list of the oldest and only the oldest ones?
– michaeak
yesterday
Please tell what is the desired result. I.e. How the map/list/whatever looks like.
– michaeak
yesterday