Android-java-如何按对象内的某个值对对象列表进行排序

133

我正在尝试通过对象中的特定值对一个ArrayList进行排序。如何最好地实现这样的功能?我应该使用Collections.sort()和某种比较器吗?

我正在尝试按照它们在某个变量中保存的float值对对象列表进行排序。

编辑: 这是我到目前为止的代码:

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

错误显示为:无法在基本类型double上调用compareTo(double)。

这是因为比较器不能返回除某种类型之外的任何内容吗?


2
“我应该使用带有某种比较器的Collections.sort()吗?” “是的,听起来是个好主意。” - Kennet
我不知道这是否重要,但列表中的对象数量可能高达80个。这就是为什么我对使用比较器感到困惑,因为它一次只比较两个值。 - James andresakis
这就是排序的工作方式。首先将一个项目添加到列表中。当添加下一个项目时,应该将其放在当前列表中的哪个位置之前或之后。当添加第三个项目时,与列表中的第一个项目进行比较,如果在其之后,则与下一个项目进行比较。以此类推。 - Kennet
15个回答

428

按照以下代码,可以对任何 ArrayList 进行排序

Collections.sort(myList, new Comparator<EmployeeClass>(){
    public int compare(EmployeeClass obj1, EmployeeClass obj2) {
        // ## Ascending order
        return obj1.firstName.compareToIgnoreCase(obj2.firstName); // To compare string values
        // return Integer.valueOf(obj1.empId).compareTo(Integer.valueOf(obj2.empId)); // To compare integer values

        // ## Descending order
        // return obj2.firstName.compareToIgnoreCase(obj1.firstName); // To compare string values
        // return Integer.valueOf(obj2.empId).compareTo(Integer.valueOf(obj1.empId)); // To compare integer values
        }
    });

23
这应该是最佳答案! - John Smith
3
简单而优秀的回答,太棒了,兄弟! - Sadashiv
1
这看起来非常简洁。谢谢。并且提供的提示也是一个加分项。 - Anurag
4
可以用 "return Integer.compare(obj1.empId, obj2.empId);" 替换 "int compare",以比较两个对象的 empId 值。 - Ali Zarei
1
Stackoverflow 应该在这些精彩的答案旁边添加一个“捐赠”按钮 :) - toto_tata
显示剩余7条评论

104
你应该使用Comparable而不是Comparator,如果你想要一个默认的排序。
看这里,这可能会有所帮助- 何时使用Comparable和/或Comparator? 试一下 -
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class TestSort {

    public static void main(String args[]){

        ToSort toSort1 = new ToSort(new Float(3), "3");
        ToSort toSort2 = new ToSort(new Float(6), "6");
        ToSort toSort3 = new ToSort(new Float(9), "9");
        ToSort toSort4 = new ToSort(new Float(1), "1");
        ToSort toSort5 = new ToSort(new Float(5), "5");
        ToSort toSort6 = new ToSort(new Float(0), "0");
        ToSort toSort7 = new ToSort(new Float(3), "3");
        ToSort toSort8 = new ToSort(new Float(-3), "-3");

        List<ToSort> sortList = new ArrayList<ToSort>();
        sortList.add(toSort1);
        sortList.add(toSort2);
        sortList.add(toSort3);
        sortList.add(toSort4);
        sortList.add(toSort5);
        sortList.add(toSort6);
        sortList.add(toSort7);
        sortList.add(toSort8);

        Collections.sort(sortList);

        for(ToSort toSort : sortList){
            System.out.println(toSort.toString());
        }
    }

}

public class ToSort implements Comparable<ToSort> {

    private Float val;
    private String id;

    public ToSort(Float val, String id){
        this.val = val;
        this.id = id;
    }

    @Override
    public int compareTo(ToSort f) {

        if (val.floatValue() > f.val.floatValue()) {
            return 1;
        }
        else if (val.floatValue() <  f.val.floatValue()) {
            return -1;
        }
        else {
            return 0;
        }

    }

    @Override
    public String toString(){
        return this.id;
    }
}

1
嘿,谢谢你提供链接 :) 我经常在不同的编程语言之间切换,所以总是会错过一些东西 :p 你知道怎么回事......什么都会一点,但没有精通任何一门语言 lol - James andresakis

46

我认为这会更好地帮助你

Person p = new Person("Bruce", "Willis");
Person p1  = new Person("Tom", "Hanks");
Person p2 = new Person("Nicolas", "Cage");
Person p3 = new Person("John", "Travolta");

ArrayList<Person> list = new ArrayList<Person>();
list.add(p);
list.add(p1);
list.add(p2);
list.add(p3);

Collections.sort(list, new Comparator() {
    @Override
    public int compare(Object o1, Object o2) {
        Person p1 = (Person) o1;
        Person p2 = (Person) o2;
        return p1.getFirstName().compareToIgnoreCase(p2.getFirstName());
    }
});

33

现在无需使用new 操作符创建OBJECT,而是使用valueOf与Collections.Sort中的compareTo来进行排序,从而避免使用拳击(即不需要打包)。

1)按升序排列

Collections.sort(temp, new Comparator<XYZBean>() 
{
     @Override
     public int compare(XYZBean lhs, XYZBean rhs) {

       return Integer.valueOf(lhs.getDistance()).compareTo(rhs.getDistance());
      }
 });

1)按降序排列

Collections.sort(temp, new Comparator<XYZBean>() 
{
     @Override
     public int compare(XYZBean lhs, XYZBean rhs) {

       return Integer.valueOf(rhs.getDistance()).compareTo(lhs.getDistance());
      }
 });

上面有人推荐了你的答案,用于比较整数值。但是即使我也会尝试你的方法,我还是想知道:为什么你将第一个值转换为整数,而不是第二个值?这样做是否仍然有效? compareTo 已经在“引擎盖下”转换了参数,还是这只是一个错误? - SebasSBM
尝试了一下后,我想我知道原因了:也许比较器的输入只是“int”,它本身没有“compareTo”方法...所以,如果我没有忽略任何东西,那就是因为这个原因,对吧?所以,在应用您的代码之后,Android Studio建议我将其替换为Integer.compare(rhs.getDistance(), lhs.getDistance())...这样看起来更简洁了,不是吗?不过我还需要测试一下... - SebasSBM
但是,这个答案已经8年了...也许我的建议在那些日子的最新API级别中不是一个选项... - SebasSBM

6

对于Kotlin来说非常简单!

listToBeSorted.sortBy { it.distance }


2
你可以使用这个方法来比较两个字符串。
Collections.sort(contactsList, new Comparator<ContactsData>() {

                    @Override
                    public int compare(ContactsData lhs, ContactsData rhs) {

                        char l = Character.toUpperCase(lhs.name.charAt(0));

                        if (l < 'A' || l > 'Z')

                            l += 'Z';

                        char r = Character.toUpperCase(rhs.name.charAt(0));

                        if (r < 'A' || r > 'Z')

                            r += 'Z';

                        String s1 = l + lhs.name.substring(1);

                        String s2 = r + rhs.name.substring(1);

                        return s1.compareTo(s2);

                    }

                });

现在创建一个ContactData类。
public class ContactsData {

public String name;
public String id;
public String email;
public String avatar; 
public String connection_type;
public String thumb;
public String small;
public String first_name;
public String last_name;
public String no_of_user;
public int grpIndex;

public ContactsData(String name, String id, String email, String avatar, String connection_type)
{
    this.name = name;
    this.id = id;
    this.email = email;
    this.avatar = avatar;
    this.connection_type = connection_type;

}
}

这里的contactsList是:

public static ArrayList<ContactsData> contactsList = new ArrayList<ContactsData>();

将以数字开头的名称(例如1gbfilename)放在底部。如何将它们放在顶部? - User

2

Person Model Class

 class Person {
        int id;
        String name;
        String fatherName;

        public Person(int id, String name, String fatherName) {
            this.id = id;
            this.name = name;
            this.fatherName = fatherName;
        }
        
    }

排序

class SORT_BY_ID implements Comparator<Person> {
        public int compare(Person a, Person b)
        {
            return a.id - b.id;
        }
    }

使用方法

 ArrayList<Person> personArrayList = new ArrayList<Person>();
            personArrayList.add(new Person(111, "bb", "oakla"));
            personArrayList.add(new Person(131, "aa", "fast"));
            personArrayList.add(new Person(121, "cccc", "paokla"));

            System.out.println("Before Sorted Array list of PErson");
            for (int i=0; i<personArrayList.size(); i++)
                System.out.println(personArrayList.get(i));

            Collections.sort(personArrayList, new SORT_BY_ID());

            System.out.println("After Sorted ");
            for (int i=0; i<personArrayList.size(); i++)
                System.out.println(personArrayList.get(i));

相同的答案已经给出。您还可以看到不同的方法。 - Snigdhajyoti

2
对于Kotlin,您可以使用此函数。
fun sortList(list: List<YourCustomPOJOClass?>) {

    //descending
    Collections.sort(
        list
    ) { o1, o2 -> Integer.valueOf(o1!!.intValueXYZ!!).compareTo(o2!!.intValueXYZ!!) }

//    //ascending
//    Collections.sort(
//        list
//    ) { o1, o2 -> Integer.valueOf(o2!!.intValueXYZ!!).compareTo(o1!!.intValueXYZ!!) }
}

只需要在您的活动片段中调用它即可。

sortList(list)

1
模型类:
public class ToDoModel implements Comparable<ToDoModel> {
    private String id;
    private Date taskDate;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public Date getTaskDate() {
        return taskDate;
    }

    public void setTaskDate(Date taskDate) {
        this.taskDate = taskDate;
    }

    @Override
    public int compareTo(ToDoModel another) {
        return getTaskDate().compareTo(another.getTaskDate());  
    }
}

现在将数据设置在ArrayList中。
for (int i = 0; i < your_array_length; i++) {
    ToDoModel tm = new ToDoModel();
    tm.setId(your_id);
    tm.setTaskDate(your_date);
    mArrayList.add(tm);
}

现在对 ArrayList 进行排序。
Collections.sort(toDoList);

总结:它将按日期对您的数据进行排序。

1
public class DateComparator implements Comparator<Marker> {
    @Override
    public int compare(Mark lhs, Mark rhs) {
        Double distance = Double.valueOf(lhs.getDistance());
        Double distance1 = Double.valueOf(rhs.getDistance());
        if (distance.compareTo(distance1) < 0) {
            return -1;
        } else if (distance.compareTo(distance1) > 0) {
            return 1;
        } else {
            return 0;
        }
    }
}

ArrayList(Marker) arraylist;

如何使用:

Collections.sort(arraylist, new DateComparator());

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接