Java 8 Lambda:比较器

Nuñ*_*ada 43 java lambda comparator java-8

我想用Lambda对列表进行排序:

List<Message> messagesByDeviceType = new ArrayList<Message>();      
messagesByDeviceType.sort((Message o1, Message o2)->o1.getTime()-o2.getTime());
Run Code Online (Sandbox Code Playgroud)

但是我得到了这个编译错误:

 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) 
     -> {})
Run Code Online (Sandbox Code Playgroud)

Eug*_*ene 78

Comparator#compareTo返回int; 虽然getTime很明显long.

它会像这样写得更好:

 .sort(Comparator.comparingLong(Message::getTime))
Run Code Online (Sandbox Code Playgroud)


Era*_*ran 22

该方法必须返回一个,而你Comparatorcompare()方法int似乎正在返回一个long.

您可以将其更改为:

(Message o1, Message o2)->Long.compare(o1.getTime(),o2.getTime())
Run Code Online (Sandbox Code Playgroud)

这是假设(基于您的错误消息)o1.getTime()返回a long.


Ton*_*ony 21

LAMBDA

lambda可以看作是一些有点麻烦的匿名类的简写:

Java8版本:

Collections.sort(list, (o1, o2) -> o1.getTime() - o2.getTime());
Run Code Online (Sandbox Code Playgroud)

Pre-Java8版本:

    Collections.sort(list, new Comparator<Message>() {
        @Override
        public int compare(Message o1, Message o2) {
            return o1.getTime() - o2.getTime();
        }
    }); 
Run Code Online (Sandbox Code Playgroud)

所以,每当你对如何编写正确的lambda感到困惑时,你可能会尝试编写一个pre-lambda版本,看看它是怎么回事.

应用

在您的特定问题中,您可以看到compare返回值int,getTime返回值很长,这是错误的来源.

您可以使用任一方法作为其他答案方法,例如:

Long.compare(o1.getTime(),o2.getTime())
Run Code Online (Sandbox Code Playgroud)

注意

  • 您应该避免使用-in Comparator,这可能会导致溢出,在某些情况下,并导致程序崩溃.


Yas*_*ash 8

比较

我们使用比较器接口对同类和异构元素进行排序,以实现默认的自定义排序顺序.

int compare(T o1, T o2);
Run Code Online (Sandbox Code Playgroud)

它需要两个参数来进行排序.返回一个

    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.
Run Code Online (Sandbox Code Playgroud)

匿名类 如何使用内部类对Java 8的早期版本中的对象列表进行排序.

匿名类无法访问其封闭范围中未声明为final或者有效final的局部变量.

Comparator<Employee> timeCompare = new Comparator<Employee>() {
    @Override public int compare(Employee e1, Employee e2) {
        return e1.getCreationTime().compareTo( e2.getCreationTime() );
    }
};
Run Code Online (Sandbox Code Playgroud)

Java 8 Lambda Expressionsuing比较方法

lambda表达式就像一个方法:它提供了一个形式参数列表和一个正文 - 一个表达式或块 - 用这些参数表示.

LambdaExpression:LambdaParameters -> LambdaBody

使用但未在lambda表达式中声明的任何局部变量,形式参数或异常参数必须声明为final或有效final,否则在尝试使用时会发生编译时错误.

Comparator<Employee> functional_semantics = (e1, e2) -> {
   return e1.getCreationTime().compareTo( e2.getCreationTime() );
};
Run Code Online (Sandbox Code Playgroud)

基本排序Lambda支持

Comparator<Employee> timeCompareLambda = (o1, o2) -> (int) ( o1.getCreationTime() - o2.getCreationTime());
Collections.sort(java8, timeCompareLambda );
Run Code Online (Sandbox Code Playgroud)

使用提取键和比较方法:通过提取的键进行比较的比较器.使用:: keyword传递引用.

static <T> Comparator<T> comparingLong(ToLongFunction<? super T> keyExtractor)
Run Code Online (Sandbox Code Playgroud)
ToLongFunction<Employee> keyExtracor = Employee::getCreationTime;
Comparator<Employee> byTime = Comparator.comparingLong( Employee::getCreationTime );
Run Code Online (Sandbox Code Playgroud)

样品测试代码:

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
}
Run Code Online (Sandbox Code Playgroud)

另见这些帖子: