我读过关于使用比较器对ArrayLists进行排序的文章,但是在所有的例子中,人们都使用了compareTo
,根据一些研究,这是一种针对字符串的方法。
我想通过自定义对象的一个属性对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);
...
}
由于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
。
你的排序代码会和你写的差不多。
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());
}
});
现在你可以用一个lambda expression为`Comparator'写一个更短的例子。
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));
所有这些都是等价的形式。
有自然排序顺序的类(以Number类为例)应该实现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();
}
}
使用方法:{{6917540}}}。
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) {
...
}
});
是的,你可以。 比较项目有两种选择,Comparable
这两个接口都允许有不同的行为。 比较器允许你使对象的行为像你刚才描述的字符串一样(事实上,字符串实现了比较器)。 第二个,比较器,允许你做你要求做的事情。 你可以这样做。
Collections.sort(myArrayList, new MyComparator());
这将导致Collections.sort方法使用你的比较器作为它的排序机制。 如果ArrayList中的对象实现了可比性,你可以这样做。
Collections.sort(myArrayList);
Collections类包含了许多这样有用的、常见的工具。
因为技术每天都在出现,所以答案会随着时间的推移而改变。 我看了一下LambdaJ,似乎很有意思。
你可以尝试用LambdaJ来解决这些任务。 你可以在这里找到它。 [http://code.google.com/p/lambdaj/][1]
这里有一个例子。
Sort Iterative
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倍),但你能找到更易读的代码吗?
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());
}
}
}
JAVA 8的最佳简易方法是英文字母排序
类实施
public class NewspaperClass implements Comparable<NewspaperClass>{
public String name;
@Override
public int compareTo(NewspaperClass another) {
return name.compareTo(another.name);
}
}
排序
Collections.sort(Your List);
如果您想对包含非英文字符的字母进行排序,您可以使用Locale...。 下面的代码使用土耳其字符排序...
类实现
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());
方法参考
[Collections.sort
][1]方法可以使用你传递的[Comparator
][3]对一个[List
][2]进行排序。
那个Comparator
可以用[Comparator.compararing
][4]方法来实现,你可以传递一个[方法引用][5]作为必要的[Function
][6]。
幸运的是,实际的代码比这个描述要简单得多,也短得多。
对于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())));
[1]: https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Collections.html#sort(java.util.List,java.util.Comparator) [2]: https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/List.html [3]: https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Comparator.html [4]: https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Comparator.html#comparing(java.util.function.Function) [5]: https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html [6]: https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/function/Function.html
从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 Lambda缩短了排序。
Collections.sort(stdList, (o1, o2) -> o1.getName().compareTo(o2.getName()));
你可以试试番石榴[订购][1]。
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);
[1]: http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Ordering.html
是的,这是有可能的,例如在本回答中,我通过类IndexValue
的属性v
进行排序。
// 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中大多数核心库所做的),但那会定义类本身的"自然排序顺序"。
的类,而且不会让你插入新的。
1:
我发现大部分的答案都是依靠底层类(Object)来实现可比性或者有一个辅助的可比接口。
而我的解决方案则不然 下面的代码让你通过知道对象的字符串名称来比较对象'的字段。 你可以很容易地修改它,不使用这个名字,但是你需要暴露它或者构造一个你想要比较的对象。
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);
}
}
}
}
这段代码可能很有用。 如果你想对一个对象进行排序 在我的例子中,我想按卷名排序。
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中使用它。
从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
你可以看看2016年在德国斯图加特Java论坛上举行的这个【演讲】1。
只有少数幻灯片使用德语,99%的内容都是"基于英语的"。 的Java源码。 像
someCollection.sort(
OurCustomComparator
.comparing(Person::getName)
.thenComparing(Person::getId)
);
其中OurCustomComparator
使用的是默认方法(还有其他有趣的想法)。
如图所示,导致非常简洁的代码来选择一些getter方法进行排序。
以及超级简单的排序标准的链式(或反转)。
如果你喜欢java8,你会发现那里有很多材料可以让你入门。
1: