我有一个Duck对象的集合,我想用多个键对它们进行排序.
class Duck {
DuckAge age; //implements Comparable
DuckWeight weight; //implements Comparable
String name;
}
List<Duck> ducks = Pond.getDucks();
Run Code Online (Sandbox Code Playgroud)
例如.我想主要根据他们的重量来排序,其次是他们的年龄.如果两只鸭子具有完全相同的重量和完全相同的年龄,那么让我们使用它们的名称作为三级键来区分它们.我可能会这样做:
Collections.sort(ducks, new Comparator<Duck>(){
@Override
public int compare(Duck d1, Duck d2){
int weightCmp = d1.weight.compareTo(d2.weight);
if (weightCmp != 0) {
return weightCmp;
}
int ageCmp = d1.age.compareTo(d2.age);
if (ageCmp != 0) {
return ageCmp;
}
return d1.name.compareTo(d2.name);
}
});
Run Code Online (Sandbox Code Playgroud)
我经常这样做,但这个解决方案闻不到.它不能很好地扩展,并且很容易搞砸.当然必须有一种更好的方法来使用多个键对Ducks进行排序!有人知道更好的解决方案吗?
EDIT删除了不必要的else分支
这是来自Oracle的JDK 8实现的Stream接口:
public interface Stream<T> extends BaseStream<T, Stream<T>> {
Stream<T> sorted();
}
Run Code Online (Sandbox Code Playgroud)
并且很容易在运行时将其清除,并且在编译时不会生成警告.这是一个例子:
class Foo {
public static void main(String[] args) {
Arrays.asList(new Foo(), new Foo()).stream().sorted().forEach(f -> {});
}
}
Run Code Online (Sandbox Code Playgroud)
这将编译得很好,但会在运行时抛出异常:
Exception in thread "main" java.lang.ClassCastException: Foo cannot be cast to java.lang.Comparable
Run Code Online (Sandbox Code Playgroud)
sorted在编译器实际可以捕获这些问题的地方没有定义该方法的原因是什么?也许我错了,但不是这么简单:
interface Stream<T> {
<C extends Comparable<T>> void sorted(C c);
}
Run Code Online (Sandbox Code Playgroud)
?
显然,那些实现这一点的人(考虑到编程和工程方面比我早了几年)必须有一个很好的理由,我无法看到,但这是什么原因?
Comparable合同规定e.compareTo(null)必须抛出NullPointerException.
来自API:
请注意,这
null不是任何类的实例,并且e.compareTo(null)应该抛出一个NullPointerException偶数e.equals(null)返回false.
另一方面,ComparatorAPI没有提及比较时需要发生的事情null.考虑以下尝试采用a的泛型方法Comparable,并Comparator为其null作为最小元素返回.
static <T extends Comparable<? super T>> Comparator<T> nullComparableComparator() {
return new Comparator<T>() {
@Override public int compare(T el1, T el2) {
return
el1 == null ? -1 :
el2 == null ? +1 :
el1.compareTo(el2);
}
};
}
Run Code Online (Sandbox Code Playgroud)
这允许我们执行以下操作:
List<Integer> numbers = new ArrayList<Integer>(
Arrays.asList(3, 2, 1, null, …Run Code Online (Sandbox Code Playgroud) 我正在学习数组,基本上我有一个收集姓氏,名字和分数的数组.
我需要编写一个compareTo方法来比较姓氏和名字,以便列表可以按字母顺序从姓氏开始排序,然后如果两个人的姓氏相同,那么它将对第一个名称进行排序.
我很困惑,因为我书中的所有信息都是比较数字,而不是对象和字符串.
这是我到目前为止编码的内容.我知道这是错的,但它至少解释了我认为我在做什么:
public int compare(Object obj) // creating a method to compare
{
Student s = (Student) obj; // creating a student object
// I guess here I'm telling it to compare the last names?
int studentCompare = this.lastName.compareTo(s.getLastName());
if (studentCompare != 0)
return studentCompare;
else
{
if (this.getLastName() < s.getLastName())
return - 1;
if (this.getLastName() > s.getLastName())
return 1;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我知道<和>符号是错误的,但就像我说我的书只告诉你如何使用compareTo.
我正在创建一个简单的程序来了解Java Comparator类.我已按Arraylist顺序排序,但现在我想按降序对列表进行排序,但是在调用.reverseOrder()方法时遇到问题,因为我使用了一个实现的内部类Comparator<Song>(歌曲是一个包含getter和setter方法的歌曲类).
这是我的SongSort班级,其中包括分拣过程等.
import java.util.*;
import java.io.*;
public class SongSort
{
ArrayList<Song> songList = new ArrayList<Song>();
public void main(String[] args)
{
new SongSort().go();
}
class ArtistCompare implements Comparator<Song>
{
public int compare(Song one, Song two)
{
return one.getRating().compareTo(two.getRating());
}
}
public void go()
{
getSongs();
System.out.println(songList);
//Collections.sort(songList);
System.out.println(songList);
ArtistCompare artistCompare = new ArtistCompare();
Collections.sort(songList, artistCompare);
System.out.println(songList);
}
public void getSongs()
{
try{
File file = new File("SongListMore.txt");
BufferedReader reader = new BufferedReader(new …Run Code Online (Sandbox Code Playgroud) 我有一个类,我已经用一个属性对它进行排序.现在我需要做另一件事,我需要创建另一种方法来对数据进行排序.我该怎么做,所以我可以在两种方法之间做出选择.我知道的唯一命令是Collections.sort,它将从我想要比较其数据的类中获取方法compareTo.
它甚至可能吗?
如果我java.lang.Comparable为一个类实现,我仍然必须覆盖该equals()方法吗?或者也将Comparable工作equals?
如果答案是否定的,那么如果出现一些差异怎么办?假设我在equals()方法中将两个对象称为相等的方式不同于我将两个相同类的对象称为相等的compareTo()方式Comparable.
而且,如果我实施Comparable,我还必须覆盖equals()吗?
为什么要Collections.sort(List<T>)签名:
public static <T extends Comparable<? super T>> void sort(List<T> list)
Run Code Online (Sandbox Code Playgroud)
并不是 :
public static <T extends Comparable<T>> void sort(List<? extends T> list)
Run Code Online (Sandbox Code Playgroud)
我正在尝试将排序列表实现为Java中的简单练习.为了使它具有通用性我有一个add(Comparable obj)所以我可以在任何实现Comparable接口的类中使用它.
但是,当我obj.compareTo(...)在代码中的任何地方使用时,我"unchecked call to compareTo(T) as a member of the raw type java.lang.Comparable"从编译器(带-Xlint:unchecked选项)获得.代码工作正常,但我无法弄清楚如何摆脱这个恼人的消息.
任何提示?
我可以使用它按emp id排序,但我不确定是否可以比较字符串.我得到一个错误,操作符未定义为字符串.
public int compareTo(Emp i) {
if (this.getName() == ((Emp ) i).getName())
return 0;
else if ((this.getName()) > ((Emp ) i).getName())
return 1;
else
return -1;
Run Code Online (Sandbox Code Playgroud) comparable ×10
java ×10
generics ×3
sorting ×3
collections ×2
comparator ×2
compareto ×2
equals ×1
java-8 ×1
java-stream ×1
null ×1
unchecked ×1