I'm iterating all Student
data using natural sorting method of java 8 sorted()
. While iterating student data, get exception in IDE console class com.java8.Student cannot be cast to class java.lang.Comparable
. My StreamStudent.java
file is inside com.java8
package.
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()));
}
}
CodePudding user response:
Student
must implement Comparable. The implementation of Comparable is what defines the natural ordering.
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.
public class Student implements Comparable<Student> {
@Override
public int compareTo(Student o) {
//implement comparison here
return 0;
}
}
CodePudding user response:
The elements of your stream must implement the Comparable
interface in order to be sorted via the sorted()
stream operation. 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)
. This way you can still sort your elements without having to change the Student
's implementation.
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 ...
}
}
CodePudding user response:
Your student class should implement Comparable
interface so it can be sorted:
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<Student> studentComparator
= Comparator.comparing(Student::getLastName).thenComparing(Student::getFirstName);
List<Student> studentsSorted = stdList.stream().sorted(studentComparator).collect(Collectors.toList());
CodePudding user response:
You need to implement Comparable. Here a link that might help you. You have to implement the method compareTo