programing

Comparator를 사용하여 커스텀 정렬 순서를 정의하려면 어떻게 해야 합니까?

minecode 2022. 10. 31. 21:19
반응형

Comparator를 사용하여 커스텀 정렬 순서를 정의하려면 어떻게 해야 합니까?

자동차 목록 정렬 데모를 개발하고 싶습니다.데이터 테이블을 사용하여 차량 목록을 표시하고 있습니다.자동차 색상별로 목록을 정렬하려고 합니다.여기서는 알파벳 순서로 정렬되지 않습니다.빨간색 차가 먼저 오고, 파란색이 먼저 오는 등 커스텀 정렬 순서를 사용하고 싶습니다.

그러기 위해 Java를 사용하려고 하는데 알파벳 순서로만 정렬이 가능합니다.

따라서 분류가 더 빨라질 수 있도록 사용하는 기술을 구현하는 방법을 안내해 주실 수 있습니까?

class Car implements Comparable<Car>
{
    private String name;
    private String color;

    public Car(String name, String color){
        this.name = name;
        this.color = color;
    }

    //Implement the natural order for this class
    public int compareTo(Car c) {
        return name.compareTo(c.name);
    }

    static class ColorComparator implements Comparator<Car> {
        public int compare(Car c1, Car c2) {
            String a1 = c1.color;
            String a2 = c2.color;
            return a1.compareTo(a2);
        }
    }

    public static void main(String[] args) {
        List<Car> carList = new ArrayList<>();
        List<String> sortOrder = new ArrayList<>();

        carList.add(new Car("Ford","Silver"));
        carList.add(new Car("Tes","Blue"));
        carList.add(new Car("Honda","Magenta"));

        sortOrder.add("Silver");
        sortOrder.add("Magenta");
        sortOrder.add("Blue");

        // Now here I am confuse how to implement my custom sort             
    }
}

Strings를 사용하는 대신 차량 색상에 대한 열거를 작성할 것을 권장합니다. 열거의 자연 순서는 상수를 선언하는 순서가 됩니다.

public enum PaintColors {
    SILVER, BLUE, MAGENTA, RED
}

그리고.

 static class ColorComparator implements Comparator<CarSort>
 {
     public int compare(CarSort c1, CarSort c2)
     {
         return c1.getColor().compareTo(c2.getColor());
     }
 }

String을 PaintColor로 변경한 후 차량 목록은 주로 다음과 같습니다.

carList.add(new CarSort("Ford Figo",PaintColor.SILVER));

...

Collections.sort(carList, new ColorComparator());

이거 어때:

List<String> definedOrder = // define your custom order
    Arrays.asList("Red", "Green", "Magenta", "Silver");

Comparator<Car> comparator = new Comparator<Car>(){

    @Override
    public int compare(final Car o1, final Car o2){
        // let your comparator look up your car's color in the custom order
        return Integer.valueOf(
            definedOrder.indexOf(o1.getColor()))
            .compareTo(
                Integer.valueOf(
                    definedOrder.indexOf(o2.getColor())));
    }
};

원칙적으로, I는 다음 명령어를 사용하는 것에 동의합니다.enum는 훨씬 뛰어난 접근법이지만, 이 버전에서는 다양한 정렬 순서를 정의할 수 있기 때문에 유연성이 향상되었습니다.

갱신하다

Guava의 클래스에는 다음과 같은 기능이 내장되어 있습니다.

List<String> colorOrder = ImmutableList.of("red","green","blue","yellow");
final Ordering<String> colorOrdering = Ordering.explicit(colorOrder);
Comparator<Car> comp = new Comparator<Car>() {
    @Override
    public int compare(Car o1, Car o2) {
        return colorOrdering.compare(o1.getColor(),o2.getColor());
    }
}; 

이 버전은 좀 덜 장황하다.


다시 업데이트

Java 8은 비교기의 세부사항을 더욱 줄여줍니다.

Comparator<Car> carComparator = Comparator.comparing(
        c -> definedOrder.indexOf(c.getColor()));

비교기 라인...

List<Object> objList = findObj(name);
Collections.sort(objList, new Comparator<Object>() {
    @Override
    public int compare(Object a1, Object a2) {
        return a1.getType().compareToIgnoreCase(a2.getType());
    }
});

다음과 같이 할 수 있다고 생각합니다.

class ColorComparator implements Comparator<CarSort>
{
    private List<String> sortOrder;
    public ColorComparator (List<String> sortOrder){
        this.sortOrder = sortOrder;
    }

    public int compare(CarSort c1, CarSort c2)
    {
        String a1 = c1.getColor();
        String a2 = c2.getColor();
        return sortOrder.indexOf(a1) - sortOrder.indexOf(a2);
     }
 }

정렬의 경우 다음을 사용합니다.

Collections.sort(carList, new ColorComparator(sortOrder));

숀과 일랄렉스의 대답과 비슷한 걸 해야 했어요
다만, 소트 순서를 명시적으로 정의할 수 있는 옵션이 너무 많아, 리스트의 선두에 특정의 엔트리를 플로우 하는 것만으로 충분했습니다.지정된(비자연적) 순서로.
이게 다른 사람에게 도움이 되었으면 좋겠어요.

public class CarComparator implements Comparator<Car> {

    //sort these items in this order to the front of the list 
    private static List<String> ORDER = Arrays.asList("dd", "aa", "cc", "bb");

    public int compare(final Car o1, final Car o2) {
        int result = 0;
        int o1Index = ORDER.indexOf(o1.getName());
        int o2Index = ORDER.indexOf(o2.getName());
        //if neither are found in the order list, then do natural sort
        //if only one is found in the order list, float it above the other
        //if both are found in the order list, then do the index compare
        if (o1Index < 0 && o2Index < 0) result = o1.getName().compareTo(o2.getName());
        else if (o1Index < 0) result = 1;
        else if (o2Index < 0) result = -1;
        else result = o1Index - o2Index;
        return result;
    }

//Testing output: dd,aa,aa,cc,bb,bb,bb,a,aaa,ac,ac,ba,bd,ca,cb,cb,cd,da,db,dc,zz
}

다음과 같이 하겠습니다.

List<String> order = List.of("Red", "Green", "Magenta", "Silver");

Comparator.comparing(Car::getColor(), Comparator.comparingInt(c -> order.indexOf(c)))

모든 크레딧은 @Sean Patrick Floyd :)

Java 8에서는 다음과 같은 작업을 수행할 수 있습니다.

먼저 Enum이 필요합니다.

public enum Color {
    BLUE, YELLOW, RED
}

자동차 클래스:

public class Car {

    Color color;

    ....

    public Color getColor() {
        return color;
    }

    public void setColor(Color color) {
        this.color = color;
    }
}

그런 다음 차량 목록을 사용하여 다음을 수행할 수 있습니다.

Collections.sort(carList, Comparator:comparing(CarSort::getColor));

1개의 Enum 타입을 다음과 같이 정의합니다.

public enum Colors {
     BLUE, SILVER, MAGENTA, RED
}

데이터 유형 변경color부터String로.Colorsgetter의 반환 유형 및 인수 유형 및 색상 설정 방법 변경Colors

다음과 같이 비교기 유형을 정의합니다.

static class ColorComparator implements Comparator<CarSort>
{
    public int compare(CarSort c1, CarSort c2)
    {
        return c1.getColor().compareTo(c2.getColor());
    }
}

List에 요소를 추가한 후 목록 및 비교기 개체를 인수로 전달하여 수집의 정렬 메서드를 호출합니다.

예,Collections.sort(carList, new ColorComparator());그런 다음 다음을 사용하여 인쇄합니다.ListIterator.

풀 클래스의 실장은 다음과 같습니다.

package test;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;    
import java.util.ListIterator;

public class CarSort implements Comparable<CarSort>{

    String name;
    Colors color;

    public CarSort(String name, Colors color){
        this.name = name;
        this.color = color;
    } 

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Colors getColor() {
        return color;
    }
    public void setColor(Colors color) {
        this.color = color;
    }

    //Implement the natural order for this class
    public int compareTo(CarSort c)
    {
        return getName().compareTo(c.getName());
    }

    static class ColorComparator implements Comparator<CarSort>
    {
        public int compare(CarSort c1, CarSort c2)
        {
            return c1.getColor().compareTo(c2.getColor());
        }
    }

    public enum Colors {
         BLUE, SILVER, MAGENTA, RED
    }

     public static void main(String[] args)
     {
         List<CarSort> carList = new ArrayList<CarSort>();
         List<String> sortOrder = new ArrayList<String>();

         carList.add(new CarSort("Ford Figo",Colors.SILVER));
         carList.add(new CarSort("Santro",Colors.BLUE));
         carList.add(new CarSort("Honda Jazz",Colors.MAGENTA));
         carList.add(new CarSort("Indigo V2",Colors.RED));
         Collections.sort(carList, new ColorComparator());

         ListIterator<CarSort> itr=carList.listIterator();
         while (itr.hasNext()) {
            CarSort carSort = (CarSort) itr.next();
            System.out.println("Car colors: "+carSort.getColor());
        }
     }
}

단순한 루프 사용:

public static void compareSortOrder (List<String> sortOrder, List<String> listToCompare){
        int currentSortingLevel = 0;
        for (int i=0; i<listToCompare.size(); i++){
            System.out.println("Item from list: " + listToCompare.get(i));
            System.out.println("Sorting level: " + sortOrder.get(currentSortingLevel));
            if (listToCompare.get(i).equals(sortOrder.get(currentSortingLevel))){

            } else {
                try{
                    while (!listToCompare.get(i).equals(sortOrder.get(currentSortingLevel)))
                        currentSortingLevel++;
                    System.out.println("Changing sorting level to next value: " + sortOrder.get(currentSortingLevel));
                } catch (ArrayIndexOutOfBoundsException e){

                }

            }
        }
    }

목록 내 정렬 순서

public static List<String> ALARMS_LIST = Arrays.asList(
            "CRITICAL",
            "MAJOR",
            "MINOR",
            "WARNING",
            "GOOD",
            "N/A");

언급URL : https://stackoverflow.com/questions/5245093/how-do-i-use-comparator-to-define-a-custom-sort-order

반응형