Java 如何对 Collection<T> 进行排序?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2477261/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 08:12:32  来源:igfitidea点击:

How to sort a Collection<T>?

javasortingcollections

提问by Mercer

I have a generic Collectionand am trying to work out how I can sort the items contained within it. I've tried a few things but I can't get any of them working.

我有一个通用的,Collection并且正在尝试弄清楚如何对其中包含的项目进行排序。我已经尝试了一些东西,但我无法让它们中的任何一个工作。

采纳答案by Alexander Pogrebnyak

Collections by themselves do not have a predefined order, therefore you must convert them to a java.util.List. Then you can use one form of java.util.Collections.sort

集合本身没有预定义的顺序,因此您必须将它们转换为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

回答by jagamot

Here is an example. (I am using CompareToBuilderclass from Apache for convenience, although this can be done without using it.)

这是一个例子。(CompareToBuilder为了方便起见,我正在使用Apache 的类,尽管这可以在不使用它的情况下完成。)

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

If you have a specific code that you are working on and are having issues, you can post your pseudo code and we can try to help you out!

如果您有正在处理的特定代码并且遇到问题,您可以发布您的伪代码,我们可以尝试帮助您!

回答by andyczerwonka

You can't if T is all you get. It must be injected by the provider:

如果 T 是你得到的全部,你就不能。它必须由提供者注入:

Collection<T extends Comparable>

or pass in the Comparator

或传入比较器

Collections.sort(...)

回答by Michael Borgwardt

A Collectiondoes not have an ordering, so wanting to sort it does not make sense. You can sort Listinstances and arrays, and the methods to do that are Collections.sort()and Arrays.sort()

ACollection没有排序,因此想要对其​​进行排序是没有意义的。您可以按List实例和数组,而方法做到这一点是Collections.sort()Arrays.sort()

回答by polygenelubricants

You have two basic options provided by java.util.Collections:

您有以下两个基本选项java.util.Collections

Depending on what the Collectionis, you can also look at SortedSetor SortedMap.

根据是什么Collection,您还可以查看SortedSetSortedMap

回答by Fortega

If your collections object is a list, I would use the sort method, as proposed in the other answers.

如果您的集合对象是一个列表,我将使用其他答案中建议的 sort 方法。

However, if it is not a list, and you don't really care about what type of Collection object is returned, I think it is faster to create a TreeSet instead of a List:

但是,如果它不是列表,并且您并不真正关心返回的是什么类型的 Collection 对象,我认为创建 TreeSet 而不是 List 会更快:

TreeSet sortedSet = new TreeSet(myComparator);
sortedSet.addAll(myCollectionToBeSorted);

回答by lomse

Assuming you have a list of object of type Person, using Lambda expression, you can sort the last names of users for instance by doing the following:

假设您有一个 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);
            }
        }
    }

回答by spaniard81

I came across a similar problem. Had to sort a list of 3rd party class (objects).

我遇到了类似的问题。必须对第 3 方类(对象)的列表进行排序。

List<ThirdPartyClass> tpc = getTpcList(...);

ThirdPartyClass does not implement the Java Comparable interface. I found an excellent illustration from mkyongon how to approach this problem. I had to use the Comparator approach to sorting.

ThirdPartyClass 没有实现 Java Comparable 接口。我从mkyong找到了一个关于如何解决这个问题的很好的例子。我不得不使用 Comparator 方法进行排序。

//Sort ThirdPartyClass based on the value of some attribute/function
Collections.sort(tpc, Compare3rdPartyObjects.tpcComp);

where the Comparator is:

比较器是:

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