[java] 속성별로 사용자 정의 객체의 ArrayList 정렬

Comparator를 사용하여 ArrayLists를 정렬하는 것에 대해 읽었지만 모든 예제에서 사람들이 사용한 compareTo연구에 따르면 Strings에 대한 방법입니다.

속성 중 하나 인 Date 객체 ( getStartDay()) 로 사용자 정의 객체의 ArrayList를 정렬하려고했습니다 . 일반적으로 나는 그것들을 비교하여 item1.getStartDate().before(item2.getStartDate())다음과 같은 것을 쓸 수 있는지 궁금합니다.

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



답변

때문에 Date구현 Comparable, 그것은이 compareTo처럼 방법을 String수행합니다.

따라서 사용자 정의 Comparator는 다음과 같이 보일 수 있습니다.

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

compare()메소드는을 리턴해야 int하므로 boolean계획했던 것처럼 직접 리턴 할 수 없습니다 .

정렬 코드는 다음과 같이 작성됩니다.

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

비교기를 재사용 할 필요가없는 경우이 모든 것을 작성하는 약간 더 짧은 방법은 인라인 익명 클래스로 작성하는 것입니다.

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

이후

이제 람다 식 을 사용하여 마지막 예제를 더 짧은 형식으로 작성할 수 있습니다 Comparator.

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

그리고 Listsort(Comparator)당신이 더욱이를 단축 할 수 있도록 방법 :

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

이것은 키가 있는 클래스 를 생성하는 내장 메소드 가있는 일반적인 관용구입니다 .ComparatorComparable

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

이들은 모두 동등한 형태입니다.


답변

자연스러운 정렬 순서 (예 : 클래스 번호)가있는 클래스는 Comparable 인터페이스를 구현해야하며, 자연 정렬 순서가없는 클래스 (예 : 클래스 Chair)는 Comparator (또는 익명 Comparator)와 함께 제공되어야합니다. 수업).

두 가지 예 :

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

용법:

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


답변

정렬을 ArrayList위해 다음 코드 스 니펫을 사용할 수 있습니다.

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


답변

그래 넌 할수있어. 비교 항목은 두 가지 옵션이 있습니다 대등 인터페이스 및 비교기 인터페이스.

이 두 인터페이스는 다른 동작을 허용합니다. Comparable을 사용하면 방금 설명한 String (사실 String이 Comparable을 구현 함)처럼 객체를 작동시킬 수 있습니다. 두 번째 인 Comparator를 사용하면 원하는 작업을 수행 할 수 있습니다. 당신은 이것을 이렇게 할 것입니다 :

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

그러면 Collections.sort 메소드가 정렬 메커니즘으로 비교기를 사용하게됩니다. ArrayList의 객체가 비슷한 것을 구현하면 대신 다음과 같이 할 수 있습니다.

Collections.sort(myArrayList);

컬렉션 클래스는이 유용한 일반적인 도구를 포함하고 있습니다.


답변

자바 8 람다 식

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

또는

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


답변

Java 8에서는 비교기에 메소드 참조를 사용할 수 있습니다.

import static java.util.Comparator.comparing;

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


답변

기술은 매일 나타나기 때문에 시간이지나면서 대답이 바뀝니다. LambdaJ를 살펴보고 매우 흥미로운 것 같습니다.

LambdaJ를 사용 하여 이러한 작업을 해결할 수 있습니다 . http://code.google.com/p/lambdaj/에서 찾을 수 있습니다.

여기 예가 있습니다 :

반복 정렬

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

람다로 정렬

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

물론 이런 종류의 아름다움이 성능에 영향을 미치지 만 (평균 2 배) 더 읽기 쉬운 코드를 찾을 수 있습니까?