Sắp xếp ArrayList của các Đối tượng tùy chỉnh theo thuộc tính


1145

Tôi đã đọc về cách sắp xếp ArrayLists bằng Bộ so sánh nhưng trong tất cả các ví dụ mà mọi người đã sử dụng compareTomà theo một số nghiên cứu là một phương pháp cho Chuỗi.

Tôi muốn sắp xếp một ArrayList của các đối tượng tùy chỉnh theo một trong các thuộc tính của chúng: một đối tượng Date ( getStartDay()). Thông thường tôi so sánh chúng bằng cách item1.getStartDate().before(item2.getStartDate())đó vì vậy tôi đã tự hỏi liệu tôi có thể viết một cái gì đó như:

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


2
Trả lời bởi @Yishai trong bài đăng này cho thấy việc sử dụng enum tao nhã để sắp xếp tùy chỉnh và sắp xếp theo nhóm (nhiều đối số) sử dụng chuỗi so sánh.
súng

Câu trả lời:


1538

Kể từ khi Datethực hiện Comparable, nó có một compareTophương pháp giống như Stringlàm.

Vì vậy, tùy chỉnh của bạn Comparatorcó thể trông như thế này:

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

Các compare()phương pháp phải trả lại int, vì vậy bạn có thể không trực tiếp trả về một booleangiống như bạn đang lên kế hoạch để anyway.

Mã sắp xếp của bạn sẽ giống như bạn đã viết:

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

Một cách ngắn hơn một chút để viết tất cả những điều này, nếu bạn không cần sử dụng lại bộ so sánh của mình, là viết nó dưới dạng một lớp ẩn danh nội tuyến:

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

Từ

Bây giờ bạn có thể viết ví dụ cuối cùng ở dạng ngắn hơn bằng cách sử dụng biểu thức lambda cho Comparator:

Collections.sort(Database.arrayList, 
                        (o1, o2) -> o1.getStartDate().compareTo(o2.getStartDate()));

Listcó một sort(Comparator)phương pháp, vì vậy bạn có thể rút ngắn điều này hơn nữa:

Database.arrayList.sort((o1, o2) -> o1.getStartDate().compareTo(o2.getStartDate()));

Đây là một thành ngữ phổ biến đến mức có một phương thức tích hợp sẵn để tạo Comparatormột lớp cho một Comparablekhóa:

Database.arrayList.sort(Comparator.comparing(MyObject::getStartDate));

Tất cả đều là những hình thức tương đương.


33
+1 để đề cập rằng nó sẽ trở lại intvà bạn nên sử dụng nó Date#compareTo()cho việc này. Tại sao điều này không được nêu lên trên câu trả lời khác là ngoài tôi. Liên kết này cũng có thể hữu ích: Hướng dẫn đặt hàng đối tượng tại Sun.com .
BalusC

5
Tôi nghĩ rằng câu trả lời tốt nhất cũng nên bao gồm cách thức phù hợp để thực hiện nó trong Java 8. Collections.sort (list, so sánh.compared (MyObject :: getStartDate)); mà đọc tốt hơn và ít bị lỗi hơn. Rất dễ dàng để viết return o1.getStartDate (). So sánhTo (o1.getStartDate ());
Kuba

2
Lớp so sánh nên tĩnh :)
Jarmez De La Rocha

4
@Kuba tốt hơn chưa, dùng đi List.sort().
shmosel

3
Giải pháp này không hoạt động trên API Android <24. Các bạn có biết một giải pháp cho việc này?
Jim Clermonts

194

Các lớp có thứ tự sắp xếp tự nhiên (ví dụ Số lớp) sẽ triển khai giao diện So sánh, trong khi các lớp không có thứ tự sắp xếp tự nhiên (ví dụ Chủ tịch lớp) phải được cung cấp Trình so sánh (hoặc Trình so sánh ẩn danh) lớp học).

Hai ví dụ:

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

Sử dụng:

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

Tôi đã thử điều đó - nhưng khi tôi muốn truy cập vào lớp so sánh Chủ tịch WeightComparator bên ngoài trong bất kỳ lớp nào khác, tôi không có quyền truy cập vào lớp này (tất nhiên không phải vì nó không công khai). Tôi có cần tạo một lớp Chủ tịch công cộng mới trong một tệp riêng không? - Tôi thực sự là người đầu tiên thử điều này sau 3 năm hay tôi đã bỏ lỡ sth?
dùng387184

@ user387184 - chỉ cần đặt nó ở chế độ công khai và đặt nó vào tệp riêng của nó (tốt nhất là gói riêng của nó) và bạn sẽ có thể sử dụng nó ở mọi nơi trong dự án của bạn. Không cần phải tạo một lớp bổ sung!
Bjorn

bạn có nghĩa là tạo một tệp mới - không phải là một lớp và nhập mã: "class Chủ tịch WeightComparator thực hiện Trình so sánh <Ghế> {...."?
dùng387184

@ user387184, chính xác - nhưng với từ khóa publicở phía trước class.
Bjorn

157

Để sắp xếp một ArrayListbạn có thể sử dụng đoạn mã sau:

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

1
Bất kỳ ai sử dụng lambda stackoverflow.com/questions/2784514/...
Sorter

Điều đó sắp xếp nhưng mang lại giá trị gấp đôi cho mỗi yếu tố
Sam

44

Vâng, bạn có thể. Có hai tùy chọn để so sánh các mục, giao diện So sánh và giao diện So sánh .

Cả hai giao diện này cho phép hành vi khác nhau. Có thể so sánh cho phép bạn làm cho đối tượng hoạt động giống như bạn vừa mô tả Chuỗi (trên thực tế, Chuỗi thực hiện So sánh). Thứ hai, so sánh, cho phép bạn làm những gì bạn đang yêu cầu làm. Bạn sẽ làm nó như thế này:

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

Điều đó sẽ khiến phương thức Collections.sort sử dụng bộ so sánh của bạn cho cơ chế sắp xếp của nó. Nếu các đối tượng trong ArrayList triển khai có thể so sánh, thay vào đó bạn có thể làm một cái gì đó như thế này:

Collections.sort(myArrayList);

Lớp Bộ sưu tập chứa một số các công cụ phổ biến, hữu ích này.


42

Biểu thức lambda JAVA 8

Collections.sort(studList, (Student s1, Student s2) ->{
        return s1.getFirstName().compareToIgnoreCase(s2.getFirstName());
});

HOẶC LÀ

Comparator<Student> c = (s1, s2) -> s1.firstName.compareTo(s2.firstName);
studList.sort(c)

3
HoặcCollections.sort(studList, Comparator.comparing(Student::getFirstName));
Holger

5
.. hoặcstudList.sort(Comparator.comparing(Student::getFirstName));
Alexis C.

Thứ tự sắp xếp sẽ luôn tăng dần trong trường hợp của bạn. Tôi cũng quan tâm đến thứ tự sắp xếp trong ví dụ của tôi. Cảm ơn quý ông.
Sắp xếp

33

Với Java 8, bạn có thể sử dụng tham chiếu phương thức cho trình so sánh của mình:

import static java.util.Comparator.comparing;

Collections.sort(list, comparing(MyObject::getStartDate));

@ user387184 thật không may, Android không hỗ trợ Java 8, mặc dù có thể có một cách giải quyết (tôi chưa thử nghiệm nó).
assylias

14

Vì công nghệ xuất hiện hàng ngày, câu trả lời sẽ thay đổi theo thời gian. Tôi đã xem LambdaJ và có vẻ rất thú vị.

Bạn có thể thử giải quyết các nhiệm vụ này với LambdaJ . Bạn có thể tìm thấy nó ở đây: http://code.google.com.vn/p/lambdaj/

Ở đây bạn có một ví dụ:

Sắp xếp lặp đi lặp lại

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

Sắp xếp với lambda

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

Tất nhiên, có loại tác động làm đẹp này trong hiệu suất (trung bình 2 lần), nhưng bạn có thể tìm thấy một mã dễ đọc hơn không?


Điều đó sắp xếp nhưng mang lại giá trị gấp đôi cho mỗi yếu tố làm thế nào để tránh nó
Sam

@Sam, nó không nên ... nó hoạt động như mong đợi. Trừ khi bạn đang sử dụng một phiên bản mới có lỗi, tôi khuyên bạn nên đăng nó trong diễn đàn. Dù sao, câu trả lời này đã được đăng trước java 8, nếu bạn sử dụng nó, thì nó sẽ tốt hơn nhiều so với sử dụng lambdaj
Federico Piazza

Tôi đã phải loại bỏ ngay cả các mục trong một vòng lặp foreach khôn ngoan khác, nó mang lại cho tôi gấp đôi mỗi nội dung.
Sam

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

}

}

7
Chào mừng đến với stackoverflow. Câu hỏi này đã được trả lời một thời gian trước. Trước khi phục hồi các chủ đề cũ, hãy chắc chắn rằng phản hồi của bạn thêm một cái gì đó quan trọng vào chủ đề.
Leigh

1
Vui lòng thêm lời giải thích cho câu trả lời của bạn.
Arashsoft

Chỉ cần biên dịch và chạy. Mã là nhận xét và giải thích.
CharlesW

9

Cách dễ dàng nhất với JAVA 8 là dành cho bảng chữ cái tiếng Anh

Thực hiện lớp

public class NewspaperClass implements Comparable<NewspaperClass>{
   public String name;

   @Override
   public int compareTo(NewspaperClass another) {
      return name.compareTo(another.name);
   }
}

Sắp xếp

  Collections.sort(Your List);

Nếu bạn muốn sắp xếp cho bảng chữ cái có chứa các ký tự không phải tiếng Anh, bạn có thể sử dụng Ngôn ngữ ... Dưới đây mã sử dụng sắp xếp ký tự Thổ Nhĩ Kỳ ...

Thực hiện lớp

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

Sắp xếp

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

9

Tham chiếu chức năng & phương pháp

Các Collections.sortphương pháp có thể sắp xếp một Listcách sử dụng một Comparatorbạn vượt qua. Điều đó Comparatorcó thể được thực hiện bằng Comparator.comparingphương thức mà bạn có thể truyền tham chiếu phương thức khi cần thiết Function. May mắn thay, mã thực tế đơn giản và ngắn hơn nhiều so với mô tả này.

Đối với Java 8:

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

hoặc là

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

Một cách khác là

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

1
Cuộc gọi yêu cầu API cấp 24
akshay bhange


6

Java 8 Lambda rút ngắn sắp xếp.

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

2
Collections.sort(stdList, Comparator.comparing(SomeClass::getName));
bcsb1001

5

Bạn có thể sử dụng Trình so sánh Bean để sắp xếp trên bất kỳ thuộc tính nào trong lớp tùy chỉnh của bạn.


5

Vâng, ví dụ như trong câu trả lời này, tôi sắp xếp theo thuộc tính vcủa lớpIndexValue

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

Nếu bạn nhận thấy ở đây tôi đang tạo một lớp bên trong ẩn danh (là Java để đóng) và chuyển trực tiếp nó đến sortphương thức của lớpArrays

Đối tượng của bạn cũng có thể triển khai Comparable(đó là String và hầu hết các thư viện cốt lõi trong Java) nhưng điều đó sẽ xác định "thứ tự sắp xếp tự nhiên" của lớp mà nó tự và không cho phép bạn cắm các thư viện mới.


1
... nhưng mà bạn chỉ có thể ghi đè bằng Comparator:)
BalusC

5

Tôi đã tìm thấy hầu hết nếu không phải tất cả các câu trả lời này đều dựa vào lớp bên dưới (Object) để thực hiện so sánh hoặc để có một giao diện so sánh trợ giúp.

Không phải với giải pháp của tôi! Đoạn mã sau cho phép bạn so sánh trường của đối tượng bằng cách biết tên chuỗi của chúng. Bạn có thể dễ dàng sửa đổi nó để không sử dụng tên, nhưng sau đó bạn cần phơi bày nó hoặc xây dựng một trong các Đối tượng bạn muốn so sánh với.

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

5

Bạn có thể thử đặt hàng ổi :

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

Bạn có thể Sắp xếp bằng java 8

yourList.sort(Comparator.comparing(Classname::getName));

or

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

3

Đoạn mã này có thể hữu ích. Nếu bạn muốn sắp xếp một Object trong trường hợp của tôi, tôi muốn sắp xếp theo 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;
}

Những công việc này. Tôi sử dụng nó trong jsp của tôi.


3

Với thư viện này ở đây, bạn có thể sắp xếp danh sách các đối tượng tùy chỉnh trên nhiều cột. Thư viện sử dụng các tính năng phiên bản 8.0. Mẫu cũng có sẵn ở đó. Đây là một mẫu để làm

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

3

Bạn có thể xem qua bài thuyết trình này tại Diễn đàn Java ở Stuttgart Đức năm 2016.

Chỉ có một vài slide sử dụng ngôn ngữ tiếng Đức, 99% nội dung là mã nguồn Java "dựa trên tiếng Anh"; giống

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

nơi OurCustomComparatorđang sử dụng các phương thức mặc định (và các ý tưởng thú vị khác). Như được hiển thị, dẫn đến mã rất súc tích để chọn một số phương thức getter để sắp xếp; và chuỗi siêu đơn giản (hoặc đảo ngược) của tiêu chí sắp xếp.

Nếu bạn vào java8, bạn sẽ tìm thấy rất nhiều tài liệu ở đó để bắt đầu.


3

Mới vì 1.8 là phương thức List.sort () thay vì sử dụng Collection.sort () để bạn gọi trực tiếp mylistcontainer.sort ()

Đây là đoạn mã trình bày tính năng 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]

Lớp trái cây là:

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   


1

Tôi thích quá trình này:

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

Nếu bạn liệt kê các đối tượng có một thuộc tính được gọi startDate, bạn gọi hãy sử dụng nó nhiều lần. Bạn thậm chí có thể xâu chuỗi chúngstartDate.time .

Điều này đòi hỏi đối tượng của bạn sẽ được Comparablemà có nghĩa là bạn cần có một compareTo, equalshashCode thực hiện.

Vâng, nó có thể nhanh hơn ... Nhưng bây giờ bạn không phải tạo một Bộ so sánh mới cho từng loại sắp xếp. Nếu bạn có thể tiết kiệm thời gian dev và từ bỏ thời gian chạy, bạn có thể đi với cái này.


3
1, câu trả lời này đã được đưa ra 2 giờ trước đó với mã làm việc được cung cấp là tốt. Không cần phải đăng lại cùng một giải pháp và làm lộn xộn diễn đàn, đặc biệt là vì BeanComparator không phải là một lớp tiêu chuẩn, vì vậy nó không thực sự là một giải pháp nếu người đăng không biết bạn đang nói gì. Nếu bạn thích đề xuất ban đầu, bạn có thể nâng cấp nó và thêm nhận xét nếu bạn muốn.
camickr

0

Sử dụng Java 8 có thể định nghĩa Comparatortrong một dòng bằng cách sử dụngComparator.comparing()

Sử dụng bất kỳ cách nào sau đây:

Lựa chọn 1:

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

Lựa chọn 2:

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

1
Có vẻ là một bản sao của Câu trả lời này từ 3 ​​năm trước.
Basil Bourque

1
Không chính xác, chỉ có tùy chọn 2 ở đây tương tự như tùy chọn 1 trong câu trả lời được đề cập. Tôi cảm thấy hai câu trả lời khác nhau có thể có ít nhất một số điểm tương đồng nếu chúng là câu trả lời cho cùng một câu hỏi.
Sahil Chhabra

0

Lớp tùy chỉnh của bạn có thể triển khai giao diện "Có thể so sánh", yêu cầu triển khai phương thức So sánh. Trong phương thức So sánh, sau đó bạn có thể xác định điều đó có nghĩa là một đối tượng nhỏ hơn hoặc nhiều hơn đối tượng khác. Vì vậy, trong ví dụ của bạn, nó có thể trông giống như thế này:

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

Một số âm cho thấy giá trị này nhỏ hơn đối tượng được so sánh. Số dương cho biết giá trị này lớn hơn so với đối tượng và Zero có nghĩa là các đối tượng bằng nhau.

Sau đó, bạn có thể sử dụng bộ sưu tập.sort (myList) để sắp xếp danh sách của mình mà không cần phải cung cấp bộ so sánh. Phương pháp này cũng có lợi thế là có những thứ được sắp xếp tự động nếu bạn sử dụng một cấu trúc dữ liệu bộ sưu tập được sắp xếp như TreeSet hoặc TreeMap.

Bạn có thể kiểm tra bài viết này nếu bạn muốn đọc thêm về giao diện So sánh (tiết lộ: Tôi là tác giả;)) https://nullbeans.com/the-java-comparable-interface-automatic-sort-of-collections/


0

Bạn cũng có thể sử dụng Springs PropertyComparator nếu bạn chỉ có một đường dẫn thuộc tính String đến thuộc tính (lồng nhau) mà bạn muốn sắp xếp:

List<SomeObject> list = ...;
PropertyComparator<HitWithInfo> propertyComparator = new PropertyComparator<>(
    "property.nested.myProperty", false, true);
list.sort(propertyComparator);

Hạn chế là, bộ so sánh này âm thầm bỏ qua các thuộc tính không tồn tại hoặc không thể truy cập và xử lý đây là giá trị null để so sánh. Điều này có nghĩa, bạn nên kiểm tra cẩn thận một bộ so sánh như vậy hoặc xác nhận sự tồn tại của đường dẫn tài sản bằng cách nào đó.


0

sử dụng api luồng java-8, bạn có thể sắp xếp ArrayListtheo:

 Comparator<Person> birthdayComparator = Comparator.comparing(Person::getBirthday);
 List<Person> sortedList = list.stream().sorted(birthdayComparator).collect(toList());

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.