Pertanyaan Urutkan ArrayList Objek kustom oleh properti


Saya membaca tentang menyortir ArrayLists menggunakan Comparator tetapi di semua contoh yang digunakan orang compareTo yang menurut beberapa penelitian adalah metode untuk Strings.

Saya ingin mengurutkan ArrayList objek khusus oleh salah satu propertinya: sebuah objek Tanggal (getStartDay()). Biasanya saya membandingkannya dengan item1.getStartDate().before(item2.getStartDate()) jadi saya bertanya-tanya apakah saya bisa menulis sesuatu seperti:

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

952
2018-05-06 21:09


asal


Jawaban:


Sejak Date mengimplementasikan Comparable, itu memiliki compareTo metode seperti String tidak.

Jadi kebiasaanmu Comparator bisa terlihat seperti ini:

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

Itu compare() metode harus mengembalikan int, sehingga Anda tidak dapat langsung mengembalikan boolean seperti yang Anda rencanakan.

Kode penyortiran Anda akan seperti yang Anda tulis:

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

Cara yang sedikit lebih pendek untuk menulis semua ini, jika Anda tidak perlu menggunakan kembali pembanding Anda, adalah menulisnya sebagai kelas anonim inline:

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

Sejak

Anda sekarang dapat menulis contoh terakhir dalam bentuk yang lebih pendek dengan menggunakan a ekspresi lambda Untuk Comparator:

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

Dan List mempunyai sebuah sort(Comparator) metode, sehingga Anda dapat mempersingkat ini lebih jauh:

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

Ini adalah ungkapan umum yang ada metode bawaan untuk menghasilkan Comparator untuk kelas dengan Comparable kunci:

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

Semua ini adalah bentuk yang setara.


1305
2018-05-06 21:18



Kelas yang memiliki susunan urutan alami (Nomor kelas, sebagai contoh) harus mengimplementasikan antarmuka Comparable, sementara kelas yang tidak memiliki urutan urutan alami (Ketua kelas, sebagai contoh) harus dilengkapi dengan Pembanding (atau Komparator anonim kelas).

Dua contoh:

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

Pemakaian:

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

181
2018-05-06 21:45



Untuk menyortir sebuah ArrayList Anda bisa menggunakan potongan kode berikut:

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

150
2018-05-06 13:50



Ya kamu bisa. Ada dua opsi dengan membandingkan item, Sebanding antarmuka, dan Pembanding antarmuka.

Kedua antarmuka ini memungkinkan perilaku yang berbeda. Sebanding memungkinkan Anda untuk membuat objek bertindak seperti Anda baru saja dijelaskan Strings (sebenarnya, String mengimplementasikan Comparable). Yang kedua, Comparator, memungkinkan Anda melakukan apa yang Anda minta. Anda akan melakukannya seperti ini:

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

Itu akan menyebabkan metode Collections.sort menggunakan komparator Anda untuk mekanisme penyortirannya. Jika objek dalam ArrayList menerapkan sebanding, Anda malah bisa melakukan sesuatu seperti ini:

Collections.sort(myArrayList);

Itu Koleksi kelas berisi sejumlah alat yang berguna dan umum ini.


40
2018-05-06 21:17



JAWA 8 lambda ekspresi

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

ATAU

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

31
2017-09-05 13:10



Dengan Java 8 Anda dapat menggunakan referensi metode untuk komparator Anda:

import static java.util.Comparator.comparing;

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

26
2018-03-13 15:19



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

}

}

13
2018-04-03 15:32



Karena teknologi muncul setiap hari, jawabannya akan berubah dalam waktu. Saya melihat LambdaJ dan sepertinya sangat menarik.

Anda dapat mencoba menyelesaikan tugas-tugas ini LambdaJ. Anda dapat menemukannya di sini: http://code.google.com/p/lambdaj/

Di sini Anda memiliki contoh:

Urutkan Iteratif

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

Sortir dengan lambda

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

Tentu saja, memiliki keindahan seperti ini berdampak pada kinerja (rata-rata 2 kali), tetapi dapatkah Anda menemukan kode yang lebih mudah dibaca?


13
2018-03-12 17:49