我读过有关使用Comparator对ArrayList进行排序的信息,但在所有示例中,人们都使用了compareTo ,根据一些研究,它是String的一种方法。

我想按自定义对象的属性之一对ArrayList进行排序: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);...
}

#1楼

我发现,大多数(如果不是全部)这些答案都依赖于基础类(对象)来实现可比的或具有辅助可比的接口。

没有我的解决方案! 以下代码可让您通过了解对象的字符串名称来比较对象的字段。 您可以轻松地修改它而不使用名称,但是随后您需要公开它或构造要与之比较的对象之一。

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" })@Overridepublic 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" })@Overridepublic 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);}}}
}

#2楼

为了对ArrayList进行排序,您可以使用以下代码片段:

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

#3楼

此代码段可能有用。 如果要对我的对象进行排序,我想按VolumeName进行排序:

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中使用它。


#4楼

您可以尝试番石榴订购 :

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

#5楼

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

您可以尝试使用LambdaJ解决这些任务。 您可以在这里找到它: http : //code.google.com/p/lambdaj/

这里有一个例子:

排序迭代

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

用lambda排序

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

当然,具有这种美感会影响性能(平均2倍),但是您能找到更具可读性的代码吗?


#6楼

使用Java 8时,可以将方法引用用作比较器:

import static java.util.Comparator.comparing;Collections.sort(list, comparing(MyObject::getStartDate));

#7楼

JAVA 8 Lambda表达式

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)

#8楼

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

这两个接口都允许不同的行为。 Comparable允许您使对象像刚刚描述的String一样工作(实际上,String实现Comparable)。 第二个是Comparator,它允许您执行要求的操作。 您可以这样做:

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

这将导致Collections.sort方法将比较器用于其排序机制。 如果ArrayList中的对象实现可比较,则可以改为执行以下操作:

Collections.sort(myArrayList);

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


#9楼

由于Date实现Comparable ,因此它具有String一样的compareTo方法。

因此,您的自定义Comparator可能如下所示:

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

compare()方法必须返回一个int ,因此无论如何您都不能直接返回一个boolean

您的排序代码几乎就像您写的那样:

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

如果您不需要重用比较器,则编写所有这些内容的一种更短的方法是将其编写为内联匿名类:

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

自从Java-8

现在,您可以通过对Comparator使用lambda表达式 ,以较短的形式编写最后一个示例:

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

所有这些都是等效形式。


#10楼

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

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

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


#11楼

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


#12楼

是的,这是可能的,例如在此答案中,我按类IndexValue的属性v进行了IndexValue

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

如果您在这里注意到,我正在创建一个匿名内部类 (这是用于闭包的Java),并将其直接传递给Arrays类的sort方法

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


#13楼

具有自然排序顺序的类(例如,一个类编号)应实现Comparable接口,而没有自然排序顺序的类(例如,一个类Chair)应提供一个Comparator(或匿名Comparator)类)。

两个例子:

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

#14楼

我更喜欢这个过程:

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实现。

是的,它可能会更快...但是现在您不必为每种类型都创建新的Comparator。 如果您可以节省开发时间并放弃运行时,则可以使用此工具。


#15楼

Java 8 Lambda缩短了排序时间。

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

#16楼

使用此库,您可以在多列上对自定义对象的列表进行排序。 该库使用8.0版功能。 那里也有样品。 这是一个样本

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

#17楼

功能与方法参考

Collections.sort方法可以使用您传递的ComparatorList进行排序。 该Comparator可以使用来实现Comparator.comparing方法,其中可以传递一个方法参考作为必要Function 。 幸运的是,实际代码比此描述要简单得多且短得多。

对于Java 8:

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

要么

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

另一种方法是

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

#18楼

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 。


#19楼

JAVA 8最好的简单方法是英语字母排序

类实施

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

分类

  Collections.sort(Your List);

如果要对包含非英文字符的字母进行排序,可以使用“语言环境...”下面的代码使用“土耳其语字符排序” ...

类实施

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

分类

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

#20楼

您可以使用Java 8进行排序

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

#21楼

您可以在2016年德国斯图加特的Java论坛上观看此演示文稿 。

只有少数几张幻灯片使用德语,其中99%的内容是“基于英语的” Java源代码。 喜欢

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

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

如果您对Java8感兴趣,那么您会发现很多入门知识。


#22楼

自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]

水果类是:

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

#23楼

使用Java 8使用可以使用Comparator.comparing()在一行中定义Comparator

使用以下任何一种方式:

选项1:

listToBeSorted.sort(Comparator.comparing(CustomObject::getStartDate));

选项2:

Collections.sort(listToBeSorted, Comparator.comparing(CustomObject::getStartDate));

#24楼

您的自定义类可以实现“ Comparable”接口,该接口需要执行CompareTo方法。 然后,在CompareTo方法中,可以定义一个对象小于或大于另一个对象的含义。 因此,在您的示例中,它看起来可能像这样:

public class MyCustomClass implements Comparable<MyCustomClass>{

..........

 @Override
public int compareTo(MyCustomClass a) {if(this.getStartDate().before(a.getStartDate())){return -1;}else if(a.getStartDate().before(this.getStartDate())){return 1;}else {return 0;}
}

负数表示是不是被比较的对象小。 正数表示对象大于与对象比较的对象,零则表示对象相等。

然后,您可以使用collections.sort(myList)对列表进行排序,而不必提供比较器。 如果使用诸如TreeSet或TreeMap之类的排序集合数据结构,此方法还具有使事物自动排序的优点。

如果您想了解有关Comparable接口的更多信息,可以查看本文(披露:我是作者;)) https://nullbeans.com/the-java-comparable-interface-automatic-sort-of-collections/


#25楼

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();}// Comparatorpublic static class CompId implements Comparator<Person> {@Overridepublic 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;}@Overridepublic int compare(Person arg0, Person arg1) {return mod*arg0.hireDate.compareTo(arg1.hireDate);}}
}public static void main(String[] args) {// TODO Auto-generated method stubSimpleDateFormat 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 blocke.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());}}}

按属性对自定义对象的ArrayList进行排序相关推荐

  1. java 自定义对象 排序,使用自定义排序顺序对对象的ArrayList进行排序

    问题 我希望为我的地址簿应用程序实现一个排序功能. 我想排序anArrayList contactArray.Contact是一个包含四个字段的类:名称,家庭电话号码,手机号码和地址.我想排序name ...

  2. java 集合自定义元素_java集合 collection-list-ArrayList 将自定义对象作为元素存到ArrayList集合中,并去除重复元素。...

    import java.util.*;/*将自定义对象作为元素存到ArrayList集合中,并去除重复元素. 比如:存人对象.同姓名同年龄,视为同一个人.为重复元素. 思路: 1,对人描述,将数据封装 ...

  3. [置顶] 深入浅出Javascript(三)创建自定义对象以及属性、方法

    怎么样创建一个对象? 利用Object创建自定义对象 JavaScript能够自定义对象来扩展程序的功能,不仅如此,它还能扩展JavaScript提供的内置对象,新增内置对象的属性或方法 例如下面代码 ...

  4. ht-8 对arrayList中的自定义对象排序( Collections.sort(ListT list, Comparator? super T c))...

    1 package com.iotek.set; 2 3 import java.util.ArrayList; 4 import java.util.Collections; 5 import ja ...

  5. 定义一个学生类Student,包含三个属性姓名、年龄、性别, 创建三个学生对象存入ArrayList集合中。 A:使用迭代器遍历集合。 B:求出年龄最大的学生,然后将该对象的姓名变为:小猪佩奇。

    Java基础 定义一个学生类Student,包含三个属性姓名.年龄.性别, 创建三个学生对象存入ArrayList集合中. A:使用迭代器遍历集合. B:求出年龄最大的学生,然后将该对象的姓名变为:小 ...

  6. python定义一个学生类姓名、年龄、性别、成绩、你成绩评价_.定义一个学生类Student,包含三个属性姓名、年龄、性别,创建三个学生对象存入ArrayList集合中。...

    3.定义一个学生类Student,包含三个属性姓名.年龄.性别,创建三个学生对象存入ArrayList集合中. A:遍历集合遍历输出. B:求出年龄最大的学生,让后将该对象的姓名变为:王者荣耀. pa ...

  7. ArrayList存储自定义对象并遍历三种方式(迭代器 普通for 增强for)

    import java.util.ArrayList; import java.util.Iterator;/** ArrayList存储自定义对象并遍历* A:迭代器* B:普通for* C:增强f ...

  8. 判断java中String、自定义对象、集合为空的方法

    一.仅判断是否分配内存 如果仅判断该对象.集合是否已被分配内存(即null还是非null),而不用考虑是否有值,则直接使用 object == null判断即可. 二.如果需进一步判断 要进一步判断该 ...

  9. android sqlite存对象,【Android基础】Android SQLite存储自定义对象

    Android SQLite存储自定义对象 在SQLite数据库中可存储的数据类型有NULL.INTEGER.REAL(浮点型).TEXT.BOOL,一共是五种数据类型.在Android开发中,我们存 ...

最新文章

  1. 独家 | 手把手教你怎样用Python生成漂亮且精辟的图像(附教程代码)
  2. python路径拼接问题
  3. grep从文件末尾开始找_c++ 开始之旅
  4. 算法(第4版)Robert Sedgewick 刷题 第一章(1)
  5. python线性加权模型_局部加权之线性回归(1) - Python实现
  6. 《C++ Primer 5th》笔记(6 / 19):函数
  7. Envoy service mesh、Prometheus和Grafana下的微服务监控(翻译)
  8. android系统如何自适应屏幕大小
  9. iOS 循环引用 委托 (实例说明)
  10. arg,argmin和argmax理解
  11. java 设置颜色_java 中怎样设置窗口的颜色
  12. C语言数组指针和指向数组的指针变量—数组名作函数参数.doc
  13. 服务器虚拟cpu,服务器虚拟化 vcpu与内存配比
  14. 如何使用两台无线路由器进行无线桥接(互联)(转)
  15. java验证用户名和密码_java验证用户名和密码详解
  16. macbook 如何卸载 homebrew
  17. PTE学术英语考试受全球广泛认可,2018中国考量快速增长
  18. arm处理器下的对齐异常1-简介
  19. 英语词根记忆法(8)
  20. 学前教育专业计算机实训室,学前教育模拟实训室

热门文章

  1. List遍历过程中删除数据
  2. Android Jetpack组件之Hilt使用
  3. Android: ListView 和 RecyclerView 对比(一)
  4. 【转自知乎】:localhost、127.0.0.1 和 本机IP 三者的区别?
  5. Volley源码分析
  6. 第三周项目四-穷举法解决组合问题
  7. java 反射详解通俗易懂
  8. JNI的native代码中打印日志到eclipse的logcat中
  9. Android之图片加载框架Picasso源码解析
  10. Android性能优化典范第二季