programing

사용자 지정 정렬 순서를 사용하여 개체의 ArrayList 정렬

randomtip 2022. 10. 12. 21:24
반응형

사용자 지정 정렬 순서를 사용하여 개체의 ArrayList 정렬

주소록 앱에 정렬 기능을 구현하려고 합니다.

하고 ArrayList<Contact> contactArrayContact는 이름, 집 번호, 휴대전화 번호 및 주소의 4가지 필드를 포함하는 클래스입니다.분분 on on on on로 name.

이를 위해 커스텀 정렬 함수를 작성하려면 어떻게 해야 합니까?

다음은 객체 정렬에 대한 튜토리얼입니다.

몇 가지 예를 들겠지만, 어쨌든 읽어보는 것을 추천합니다.


으로 분류할 수 있습니다.ArrayList. 자연(기본값) 순서를 정의하려면 다음 절차를 수행해야 합니다.Contact디폴트로 정렬하는 것을 전제로 하고 있습니다.name다음 작업을 수행합니다(간단하게 하기 위해 체크 생략).

public class Contact implements Comparable<Contact> {

    private String name;
    private String phone;
    private Address address;

    @Override
    public int compareTo(Contact other) {
        return name.compareTo(other.name);
    }

    // Add/generate getters/setters and other boilerplate.
}

그냥 할 수 있도록

List<Contact> contacts = new ArrayList<Contact>();
// Fill it.

Collections.sort(contacts);

외부 제어 가능한 순서(자연의 순서보다 우선)를 정의하는 경우는, 다음과 같이 작성할 필요가 있습니다.

List<Contact> contacts = new ArrayList<Contact>();
// Fill it.

// Now sort by address instead of name (default).
Collections.sort(contacts, new Comparator<Contact>() {
    public int compare(Contact one, Contact other) {
        return one.getAddress().compareTo(other.getAddress());
    }
}); 

「 」, 「 」도 정의할 수 .Comparator는 s s s s s s s 。Contact매번 재작성하지 않고 재사용할 수 있습니다.

public class Contact {

    private String name;
    private String phone;
    private Address address;

    // ...

    public static Comparator<Contact> COMPARE_BY_PHONE = new Comparator<Contact>() {
        public int compare(Contact one, Contact other) {
            return one.phone.compareTo(other.phone);
        }
    };

    public static Comparator<Contact> COMPARE_BY_ADDRESS = new Comparator<Contact>() {
        public int compare(Contact one, Contact other) {
            return one.address.compareTo(other.address);
        }
    };

}

다음과 같이 사용할 수 있습니다.

List<Contact> contacts = new ArrayList<Contact>();
// Fill it.

// Sort by address.
Collections.sort(contacts, Contact.COMPARE_BY_ADDRESS);

// Sort later by phone.
Collections.sort(contacts, Contact.COMPARE_BY_PHONE);

또한 위에 크림을 바르려면 범용 자바비교기의 사용을 고려할 수 있습니다.

public class BeanComparator implements Comparator<Object> {

    private String getter;

    public BeanComparator(String field) {
        this.getter = "get" + field.substring(0, 1).toUpperCase() + field.substring(1);
    }

    public int compare(Object o1, Object o2) {
        try {
            if (o1 != null && o2 != null) {
                o1 = o1.getClass().getMethod(getter, new Class[0]).invoke(o1, new Object[0]);
                o2 = o2.getClass().getMethod(getter, new Class[0]).invoke(o2, new Object[0]);
            }
        } catch (Exception e) {
            // If this exception occurs, then it is usually a fault of the developer.
            throw new RuntimeException("Cannot compare " + o1 + " with " + o2 + " on " + getter, e);
        }

        return (o1 == null) ? -1 : ((o2 == null) ? 1 : ((Comparable<Object>) o1).compareTo(o2));
    }

}

다음과 같이 사용할 수 있습니다.

// Sort on "phone" field of the Contact bean.
Collections.sort(contacts, new BeanComparator("phone"));

(코드에서 볼 수 있듯이 정렬 시 NPE를 피하기 위해 NULL 필드가 이미 커버되어 있을 수 있습니다.)

BalusC에 의해 이미 게시된 내용과 더불어 Java 8을 통해 다음과 같이 코드를 단축하고 작성할 수 있다는 점을 지적할 필요가 있습니다.

Collection.sort(yourList, Comparator.comparing(YourClass::getSomeComparableField));

List가 " "를 가지고 있습니다.sort authorly like 。

yourList.sort(Comparator.comparing(YourClass::getSomeComparableField));

설명:

Java 8 이후 기능 인터페이스(추상 메서드가1개뿐인 인터페이스-디폴트 메서드 또는 스태틱메서드를 더 많이 가질 수 있음)는 다음과 같이 쉽게 구현할 수 있습니다.

★★Comparator<T>인 방법이 int compare(T o1, T o2)기능 인터페이스입니다.

(@BalusC응답 예) 대신

Collections.sort(contacts, new Comparator<Contact>() {
    public int compare(Contact one, Contact other) {
        return one.getAddress().compareTo(other.getAddress());
    }
}); 

이 코드를 다음과 같이 줄일 수 있습니다.

Collections.sort(contacts, (Contact one, Contact other) -> {
     return one.getAddress().compareTo(other.getAddress());
});

이 (또는 임의의) 람다를 건너뛰어 단순화할 수 있습니다.

  • 인수 타입(Java는 메서드시그니처에 따라 인수 타입을 추론합니다)
  • ★★★★★★★★★★★★★★★★★」{return}

그래서 대신

(Contact one, Contact other) -> {
     return one.getAddress().compareTo(other.getAddress();
}

우리는 쓸 수 있다

(one, other) -> one.getAddress().compareTo(other.getAddress())

, 지금 ★★★★★★★★★★★★★★★★」Comparator.comparing(FunctionToComparableValue) ★★★★★★★★★★★★★★★★★」comparing(FunctionToValue, ValueComparator)오브젝트의 특정 값을 비교하는 비교기를 쉽게 작성할 수 있습니다.

즉, 위의 코드를 다음과 같이 고쳐 쓸 수 있습니다.

Collections.sort(contacts, Comparator.comparing(Contact::getAddress)); 
//assuming that Address implements Comparable (provides default order).

이 페이지에서는 ArrayList와 같은 정렬 컬렉션에 대해 알아야 할 모든 정보를 제공합니다.

기본적으로는

  • Contact class를 구현합니다.Comparable에 의해 접속하다.
    • public int compareTo(Contact anotherContact)안에. 그에안.
  • 하면 만 하면 .Collections.sort(myContactList);,
    • 서 ''는myContactListArrayList<Contact> 컬렉션)Contact를 참조해 주세요.

또한 Comparator 클래스를 만드는 방법도 있습니다. 링크된 페이지에서도 이에 대해 읽을 수 있습니다.

예:

public class Contact implements Comparable<Contact> {

    ....

    //return -1 for less than, 0 for equals, and 1 for more than
    public compareTo(Contact anotherContact) {
        int result = 0;
        result = getName().compareTo(anotherContact.getName());
        if (result != 0)
        {
            return result;
        }
        result = getNunmber().compareTo(anotherContact.getNumber());
        if (result != 0)
        {
            return result;
        }
        ...
    }
}

BalusC와 bguiz는 이미 Java의 내장 Comparator 사용 방법에 대해 매우 완벽한 답변을 제공했습니다.

Google 컬렉션에는 표준 비교 도구보다 "강력한" Ordering 클래스가 있습니다.확인해 볼 만한 가치가 있을지도 몰라요.순서를 합성하거나, 순서를 반대로 하거나, 오브젝트에 대한 함수 결과에 따라 순서를 매기는 등 멋진 작업을 할 수 있습니다.

여기 그 장점 중 일부를 언급하는 블로그 게시물이 있습니다.

Contact 클래스에서 Comparible을 구현한 후compareTo(Contact) 수 있습니다.정렬이 가능합니다.링크한 페이지에 따라 compareTo '이 개체가 지정된 개체보다 작거나 같거나 크므로 음의 정수, 0 또는 양의 정수를 반환합니다.'

예를 들어 이름(A ~ Z)을 기준으로 정렬하려는 경우 클래스는 다음과 같습니다.

public class Contact implements Comparable<Contact> {

    private String name;

    // all the other attributes and methods

    public compareTo(Contact other) {
        return this.name.compareTo(other.name);
    }
}

lamdaj를 사용하면 연락처 모음(예를 들어 이름)을 다음과 같이 정렬할 수 있습니다.

sort(contacts, on(Contact.class).getName());

또는 주소:

sort(contacts, on(Contacts.class).getAddress());

기타 등등.일반적으로는 DSL을 사용하여 특정 조건에 따라 연락처 필터링 또는 그룹화, 속성 값 중 일부 집계 등 다양한 방법으로 컬렉션에 액세스 및 조작할 수 있습니다.

오래전에 대답한 거 알아요여기 새로운 정보가 있습니다.

예를 들어, 해당 Contact 클래스에 Comparable 구현을 통해 정의된 자연 순서가 있지만, 예를 들어 이름별로 해당 순서를 재정의하려고 합니다.이를 위한 현대적 방법은 다음과 같습니다.

List<Contact> contacts = ...;

contacts.sort(Comparator.comparing(Contact::getName).reversed().thenComparing(Comparator.naturalOrder());

이렇게 하면 이름별로 먼저 정렬된 후(역순으로), 이름 충돌의 경우 Contact 클래스 자체에 의해 구현된 '자연스러운' 순서로 돌아갑니다.

Collections.sort는 적절한 정렬 구현입니다.Contact에 대해 동등한 제품이 구현되지 않은 경우 Comparator 구현에 합격해야 합니다.

주목:

정렬 알고리즘은 변경된 mergesort(하위 서브리스트의 상위 요소가 상위 서브리스트의 하위 요소보다 작을 경우 병합이 생략됩니다)입니다.이 알고리즘은 n개의 로그(n) 성능을 보증합니다.지정된 목록은 수정 가능해야 하지만 크기를 조정할 필요는 없습니다.이 구현에서는 지정된 목록을 배열에 덤프하고 배열을 정렬한 후 목록 전체를 반복하여 배열 내의 해당 위치에서 각 요소를 재설정합니다.이렇게 하면 링크된 목록을 정렬하려고 시도했을 때 발생하는 n2 로그(n) 성능이 방지됩니다.

대부분의 검색 알고리즘보다 병합 정렬이 더 나을 수 있습니다.

나는 다음과 같은 방법으로 그것을 했다.number와 name은 2개의 배열 목록입니다.이름을 정렬해야 합니다.이름 Arralist 순서가 변경된 경우 number array list의 순서도 변경됩니다.

public void sortval(){

        String tempname="",tempnum="";

         if (name.size()>1) // check if the number of orders is larger than 1
            {
                for (int x=0; x<name.size(); x++) // bubble sort outer loop
                {
                    for (int i=0; i < name.size()-x-1; i++) {
                        if (name.get(i).compareTo(name.get(i+1)) > 0)
                        {

                            tempname = name.get(i);

                            tempnum=number.get(i);


                           name.set(i,name.get(i+1) );
                           name.set(i+1, tempname);

                            number.set(i,number.get(i+1) );
                            number.set(i+1, tempnum);


                        }
                    }
                }
            }



}

다음 방법을 사용합니다.

private ArrayList<myClass> sortList(ArrayList<myClass> list) {
    if (list != null && list.size() > 1) {
        Collections.sort(list, new Comparator<myClass>() {
            public int compare(myClass o1, myClass o2) {
                if (o1.getsortnumber() == o2.getsortnumber()) return 0;
                return o1.getsortnumber() < o2.getsortnumber() ? 1 : -1;
            }
        });
    }
    return list;
}

`

및 용도:mySortedlist = sortList(myList);클래스에서는 비교기를 구현할 필요가 없습니다.역순서 교환을 원하는 경우1그리고.-1

Java 8 기능 탑재

List<Contact> contact = contactArray.stream().sorted((c1, c2) -> ((c1.getName().compareTo(c2.getName())))).collect(Collectors.toList());

어레이를 사용해야 합니다.정렬 기능포함하는 클래스는 Comparable을 구현해야 합니다.

언급URL : https://stackoverflow.com/questions/1814095/sorting-an-arraylist-of-objects-using-a-custom-sorting-order

반응형