Java 8 Lambda:比较器
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/44225896/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java 8 Lambda: Comparator
提问by Nu?ito de la Calzada
I want to sort a list with Lambda:
我想用 Lambda 对列表进行排序:
List<Message> messagesByDeviceType = new ArrayList<Message>();
messagesByDeviceType.sort((Message o1, Message o2)->o1.getTime()-o2.getTime());
But I got this compilation error:
但是我得到了这个编译错误:
Multiple markers at this line
- Type mismatch: cannot convert from long to int
- The method sort(Comparator<? super Message>) in the type List<Message> is not applicable for the arguments ((Message o1, Message o2)
-> {})
采纳答案by Eugene
Comparator#compareTo
returns an int
; while getTime
is obviously long
.
Comparator#compareTo
返回一个int
; 而getTime
显然是long
。
It would be nicer written like this:
像这样写会更好:
.sort(Comparator.comparingLong(Message::getTime))
回答by Eran
The Comparator
's compare()
method must return an int
, and it seems yours is returning a long
.
TheComparator
的compare()
方法必须返回一个int
,而您的方法似乎正在返回一个long
。
You can change it to:
您可以将其更改为:
(Message o1, Message o2)->Long.compare(o1.getTime(),o2.getTime())
This is assuming (based on your error message) that o1.getTime()
returns a long
.
这是假设(基于您的错误消息)o1.getTime()
返回long
.
回答by Tony
Lambda
拉姆达
The lambda can be seen as the shorthand of somewhat cumbersome anonymous class:
可以将 lambda 视为有些繁琐的匿名类的简写:
Java8 version:
Java8版本:
Collections.sort(list, (o1, o2) -> o1.getTime() - o2.getTime());
Pre-Java8 version:
Java8 之前的版本:
Collections.sort(list, new Comparator<Message>() {
@Override
public int compare(Message o1, Message o2) {
return o1.getTime() - o2.getTime();
}
});
So, every time you are confused how to write a right lambda, you may try to write a pre-lambda version, and see how it is wrong.
因此,每次当您对如何编写正确的 lambda 感到困惑时,您可以尝试编写一个 pre-lambda 版本,看看它是如何出错的。
Application
应用
In your specific problem, you can see the compare
returns int
, where your getTime
returns long, which is the source of error.
在您的具体问题中,您可以看到compare
Returns int
,其中您的getTime
返回很长,这是错误的来源。
You may use either method as other answer method, like:
您可以使用任一方法作为其他答案方法,例如:
Long.compare(o1.getTime(),o2.getTime())
Notice
注意
- You should avoid using
-
inComparator
, which may causes overflow, in some cases, and crash your program.
- 您应该避免使用
-
inComparator
,这在某些情况下可能会导致溢出并导致程序崩溃。
回答by Yash
Comparator
比较器
We use comparator interface to sort homogeneous and heterogeneous elements for default, customized sorting order.
我们使用比较器接口为默认的、自定义的排序顺序对同质和异质元素进行排序。
int compare(T o1, T o2);
it takes two arguments for ordering. Returns a
negative integer(-1) ? if first argument is less than the other zero (0) ? if both are equal positive integer (1) ? if first greater than the second.
int compare(T o1, T o2);
排序需要两个参数。返回一个
negative integer(-1) ? if first argument is less than the other zero (0) ? if both are equal positive integer (1) ? if first greater than the second.
Anonymous Classeshow to sort a list of objects in prior versions of Java 8using inner Classes.
匿名类如何使用内部类对 Java 8 以前版本中的对象列表进行排序。
An anonymous class cannot access local variables in its enclosing scope that are not declared as final or effectively final.
匿名类不能访问其封闭范围内未声明为 final 或有效 final 的局部变量。
Comparator<Employee> timeCompare = new Comparator<Employee>() {
@Override public int compare(Employee e1, Employee e2) {
return e1.getCreationTime().compareTo( e2.getCreationTime() );
}
};
Java 8 Lambda Expressions
uing compare method
Java 8 使用Lambda Expressions
比较方法
A lambda expression is like a method: it provides a list of formal parameters and a body - an expression or block - expressed in terms of those parameters.
LambdaExpression:
LambdaParameters -> LambdaBody
Any local variable, formal parameter, or exception parameter used but not declared in a lambda expression must either be declared final or be effectively final, or a compile-time error occurs where the use is attempted.
一个 lambda 表达式就像一个方法:它提供一个形式参数列表和一个主体——一个表达式或块——用这些参数表示。
拉姆达表达式:
LambdaParameters -> LambdaBody
任何使用但未在 lambda 表达式中声明的局部变量、形式参数或异常参数必须声明为 final 或有效 final,否则在尝试使用时会发生编译时错误。
Comparator<Employee> functional_semantics = (e1, e2) -> {
return e1.getCreationTime().compareTo( e2.getCreationTime() );
};
Basic Sort with Lambda Support
支持 Lambda 的基本排序
Comparator<Employee> timeCompareLambda = (o1, o2) -> (int) ( o1.getCreationTime() - o2.getCreationTime());
Collections.sort(java8, timeCompareLambda );
Using Extracted Key and Comparing method: A comparator that compares by an extracted key. Pass references using :: keyword.
Using Extracted Key and Comparing method:通过提取的键进行比较的比较器。使用 :: 关键字传递引用。
static <T> Comparator<T> comparingLong(ToLongFunction<? super T> keyExtractor)
static <T> Comparator<T> comparingLong(ToLongFunction<? super T> keyExtractor)
ToLongFunction<Employee> keyExtracor = Employee::getCreationTime;
Comparator<Employee> byTime = Comparator.comparingLong( Employee::getCreationTime );
Sample Test Code:
示例测试代码:
public class Lambda_Long_Comparator {
public static void main(String[] args) {
List<Employee> java7 = getEmployees();
// Sort with Inner Class
Comparator<Employee> timeCompare = new Comparator<Employee>() {
@Override public int compare(Employee e1, Employee e2) {
return e1.getCreationTime().compareTo( e2.getCreationTime() );
}
};
// Collections.sort(list); // Defaults to Comparable<T> ? @compareTo(o1)
Collections.sort(java7, timeCompare); // Comparator<T> ? @compare (o1,o2)
System.out.println("Java < 8 \n"+ java7);
List<Employee> java8 = getEmployees();
Collections.sort(java8, Comparator
.comparing( Employee::getCreationTime )
.thenComparing( Employee::getName ));
//java8.forEach((emp)-> System.out.println(emp));
System.out.println("Java 8 \n"+java8);
}
static List<Employee> getEmployees() {
Date date = Calendar.getInstance().getTime();
List<Employee> list = new ArrayList<Employee>();
list.add( new Employee(4, "Yash", date.getTime()+7));
list.add( new Employee(2, "Raju", date.getTime()+1));
list.add( new Employee(4, "Yas", date.getTime()));
list.add( new Employee(7, "Sam", date.getTime()-4));
list.add( new Employee(8, "John", date.getTime()));
return list;
}
}
class Employee implements Comparable<Employee> {
Integer id;
String name;
Long creationTime;
public Employee(Integer id, String name, Long creationTime) {
this.id = id;
this.name = name;
this.creationTime = creationTime;
}
@Override public int compareTo(Employee e) {
return this.id.compareTo(e.id);
}
@Override public String toString() {
return "\n["+this.id+","+this.name+","+this.creationTime+"]";
}
// Other getter and setter methods
}
See these posts also:
另请参阅这些帖子:
回答by isapir
You should change
你应该改变
messagesByDeviceType.sort( (Message o1, Message o2) -> o1.getTime() - o2.getTime() );
messagesByDeviceType.sort( (Message o1, Message o2) -> o1.getTime() - o2.getTime() );
to
到
messagesByDeviceType.sort(
Comparator.comparing((Message m) -> m.getTime())
);
That assumes that the value is Comparable
, which provides a natural sort order.
假设值为Comparable
,它提供了自然的排序顺序。
If you want to add more fields then you can can chain them to the Comparator. e.g. to sort first by time, and then by sender:
如果要添加更多字段,则可以将它们链接到比较器。例如先按时间排序,然后按发件人排序:
messagesByDeviceType.sort(
Comparator
.comparing((Message m) -> m.getTime())
.thenComparing((m) -> m.getSender())
);
To reverse the order of any Comparator
, chain the reveresed()
method to it, e.g. to sort first by time descending, and then by sender:
要反转 any 的顺序Comparator
,请将reveresed()
方法链接到它,例如首先按时间降序排序,然后按发件人排序:
messagesByDeviceType.sort(
Comparator
.comparing((Message m) -> m.getTime())
.reversed()
.thenComparing((m) -> m.getSender())
);
See also https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html
另见https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html
回答by Raj
The compare()
method must return an int
, and it seems yours is returning a long
.
该compare()
方法必须返回一个int
,而您的方法似乎正在返回一个long
。
You can change it this into:
你可以把它改成:
Long.compare(o1.getTime(),o2.getTime())
Well explained regarding lambda comparator in the below presented video link.
在下面提供的视频链接中对 lambda 比较器进行了很好的解释。
回答by bhargava krishna
lamda comparator
拉姆达比较器
In the place of Developer write your class name
Comparator<Developer> byName =
(Developer o1, Developer o2)->o1.getName().compareTo(o2.getName());