Java 8 lambda过滤基于条件和顺序 [英] Java 8 lambda filtering based on condition as well as order
本文介绍了Java 8 lambda过滤基于条件和顺序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我试图根据多个条件过滤列表,排序。
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"));
我如何能够获得具有不同名称的最年长学生的名单?
在C#中,通过使用System.Linq GroupBy然后比较然后使用select进行展平,这将非常简单,我不太确定如何在Java中实现相同的效果。
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.
推荐答案
使用 toMap
收藏家:
Use the toMap
collector:
Collection<Student> values = students.stream()
.collect(toMap(Student::getName,
Function.identity(),
BinaryOperator.maxBy(Comparator.comparingInt(Student::getAge))))
.values();
解释
我们正在使用的重载来映射
:
toMap(Function<? super T,? extends K> keyMapper,
Function<? super T,? extends U> valueMapper,
BinaryOperator<U> mergeFunction)
-
上面的学生:: getName
是keyMapper
用于提取地图键值的函数。 -
Function.identity()
以上是valueMapper
函数,用于提取映射值的值,其中Function.identity()
只返回元素他们自己的来源,即学生
对象。 -
BinaryOperator.maxBy(Comparator.comparingInt(Student :: getAge))
上面是合并函数,用于决定在一个关键的碰撞情况下返回哪个学生对象,即当两个给定的学生有同名在这种情况下,取最旧的学生
。 - 最后,调用
values()
向我们返回一系列学生。 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.
等效的C#代码为:
var values = students.GroupBy(s => s.Name, v => v,
(a, b) => b.OrderByDescending(e => e.Age).Take(1))
.SelectMany(x => x);
解释(对于那些不熟悉.NET的人)
Explanation (for those unfamiliar with .NET)
我们正在使用 GroupBy
:
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
上面是用于提取值的keySelector
函数。 -
v => v
上面是elementSelector
函数,用于提取值,即学生
对象自我。 -
b.OrderByDescending(e => e.Age)。获取(1)
以上是resultSelector
给出IEnumerable< Student>
表示为b
取最年长的学生。 - 最后,我们应用
.SelectMany(x => x);
来折叠生成的IEnumerable< IEnumerable< Student>>
进入IEnumerable< Student>
。 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>
.
这篇关于Java 8 lambda过滤基于条件和顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文