如果我有一个我想要排序的元素列表,Java提供了两种方法来解决这个问题.
例如,假设我有一个Movie对象列表,我想按标题对它们进行排序.
我可以这样做的一种方法是通过调用静态java.util.Collections.sort()方法的单参数版本,并将我的电影列表作为单个参数.所以我会调用Collections.sort(myMovieList).为了使其工作,必须声明Movie类以实现java.lang.Comparable接口,并且必须在此类中实现所需的方法compareTo().
另一种排序方法是使用影片列表和java.util.Comparator对象作为参数调用静态java.util.Collections.sort()方法的双参数版本.我会调用Collections.sort(myMovieList,titleComparator).在这种情况下,Movie类不会实现Comparable接口.相反,在构建和维护影片列表本身的主类中,我将创建一个实现java.util.Comparator接口的内部类,并实现一个必需的方法compare().然后我将创建此类的实例并调用sort()的双参数版本.第二种方法的好处是您可以创建无限数量的这些内部类比较器,因此您可以以不同的方式对对象列表进行排序.在上面的例子中,
我的问题是,为什么麻烦学习两种方式在Java中进行排序,当Collections.sort()的双参数版本执行第一个单参数版本所做的所有事情时,还有一个额外的好处就是能够对列表的元素进行排序基于几个不同的标准?在编码时必须记住这一点.你有一个基本机制,用Java来排序列表来了解.
我有一个方法需要一个Comparator参数.我想传递一个Comparator其中做了正常比较和一个反向,其确实在反向比较器.
java.util.Collections提供一个reverseOrder()这对反向比较有好处,但我找不到任何正常的Comparator.
我想到的唯一解决方案是Collections.reverseOrder(Collections.reverseOrder()).但我不喜欢它因为调用里面的双重方法.
当然我可以这样写NormalComparator:
public class NormalComparator<T extends Comparable> implements Comparator<T> {
public int compare(T o1, T o2) {
return o1.compareTo(o2);
}
}
Run Code Online (Sandbox Code Playgroud)
但我真的很惊讶Java没有开箱即用的解决方案.
是否有一种简单的方法(即使用太空船操作员)根据两个不同的属性在Ruby中定义比较?即如果我有一个包含两个属性attr1和attr2的类,是否有一种Rubyesque方法来比较attr1上这个类的两个实例,如果它们相等,那么在attr2上比较它们?
我有一个存储可比数据的通用java类:
public class MyGenericStorage<T extends Comparable<T>> {
private T value;
public MyGenericStorage(T value) {
this.value = value;
}
//... methods that use T.compareTo()
}
Run Code Online (Sandbox Code Playgroud)
我还有一个名为Person的抽象类:
public abstract class Person implements Comparable<Person>
Run Code Online (Sandbox Code Playgroud)
和两个具体的子类,教授和学生:
public class Professor extends Person
public class Student extends Person
Run Code Online (Sandbox Code Playgroud)
现在当我想像这样创建一个MyGenericStorage时,我收到一个错误:
//error: type argument Student is not within bounds of type-variable T
MyGenericStorage<Student> studStore = new MyGenericStorage<Student>(new Student());
//this works:
MyGenericStorage<Person> persStore = new MyGenericStorage<Person>(new Student());
Run Code Online (Sandbox Code Playgroud)
我认为这是因为我对理解泛型存在根本问题.有人可以向我解释这个,还有,如何修复它?
编辑:
我已将MyGenericStorage更改为以下内容:
public class MyGenericStorage<T extends Comparable<? super T>>
Run Code Online (Sandbox Code Playgroud)
现在它似乎工作.有人可以解释原因吗?
我正在为我的编程类做一个家庭作业,涉及实现接口.这里的问题是我真的只是不了解接口或它们用于什么(教授对解释它不是很好).
分配是制作一个"车辆"超类,而不是三个子类,比如"卡车"或"吉普",每个都有自己的几个特征."车辆"类必须实现类似的界面,我认为我已经想到了(我有compareTo()比较车辆门数的方法),另外一个类也必须实现"混合"类(我不知道)这意味着什么).然后,我们必须实现toString(),equals(Object o)和compareTo(Object o)方法.
我想我已经compareTo()失败了,但equals()我不知道.我们要做的最后一件事是编写一个Main进行测试,这涉及制作一个Vehicle对象数组,打印出来,对它们进行排序,然后重新打印它们.它还应该遍历阵列并打印混合动力车的价格溢价,并使用该equals(Object o)方法来比较2辆车.
这是我的"Vehicle"超类的代码
package vehicle;
abstract public class Vehicle implements Comparable {
private String color;
private int numberOfDoors;
// Constructor
/**
* Creates a vehicle with a color and number of doors
* @param aColor The color of the vehicle
* @param aNumberOfDoors The number of doors
*/
public Vehicle(String aColor, int aNumberOfDoors) {
this.color = aColor;
this.numberOfDoors = aNumberOfDoors;
}
// …Run Code Online (Sandbox Code Playgroud) 我需要按字符串的长度对LinkedList的字符串进行排序,但是希望保持相同长度字符串的顺序(不按字典顺序排序).
样本输入:
this
is
just
a
test
Run Code Online (Sandbox Code Playgroud)
样本输出:
a
is
this
just
test
Run Code Online (Sandbox Code Playgroud)
我试图用一个Comparable<LinkedList<String>>和一个compareTo方法做这个,但我没有得到正确的输出(我仍然按字典顺序排序)
public class Q3_sorting implements Comparable<LinkedList<String>> {
Scanner keyboardScanner = null;
LinkedList<String> fileList = new LinkedList<String>();
Run Code Online (Sandbox Code Playgroud)
// [...]这里有一些代码
public int compareTo(LinkedList<String> o) {
// TODO Auto-generated method stub
o = fileList;
for (int i = 0; i < fileList.size() -1; i++) {
if (fileList.get(i).length() == o.get(i+1).length()) {
return 0;
}
if (fileList.get(i).length() > o.get(i+1).length()) {
return -1;
}
if (fileList.get(i).length() < o.get(i+1).length()) { …Run Code Online (Sandbox Code Playgroud) 我熟悉使用Comparable接口的标准比较,虽然今天我想要比较几个不同的变量时遇到一些麻烦.
我基本上想要实现一个compareTo方法,只有在以下if语句为真时才产生结果-1:
if (o.maxX > minX && o.maxY > minY && o.minZ < maxZ)
Run Code Online (Sandbox Code Playgroud)
虽然,我不确定这是否可能使用类似的,或者我只是不像它看起来那么熟悉.因为当我尝试这种方法时
public int compareTo(IsoSprite o) {
if (o.maxX > minX && o.maxY > minY && o.minZ < maxZ){
return -1;
}else if(o.maxX < minX && o.maxY < minY && o.minZ > maxZ){
return 1;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我收到错误"比较方法违反了其总合同!" .我想澄清一点,我不需要帮助理解这个错误意味着什么,因为我已经阅读了几个关于它的问题.虽然,我仍然不能把我的想法放在这个特定的问题上,因为我读过的其他问题的解决方案是微不足道的.
我真的很感激这种比较的一些帮助,它将是一个救生员.任何输入也很受欢迎.
编辑:经过测试后,我得到的东西几乎可以工作(并非在所有情况下),但我无法弄清楚原因:
public int compareTo(IsoSprite o) {
if (o.maxX > minX && o.maxY > minY && o.minZ < maxZ) {
return -1;
} …Run Code Online (Sandbox Code Playgroud) 比较两个产品时遇到问题。我希望比较它们各自的vintage(可选)属性。但是只要此属性为null,就会引发NPE。我以为我可以使用Comparator.nullsLast(..)处理null值...但是似乎我对它的工作方式有误解,或者代码有问题。我需要更改什么才能使这项工作对null友好?
@Override
public int compare(IProduct product1, IProduct product2) throws ProductComparisonException {
Comparator<IShopProduct> comparator =
Comparator.nullsLast(Comparator.comparing(IShopProduct::getVintage));
return comparator.compare((IShopProduct)product1.getProvidedProductData(),
(IShopProduct)product2.getProvidedProductData());
}
Run Code Online (Sandbox Code Playgroud)
提前致谢
我有一个库存类,它创建一个充满对象 Item 的 ArrayList,它也是一个类。我知道我必须调用
Collections.sort(items);才能对 ArrayList 进行排序(顺便说一下,它称为项目)。作业说我必须在 Item 类上使用一个接口,我不知道是否要实现 Comparator 或 Comparable,然后为方法compareTo()或compare()方法编写什么。另外,我Collections.sort(items)在声明 ArrayList 后立即接到电话,这样可以吗?
Comparable<Item>编辑:我的老师刚刚澄清说她希望我们在 Item 类上实现。
在我的一次采访中,我被问到
Comparable 和 Comparator 之间的性能差异是什么?
我回答说不知道。面试官说,
如果 Comparable 由类Employee 实现,当创建 5000 个 Employee 对象并将其添加到 ArrayList 中时,堆内存中将有 5000 个具有compareTo方法的对象。所以除非绝对必要,否则不要使用 Comparable。使用 Comparator,消除了上述内存开销。
他这样说对吗?
comparable ×10
java ×9
comparator ×6
collections ×3
sorting ×3
arraylist ×1
comparison ×1
generics ×1
guava ×1
inheritance ×1
interface ×1
libgdx ×1
linked-list ×1
performance ×1
ruby ×1
superclass ×1