按属性sorting自定义对象的ArrayList

我读了关于使用比较器对ArrayLists进行sorting,但是在所有的例子中,人们使用了compareTo ,根据一些研究,这是一个Strings的方法。

我想通过其属性之一来sorting自定义对象的ArrayList:Date对象( getStartDay() )。 通常我通过item1.getStartDate().before(item2.getStartDate())比较他们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); ... } 

由于Date实现了Comparable ,所以它有一个像String一样的compareTo方法。

所以你的自定义Comparator可能是这样的:

 public class CustomComparator implements Comparator<MyObject> { @Override public int compare(MyObject o1, MyObject o2) { return o1.getStartDate().compareTo(o2.getStartDate()); } } 

compare()方法必须返回一个int ,所以你不能直接返回一个boolean就像你计划的那样。

你的sorting代码就像你写的:

 Collections.sort(Database.arrayList, new CustomComparator()); 

如果你不需要重复使用你的比较器,那么写一个稍微简短的方法就是把它写成一个内联的匿名类:

 Collections.sort(Database.arrayList, new Comparator<MyObject>() { @Override public int compare(MyObject o1, MyObject o2) { return o1.getStartDate().compareTo(o2.getStartDate()); } }); 

由于java-8

您现在可以使用Comparator器的lambdaexpression式以较短的forms编写最后一个示例:

 Collections.sort(Database.arrayList, (o1, o2) -> o1.getStartDate().compareTo(o2.getStartDate())); 

List有一个sort(Comparator)方法,所以你可以进一步缩短:

 Database.arrayList.sort((o1, o2) -> o1.getStartDate().compareTo(o2.getStartDate())); 

这是一个常见的习惯用法,有一个内置的方法可以用一个Comparable键为一个类生成一个Comparator

 Database.arrayList.sort(Comparator.comparing(MyObject::getStartDate)); 

所有这些都是等同的forms。

具有自然sorting顺序的类(例如类Number)应该实现Comparable接口,而没有自然sorting顺序的类(例如,Chair类)应该提供一个比较器(或一个匿名比较器类)。

两个例子:

 public class Number implements Comparable<Number> { private int value; public Number(int value) { this.value = value; } public int compareTo(Number anotherInstance) { return this.value - anotherInstance.value; } } public class Chair { private int weight; private int height; public Chair(int weight, int height) { this.weight = weight; this.height = height; } /* Omitting getters and setters */ } class ChairWeightComparator implements Comparator<Chair> { public int compare(Chair chair1, Chair chair2) { return chair1.getWeight() - chair2.getWeight(); } } class ChairHeightComparator implements Comparator<Chair> { public int compare(Chair chair1, Chair chair2) { return chair1.getHeight() - chair2.getHeight(); } } 

用法:

 List<Number> numbers = new ArrayList<Number>(); ... Collections.sort(numbers); List<Chair> chairs = new ArrayList<Chair>(); // Sort by weight: Collections.sort(chairs, new ChairWeightComparator()); // Sort by height: Collections.sort(chairs, new ChairHeightComparator()); // You can also create anonymous comparators; // Sort by color: Collections.sort(chairs, new Comparator<Chair>() { public int compare(Chair chair1, Chair chair2) { ... } }); 

为了sorting一个ArrayList你可以使用下面的代码片断:

 Collections.sort(studList, new Comparator<Student>(){ public int compare(Student s1, Student s2) { return s1.getFirstName().compareToIgnoreCase(s2.getFirstName()); } }); 

是的你可以。 比较项目有两个选项,比较接口和比较器接口。

这两个接口都允许不同的行为。 Comparable允许你使对象的行为像刚才描述的Strings(实际上,String implements Comparable)。 第二个比较器允许你做你要做的事情。 你会这样做:

 Collections.sort(myArrayList, new MyComparator()); 

这将导致Collections.sort方法使用您的比较器的sorting机制。 如果ArrayList中的对象实现相似性,则可以改为执行下面的操作:

 Collections.sort(myArrayList); 

Collections类包含了许多这些有用的常用工具。

JAVA 8 lambdaexpression式

 Collections.sort(studList, (Student s1, Student s2) ->{ return s1.getFirstName().compareToIgnoreCase(s2.getFirstName()); }); 

要么

 Comparator<Student> c = (s1, s2) -> s1.firstName.compareTo(s2.firstName); studList.sort(c) 

在Java 8中,您可以使用比较器的方法引用:

 import static java.util.Comparator.comparing; Collections.sort(list, comparing(MyObject::getStartDate)); 
 import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Date; public class test { public static class Person { public String name; public int id; public Date hireDate; public Person(String iname, int iid, Date ihireDate) { name = iname; id = iid; hireDate = ihireDate; } public String toString() { return name + " " + id + " " + hireDate.toString(); } // Comparator public static class CompId implements Comparator<Person> { @Override public int compare(Person arg0, Person arg1) { return arg0.id - arg1.id; } } public static class CompDate implements Comparator<Person> { private int mod = 1; public CompDate(boolean desc) { if (desc) mod =-1; } @Override public int compare(Person arg0, Person arg1) { return mod*arg0.hireDate.compareTo(arg1.hireDate); } } } public static void main(String[] args) { // TODO Auto-generated method stub SimpleDateFormat df = new SimpleDateFormat("mm-dd-yyyy"); ArrayList<Person> people; people = new ArrayList<Person>(); try { people.add(new Person("Joe", 92422, df.parse("12-12-2010"))); people.add(new Person("Joef", 24122, df.parse("1-12-2010"))); people.add(new Person("Joee", 24922, df.parse("12-2-2010"))); } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } Collections.sort(people, new Person.CompId()); System.out.println("BY ID"); for (Person p : people) { System.out.println(p.toString()); } Collections.sort(people, new Person.CompDate(false)); System.out.println("BY Date asc"); for (Person p : people) { System.out.println(p.toString()); } Collections.sort(people, new Person.CompDate(true)); System.out.println("BY Date desc"); for (Person p : people) { System.out.println(p.toString()); } } } 

由于技术每天都会出现,所以答案会随时间而改变。 我看了一下LambdaJ,看起来很有趣。

你可以尝试用LambdaJ来解决这些任务。 你可以在这里find它: http : //code.google.com/p/lambdaj/

这里有一个例子:

sorting迭代

 List<Person> sortedByAgePersons = new ArrayList<Person>(persons); Collections.sort(sortedByAgePersons, new Comparator<Person>() { public int compare(Person p1, Person p2) { return Integer.valueOf(p1.getAge()).compareTo(p2.getAge()); } }); 

用lambdasorting

 List<Person> sortedByAgePersons = sort(persons, on(Person.class).getAge()); 

当然,这样的美performance会对性能产生影响(平均2次),但是你能find更易读的代码吗?

您可以使用Bean比较器对自定义类中的任何属性进行sorting。

Java 8开始,我们不必直接使用Collections.sort()List接口有一个默认的sort()方法:

 List<User> users = Arrays.asList(user1,user2,user3); users.sort( (u1, u2) -> { return u1.getFirstName.compareTo(u2.getFirstName());}); 

请参阅http://visvv.blogspot.in/2016/01/sorting-objects-in-java-8.html

使用JAVA 8最简单的方法是英文字母sorting

课程实施

 public class NewspaperClass implements Comparable<NewspaperClass>{ public String name; @Override public int compareTo(NewspaperClass another) { return name.compareTo(another.name); } } 

分类

  Collections.sort(Your List); 

如果你想sorting包含非英文字母的字母,你可以使用语言环境…下面的代码使用土耳其字符sorting…

课程实施

 public class NewspaperClass implements Comparator<NewspaperClass> { public String name; public Boolean isUserNewspaper=false; private Collator trCollator = Collator.getInstance(new Locale("tr_TR")); @Override public int compare(NewspaperClass lhs, NewspaperClass rhs) { trCollator.setStrength(Collator.PRIMARY); return trCollator.compare(lhs.name,rhs.name); } } 

分类

 Collections.sort(your array list,new NewspaperClass()); 

你可以尝试番石榴订购 :

 Function<Item, Date> getStartDate = new Function<Item, Date>() { public Date apply(Item item) { return item.getStartDate(); } }; List<Item> orderedItems = Ordering.natural().onResultOf(getStartDate). sortedCopy(items); 

是的,这是可能的,例如在这个答案我sorting的属性v的类IndexValue

  // Sorting by property v using a custom comparator. Arrays.sort( array, new Comparator<IndexValue>(){ public int compare( IndexValue a, IndexValue b ){ return av - bv; } }); 

如果你在这里注意到我创build了一个匿名的内部类 (这是闭包的Java),并直接传递给类Arrayssort方法

你的对象也可以实现Comparable (这就是Java中的String和大多数核心库),但是它会自己定义类的“自然sorting顺序”,并且不允许你插入新的类。

这个代码片段可能是有用的。 如果你想在我的情况sorting一个对象,我想通过VolumeNamesorting:

 public List<Volume> getSortedVolumes() throws SystemException { List<Volume> volumes = VolumeLocalServiceUtil.getAllVolumes(); Collections.sort(volumes, new Comparator<Volume>() { public int compare(Volume o1, Volume o2) { Volume p1 = (Volume) o1; Volume p2 = (Volume) o2; return p1.getVolumeName().compareToIgnoreCase( p2.getVolumeName()); } }); return volumes; } 

这工作。 我在我的jsp中使用它。

Java 8 Lambda缩短了sorting。

 Collections.sort(stdList, (o1, o2) -> o1.getName().compareTo(o2.getName())); 

你可以使用java 8进行sorting

 yourList.sort(Comparator.comparing(Classname::getName)); or yourList.stream().forEach(a -> a.getBObjects().sort(Comparator.comparing(Classname::getValue))); 

我发现,如果不是所有这些答案都依赖于底层类(Object)来实现可比较的或者有一个帮助器可比的接口,

不是用我的解决scheme! 下面的代码让你通过知道它们的string名来比较对象的字段。 你可以很容易的修改它,而不是使用这个名字,但是你需要暴露它,或者构build一个你想比较的对象。

 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); } } } } 

有了这个库,您可以在多列上对自定义对象列表进行sorting。 该库使用8.0版function。 样品也可在那里。 这是一个样本

 SortKeys sortKeys = new SortKeys(); sortKeys.addField("firstName") .addField("age", true); // This (true) will sort the age descending // Other ways to specify a property to the sorter are // .addField("lastName", String.class); // .addField("dob", Date.class, true); // Instantiate a ListSorter ListSorter listSorter = new ListSorter(); // Pass the data to sort (listToSort) and the "by keys" to sort (sortKeys) List sortedList = (List<Person>) listSorter.sortList(listToSort, sortKeys); 

2016年,您可以在德国斯图加特Java论坛看看这个演讲 。

只有less数幻灯片使用德语,99%的内容是“基于英语”的Java源代码; 喜欢

 someCollection.sort( OurCustomComparator .comparing(Person::getName) .thenComparing(Person::getId) ); 

OurCustomComparator使用默认的方法(和其他有趣的想法)。 如图所示,导致非常简洁的代码挑选一些getter方法进行sorting; 和超级简单的链接(或反转)的sorting标准。

如果你在java8中,你会发现很多的材料让你开始。

对于Java 8:

 Collections.sort(list, comparing(ClassName::getName)); 

要么

 Collections.sort(list, comparing(ClassName::getName).reversed()); 

它似乎与stringdatetypes也像“2015-12-14T21:55:51Z”

另一种方法是

 Collections.sort(list, comparing(ClassName::getName, Comparator.nullsLast(Comparator.naturalOrder()))); 

您的customComparator类必须实现java.util.Comparator才能使用。 它也必须覆盖compare()和equals()

compare()必须回答以下问题:对象1是否小于,等于或大于对象2?

完整文档: http : //java.sun.com/j2se/1.5.0/docs/api/java/util/Comparator.html

我更喜欢这个过程:

 public class SortUtil { public static <T> List<T> sort(List<T> list, String sortByProperty) { Collections.sort(list, new BeanComparator(sortByProperty)); return list; } } List<T> sortedList = SortUtil<T>.sort(unsortedList, "startDate"); 

如果你的对象列表有一个名为startDate的属性,你可以调用一遍又一遍。 你甚至可以链接他们startDate.time

这要求你的对象是Comparable ,这意味着你需要一个compareToequalshashCode实现。

是的,这可能会更快…但是现在你不必为每种types都做一个新的比较器。 如果你可以节省开发时间并放弃运行时间,你可以使用这个。

自1.8以来新增了一个List.sort()方法,而不是使用Collection.sort(),因此您可以直接调用mylistcontainer.sort()

这是一个演示List.sort()function的代码片段:

 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] 

水果类是:

 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); } 

} //结束Fruit类