Подреждане на enum стойности

Чудех се дали има някакъв начин за подреждане на enum за различни класове. Ако например имам фиксирана група от химикали, които реагират по различни начини на други химикали, някои силно, други слабо. По принцип искам да мога да променя реда, в който са подредени в зависимост от химикала, на който групата трябва да реагира (т.е. в зависимост от класа.). Знам, че трябва да използвам Comparable, но не съм сигурен как да го направя. Ако не съм достатъчно ясен, оставете коментар и ще обясня допълнително.

Благодаря.

public static enum Chem {
    H2SO4, 2KNO3, H20, NaCl, NO2
};

Така че имам нещо, което изглежда така, и вече знам как всеки химикал би реагирал на някои други химикали. Просто искам да подредя Chems въз основа на химикала, с който ще реагира. Това е почти всичко, което имам.


person Ester    schedule 05.05.2012    source източник
comment
Искате да кажете, че имате списък с химически компоненти, които искате да сортирате според различни критерии?   -  person Guillaume Polet    schedule 06.05.2012
comment
Не бих казал списък. Те са от тип enum.   -  person Ester    schedule 06.05.2012
comment
Определено не е достатъчно ясно. Можете ли да покажете някакъв код?   -  person Matt Ball    schedule 06.05.2012
comment
Членовете enum трябва да са валидни Java идентификатори. 2KNO3 не е валиден идентификатор на Java, тъй като започва с цифра.   -  person Mike Samuel    schedule 06.05.2012


Отговори (5)


Приложете различни Comparator (вижте http://docs.oracle.com/javase/6/docs/api/java/util/Comparator.html )

Comparator comparator1 = new Comparator<MyEnum>() {

  public int compare(MyEnum e1, MyEnum e2) {
     //your magic happens here
     if (...)
       return -1;
     else if (...)
       return 1;

     return 0;
  }
};

//and others for different ways of comparing them

//Then use one of them:
MyEnum[] allChemicals = MyEnum.values();
Arrays.sort(allChemicals, comparator1); //this is how you sort them according to the sort critiera in comparator1.
person Mattias Isegran Bergander    schedule 05.05.2012

Ето пример, показващ едни и същи стойности на enum, сортирани по различни критерии:

import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class SortEnum {

    public enum TestEnum {
        A(1, 2), B(5, 1), C(3, 0);
        private int value1;
        private int value2;

        private TestEnum(int value1, int value2) {
            this.value1 = value1;
            this.value2 = value2;
        }

        public int getValue1() {
            return value1;
        }

        public int getValue2() {
            return value2;
        }
    }

    public static void main(String[] args) {
        List<TestEnum> list = Arrays.asList(TestEnum.values());
        System.err.println(list);
        Collections.sort(list, new Comparator<TestEnum>() {
            @Override
            public int compare(TestEnum o1, TestEnum o2) {
                return o1.getValue1() - o2.getValue1();
            }
        });
        System.err.println(list);
        Collections.sort(list, new Comparator<TestEnum>() {
            @Override
            public int compare(TestEnum o1, TestEnum o2) {
                return o1.getValue2() - o2.getValue2();
            }
        });
        System.err.println(list);
    }
}

ИЗХОД е

[A, B, C] [A, C, B] [C, B, A]

person Guillaume Polet    schedule 05.05.2012

Да предположим, че имате набор от елементи:

enum Elements {Oxygen, Hydrogen, Gold}

и искате да ги сортирате в даден ред, тогава мога да направя:

Elements[] myElements = Elements.values();
Arrays.sort(myElements, new ElementComparator());

където ElementComparator може да бъде нещо като:

public class ElementComparator implements java.util.Comparator<Elements> {
    public int compare(Elements left, Elements right){
        return right.compareTo(left); //use your criteria here
    }
}

Естеството на критериите за поръчка не е ясно във вашия въпрос. Изглежда, че става въпрос за нещо, свързано с химични реакции. Предполагам, че критериите трябва да влизат в Comparator, за да се реши кой enum елемент е по-голям от другия при химическа реакция.

person Edwin Dalorzo    schedule 05.05.2012

Можете да поставите колкото искате компаратори в enum, вижте примера по-долу:

import java.util.Comparator;

public enum Day {
    MONDAY(1, 3),
    TUESDAY(2, 6),
    WEDNESDAY(3, 5),
    THURSDAY(4, 4),
    FRIDAY(5, 2),
    SATURDAY(6, 1),
    SUNDAY(0, 0);

    private final int calendarPosition;
    private final int workLevel;

    Day(int position, int level) {
      calendarPosition = position;
      workLevel = level;
    }

    int getCalendarPosition(){ return calendarPosition; }  
    int getWorkLevel() { return workLevel;  }

    public static Comparator<Day> calendarPositionComparator = new Comparator<Day>() {
      public int compare(Day d1, Day d2) {
        return d1.getCalendarPosition() - d2.getCalendarPosition();
      }
    };

    public static Comparator<Day> workLevelComparator = new Comparator<Day>() {
      public int compare(Day d1, Day d2) {
        // descending order, harder first
        return d2.getWorkLevel() - d1.getWorkLevel();
      }
    };
}

За да видите компараторите в действие:

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class EnumDayTest
{
  public static void main (String[] args) {
     List<Day> allDays = Arrays.asList(Day.values());
     System.out.println("===\nListing days in order of calendar position:");
     Collections.sort(allDays, Day.calendarPositionComparator);
     showItems(allDays);
     System.out.println("===\nListing days in order of work level:");
     Collections.sort(allDays, Day.workLevelComparator);
     showItems(allDays);
  }

  public static void showItems(List<Day> days) {
    for (Day day : days) {
      System.out.println(day.name());
    }
  }
}
person MaxZoom    schedule 14.01.2015

Искате да кажете, че действителните обекти, представляващи вашите химикали, са енуми? Това много звучи като странна реализация, ако мога да кажа: enums наистина са по-подходящи за „свойства“ на нещо.

Но така или иначе... ако наистина искате да ги представите като enums и след това да ги сортирате, бих предложил да внедрите Comparator, който може да сортира enums от вашия конкретен тип, след което в неговия метод compare() направете подходящото сравнение, напр.:

Comparator<Chemical> comp = new Comparator<Chemical>() {
    public int compare(Chemical o1, Chemical o2) {
        if (o1.reactivity() > o2.reactivity()) {
          return 1;
        } else if (o1.reactivity() < o2.reactivity()) {
          return -1;
        } else {
        return integer depending on whatever else you want to order by...
        }
    }
};

След това можете да предадете този компаратор към използвания метод за сортиране, подреден конструктор на колекция и т.н.

Можете да разширите своя enum подклас, за да включите всякакви допълнителни методи, напр. reactivity(), която изисквате.

person Neil Coffey    schedule 05.05.2012