简体   繁体   English

为什么不能将获取类强制转换为类 java.lang.Comparable

[英]Why get class cannot be cast to class java.lang.Comparable

I'm iterating all Student data using natural sorting method of java 8 sorted() .我正在使用 java 8 sorted()的自然排序方法迭代所有Student数据。 While iterating student data, get exception in IDE console class com.java8.Student cannot be cast to class java.lang.Comparable .迭代学生数据时,IDE 控制台class com.java8.Student cannot be cast to class java.lang.Comparable My StreamStudent.java file is inside com.java8 package.我的StreamStudent.java文件在com.java8包中。

Here is my full stack trace:这是我的完整堆栈跟踪:

Exception in thread "main" java.lang.ClassCastException: class com.java8.Student cannot be cast to class java.lang.Comparable (com.java8.Student is in unnamed module of loader 'app'; java.lang.Comparable is in module java.base of loader 'bootstrap')
    at java.base/java.util.Comparators$NaturalOrderComparator.compare(Comparators.java:47)
    at java.base/java.util.TimSort.countRunAndMakeAscending(TimSort.java:355)
    at java.base/java.util.TimSort.sort(TimSort.java:220)
    at java.base/java.util.Arrays.sort(Arrays.java:1307)
    at java.base/java.util.stream.SortedOps$SizedRefSortingSink.end(SortedOps.java:353)
    at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:510)
    at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
    at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921)
    at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:682)
    at com.java8.StreamStudent.main(StreamStudent.java:72)

Here down is my code:下面是我的代码:

package com.java8;

import java.util.*;
import java.util.stream.*;

class Student{
    String firstName;
    String lastName;
    Integer groupId;
    Integer age;

    // constructor and getter, setter

}

public class StreamStudent {
    public static void main(String[] args) {
        List<Student> stdList = new ArrayList<>();
        stdList.add(new Student("Sara", "Mills", 1, 18));
        stdList.add(new Student("Andrew", "Gibson", 2, 21));
        stdList.add(new Student("Craig", "Ellis", 1, 23));
        stdList.add(new Student("Steven", "Cole", 2, 19));
        stdList.add(new Student("Andrew", "Carter", 2, 2));

        
        System.out.println("1. Sort all student firstname by name");
        List<Student> students =  stdList.stream().sorted().collect(Collectors.toList());
        students.forEach((s) -> System.out.println(s.getFirstName() + " " + s.getLastName() + " " + s.getGroupId() + " " + s.getAge()));
    }
}

Student must implement Comparable . Student必须实现Comparable The implementation of Comparable is what defines the natural ordering. Comparable 的实现定义了自然排序。

This interface imposes a total ordering on the objects of each class that implements it.该接口对实现它的每个类的对象进行了总排序。 This ordering is referred to as the class's natural ordering, and the class's compareTo method is referred to as its natural comparison method.这种排序称为类的自然排序,类的 compareTo 方法称为其自然比较方法。

public class Student implements Comparable<Student> {

  @Override
  public int compareTo(Student o) {
    //implement comparison here
    return 0;
  }
}

The elements of your stream must implement the Comparable interface in order to be sorted via the sorted() stream operation.流的元素必须实现Comparable接口才能通过sorted()流操作进行排序。 Alternatively, if you cannot change the implementation of the Student class, you can supply a Comparator instance to the overloaded version sorted(Comparator<? super T> comparator) .或者,如果您无法更改Student类的实现,则可以将Comparator实例提供给重载版本sorted(Comparator<? super T> comparator) This way you can still sort your elements without having to change the Student 's implementation.这样,您仍然可以对元素进行排序,而无需更改Student的实现。

https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#sorted-java.util.Comparator- https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#sorted-java.util.Comparator-

Student Implementing Comparable学生实施可比

class Student implements Comparable<Student> {
    String firstName;
    String lastName;
    Integer groupId;
    Integer age;

    // constructor and getter, setter

    @Override
    public int compareTo(Student o) {
        return Comparator.comparing(Student::getFirstName).thenComparing(Student::getLastName).compare(this, o);
    }
}

public class StreamStudent {
    public static void main(String[] args) {
        // ... same code of yours ...

        List<Student> students =  stdList.stream().sorted().collect(Collectors.toList());

        // ... same code of yours ...
    }
}

Supply a Comparator to sorted提供一个比较器来排序

public class StreamStudent {
    public static void main(String[] args) {
        // ... same code of yours ...

        List<Student> students =  stdList.stream().sorted(Comparator.comparing(Student::getFirstName).thenComparing(Student::getLastName)).collect(Collectors.toList());

        // ... same code of yours ...
    }
}     

You need to implement Comparable.您需要实现 Comparable。 Here a link that might help you.这是一个可能对您有所帮助的链接 You have to implement the method compareTo您必须实现方法 compareTo

Your student class should implement Comparable interface so it can be sorted:您的学生类应该实现Comparable接口,以便对其进行排序:

class Student implements Comparable<Student> {
    String firstName;
    String lastName;
    Integer groupId;
    Integer age;

    @Override
    public int compareTo(Student o) {
        return this.firstName.compareTo(o.firstName);

        //In case you want compare based on multiple fields
        /*
        return Comparator
              .comparing((Student s)->s.lastName)
              .thenComparing(s->s.firstName)
              .compare(this, o);
       */
    }
}

Another solution is implementing Comparator interface for class and passing it as input to sorted method, This is useful in cases that you want sort bases on different fields in different sitations:另一个解决方案是为类实现 Comparator 接口并将其作为输入传递给 sorted 方法,这在您希望基于不同位置的不同字段进行排序的情况下很有用:

Comparator<Student> studentComparator
        = Comparator.comparing(Student::getLastName).thenComparing(Student::getFirstName);

List<Student> studentsSorted =  stdList.stream().sorted(studentComparator).collect(Collectors.toList());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM