【发布时间】:2010-03-19 12:38:28
【问题描述】:
我有一个通用的Collection,我正在尝试弄清楚如何对其中包含的项目进行排序。我尝试了一些方法,但其中任何一个都无法正常工作。
【问题讨论】:
标签: java sorting collections
我有一个通用的Collection,我正在尝试弄清楚如何对其中包含的项目进行排序。我尝试了一些方法,但其中任何一个都无法正常工作。
【问题讨论】:
标签: java sorting collections
集合本身没有预定义的顺序,因此您必须将它们转换为
java.util.List。然后你可以使用java.util.Collections.sort的一种形式
Collection< T > collection = ...;
List< T > list = new ArrayList< T >( collection );
Collections.sort( list );
// or
Collections.sort( list, new Comparator< T >( ){...} );
// list now is sorted
【讨论】:
Ordering.sortedCopy 使用的方法。
Download 类并尝试了Collection<Download> colls = new Collection<Download>(); 并得到一个实例化错误。
Collection,它是一个抽象类。但是,您可以将任何扩展集合的内容分配给 Collection 类型的局部变量。
如果只有 T,你就不能。它必须由提供者注入:
Collection<T extends Comparable>
或传入比较器
Collections.sort(...)
【讨论】:
Collection 没有排序,因此想要对其进行排序是没有意义的。您可以对List 实例和数组进行排序,这样做的方法是Collections.sort() 和Arrays.sort()
【讨论】:
java.util.Collections 提供了两个基本选项:
<T extends Comparable<? super T>> void sort(List<T> list)
T implements Comparable 使用它并且您对自然排序没问题<T> void sort(List<T> list, Comparator<? super T> c)
Comparator,请使用此选项。根据Collection 是什么,您还可以查看SortedSet 或SortedMap。
【讨论】:
假设您有一个 Person 类型的对象列表,使用 Lambda 表达式,您可以通过执行以下操作对用户的姓氏进行排序:
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
class Person {
private String firstName;
private String lastName;
public Person(String firstName, String lastName){
this.firstName = firstName;
this.lastName = lastName;
}
public String getLastName(){
return this.lastName;
}
public String getFirstName(){
return this.firstName;
}
@Override
public String toString(){
return "Person: "+ this.getFirstName() + " " + this.getLastName();
}
}
class TestSort {
public static void main(String[] args){
List<Person> people = Arrays.asList(
new Person("John", "Max"),
new Person("Coolio", "Doe"),
new Person("Judith", "Dan")
);
//Making use of lambda expression to sort the collection
people.sort((p1, p2)->p1.getLastName().compareTo(p2.getLastName()));
//Print sorted
printPeople(people);
}
public static void printPeople(List<Person> people){
for(Person p : people){
System.out.println(p);
}
}
}
【讨论】:
如果您的集合对象是一个列表,我会使用其他答案中建议的排序方法。
但是,如果它不是一个列表,并且你并不真正关心返回的是什么类型的 Collection 对象,我认为创建 TreeSet 而不是 List 更快:
TreeSet sortedSet = new TreeSet(myComparator);
sortedSet.addAll(myCollectionToBeSorted);
【讨论】:
这是一个例子。 (为方便起见,我使用 Apache 的 CompareToBuilder 类,虽然这可以不使用它来完成。)
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import org.apache.commons.lang.builder.CompareToBuilder;
public class Tester {
boolean ascending = true;
public static void main(String args[]) {
Tester tester = new Tester();
tester.printValues();
}
public void printValues() {
List<HashMap<String, Object>> list =
new ArrayList<HashMap<String, Object>>();
HashMap<String, Object> map =
new HashMap<String, Object>();
map.put( "actionId", new Integer(1234) );
map.put( "eventId", new Integer(21) );
map.put( "fromDate", getDate(1) );
map.put( "toDate", getDate(7) );
list.add(map);
map = new HashMap<String, Object>();
map.put( "actionId", new Integer(456) );
map.put( "eventId", new Integer(11) );
map.put( "fromDate", getDate(1) );
map.put( "toDate", getDate(1) );
list.add(map);
map = new HashMap<String, Object>();
map.put( "actionId", new Integer(1234) );
map.put( "eventId", new Integer(20) );
map.put( "fromDate", getDate(4) );
map.put( "toDate", getDate(16) );
list.add(map);
map = new HashMap<String, Object>();
map.put( "actionId", new Integer(1234) );
map.put( "eventId", new Integer(22) );
map.put( "fromDate", getDate(8) );
map.put( "toDate", getDate(11) );
list.add(map);
map = new HashMap<String, Object>();
map.put( "actionId", new Integer(1234) );
map.put( "eventId", new Integer(11) );
map.put( "fromDate", getDate(1) );
map.put( "toDate", getDate(10) );
list.add(map);
map = new HashMap<String, Object>();
map.put( "actionId", new Integer(1234) );
map.put( "eventId", new Integer(11) );
map.put( "fromDate", getDate(4) );
map.put( "toDate", getDate(15) );
list.add(map);
map = new HashMap<String, Object>();
map.put( "actionId", new Integer(567) );
map.put( "eventId", new Integer(12) );
map.put( "fromDate", getDate(-1) );
map.put( "toDate", getDate(1) );
list.add(map);
System.out.println("\n Before Sorting \n ");
for( int j = 0; j < list.size(); j++ )
System.out.println(list.get(j));
Collections.sort( list, new HashMapComparator2() );
System.out.println("\n After Sorting \n ");
for( int j = 0; j < list.size(); j++ )
System.out.println(list.get(j));
}
public static Date getDate(int days) {
Calendar cal = Calendar.getInstance();
cal.setTime(new Date());
cal.add(Calendar.DATE, days);
return cal.getTime();
}
public class HashMapComparator2 implements Comparator {
public int compare(Object object1, Object object2) {
if( ascending ) {
return new CompareToBuilder()
.append(
((HashMap)object1).get("actionId"),
((HashMap)object2).get("actionId")
)
.append(
((HashMap)object2).get("eventId"),
((HashMap)object1).get("eventId")
)
.toComparison();
} else {
return new CompareToBuilder()
.append(
((HashMap)object2).get("actionId"),
((HashMap)object1).get("actionId")
)
.append(
((HashMap)object2).get("eventId"),
((HashMap)object1).get("eventId")
)
.toComparison();
}
}
}
}
如果您正在处理特定代码并且遇到问题,您可以发布您的伪代码,我们可以尝试帮助您!
【讨论】:
我遇到了类似的问题。必须对 3rd 方类(对象)列表进行排序。
List<ThirdPartyClass> tpc = getTpcList(...);
ThirdPartyClass 没有实现 Java Comparable 接口。我从mkyong 找到了一个关于如何解决这个问题的优秀插图。我不得不使用 Comparator 方法进行排序。
//Sort ThirdPartyClass based on the value of some attribute/function
Collections.sort(tpc, Compare3rdPartyObjects.tpcComp);
比较器在哪里:
public abstract class Compare3rdPartyObjects {
public static Comparator<ThirdPartyClass> tpcComp = new Comparator<ThirdPartyClass>() {
public int compare(ThirdPartyClass tpc1, ThirdPartyClass tpc2) {
Integer tpc1Offset = compareUsing(tpc1);
Integer tpc2Offset = compareUsing(tpc2);
//ascending order
return tpc1Offset.compareTo(tpc2Offset);
}
};
//Fetch the attribute value that you would like to use to compare the ThirdPartyClass instances
public static Integer compareUsing(ThirdPartyClass tpc) {
Integer value = tpc.getValueUsingSomeFunction();
return value;
}
}
【讨论】: