我读过关于使用比较器排序数组列表的内容,但在所有的例子中,人们都使用了compareTo,根据一些研究,它是字符串的一种方法。
我想根据自定义对象的一个属性(Date对象)对其数组列表进行排序
(getStartDay())。通常我通过item1.getStartDate().before(item2.getStartDate())比较它们,所以我想知道我是否可以写一些像这样的东西:
public class CustomComparator {
public boolean compare(Object object1, Object object2) {
return object1.getStartDate().before(object2.getStartDate());
}
}
public class RandomName {
...
Collections.sort(Database.arrayList, new CustomComparator);
...
}
我发现这些答案大部分(如果不是全部的话)依赖于底层类(Object)来实现类似的接口或具有类似的helper接口。
没有我的解决方案!下面的代码允许您通过知道对象的字符串名称来比较对象的字段。您可以很容易地修改它,不使用名称,但随后需要公开它或构造一个想要进行比较的对象。
Collections.sort(anArrayListOfSomeObjectPerhapsUsersOrSomething, new ReflectiveComparator(). new ListComparator("name"));
public class ReflectiveComparator {
public class FieldComparator implements Comparator<Object> {
private String fieldName;
public FieldComparator(String fieldName){
this.fieldName = fieldName;
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public int compare(Object object1, Object object2) {
try {
Field field = object1.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
Comparable object1FieldValue = (Comparable) field.get(object1);
Comparable object2FieldValue = (Comparable) field.get(object2);
return object1FieldValue.compareTo(object2FieldValue);
}catch (Exception e){}
return 0;
}
}
public class ListComparator implements Comparator<Object> {
private String fieldName;
public ListComparator(String fieldName) {
this.fieldName = fieldName;
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public int compare(Object object1, Object object2) {
try {
Field field = object1.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
Comparable o1FieldValue = (Comparable) field.get(object1);
Comparable o2FieldValue = (Comparable) field.get(object2);
if (o1FieldValue == null){ return -1;}
if (o2FieldValue == null){ return 1;}
return o1FieldValue.compareTo(o2FieldValue);
} catch (NoSuchFieldException e) {
throw new IllegalStateException("Field doesn't exist", e);
} catch (IllegalAccessException e) {
throw new IllegalStateException("Field inaccessible", e);
}
}
}
}
函数和方法参考
的集合。sort方法可以使用传入的比较器对列表进行排序。该比较器可以使用Comparator. comparison方法实现,其中可以传递一个方法引用作为必要的函数。幸运的是,实际代码比这个描述简单得多。
对于Java 8:
Collections.sort(list, comparing(ClassName::getName));
or
Collections.sort(list, comparing(ClassName::getName).reversed());
另一种方法是
Collections.sort(list, comparing(ClassName::getName, Comparator.nullsLast(Comparator.naturalOrder())));
1.8以来的新功能是一个List.sort()方法,而不是使用Collection.sort()
直接调用mylistcontainer。sort()
下面是一个演示List.sort()特性的代码片段:
List<Fruit> fruits = new ArrayList<Fruit>();
fruits.add(new Fruit("Kiwi","green",40));
fruits.add(new Fruit("Banana","yellow",100));
fruits.add(new Fruit("Apple","mixed green,red",120));
fruits.add(new Fruit("Cherry","red",10));
// a) using an existing compareto() method
fruits.sort((Fruit f1,Fruit f2) -> f1.getFruitName().compareTo(f2.getFruitName()));
System.out.println("Using String.compareTo(): " + fruits);
//Using String.compareTo(): [Apple is: mixed green,red, Banana is: yellow, Cherry is: red, Kiwi is: green]
// b) Using a comparable class
fruits.sort((Fruit f1,Fruit f2) -> f1.compareTo(f2));
System.out.println("Using a Comparable Fruit class (sort by color): " + fruits);
// Using a Comparable Fruit class (sort by color): [Kiwi is green, Apple is: mixed green,red, Cherry is: red, Banana is: yellow]
Fruit类是:
public class Fruit implements Comparable<Fruit>
{
private String name;
private String color;
private int quantity;
public Fruit(String name,String color,int quantity)
{ this.name = name; this.color = color; this.quantity = quantity; }
public String getFruitName() { return name; }
public String getColor() { return color; }
public int getQuantity() { return quantity; }
@Override public final int compareTo(Fruit f) // sorting the color
{
return this.color.compareTo(f.color);
}
@Override public String toString()
{
return (name + " is: " + color);
}
} // end of Fruit class