1

想象一下,我有一个域对象,其中有一个名为 enum 的域对象,SortBy以方便对来自服务和/或 dao 层的数据进行排序。

public class Item {
    public static enum SortBy { CATEGORY, NORWEGIAN, ENGLISH; }

    private String category;
    private String norwegian;
    private String English;
}

因此,这种操作是可能的:itemDao.getItems(Item.SortBy.CATEGORY)

现在,是否有一种设计模式或很好的方法可以将这些SortBy值与 java相关联Comparator

自从我最初想到 used 的方式以来,我一直在问这个问题static,这是不好的做法(对吗?)。

  1. AMap<SortBy, Comparator<Item>在 Item 类中?

  2. 一个ItemComparators有方法的类getComparator(Item.SortBy sort)

  3. SortBy枚举本身的一个方法,它返回一个静态实例Comparator<Item>

我正在寻找一种极简主义的方式来做到这一点,而不是ItemComparatorProvider去吃豆子。

欣赏任何信息...

4

3 回答 3

4

最直接的方法是简单地让enum自身实现Comparator

public enum SortBy implements Comparator<Item> {
    CATEGORY {
        @Override
        public final int compare(final Item o1, final Item o2) {
            return compareStrings(o1.getCategory(), o2.getCategory());
        }
    },
    ENGLISH {
        @Override
        public final int compare(final Item o1, final Item o2) {
            return compareStrings(o1.getEnglish(), o2.getEnglish());
        }
    },
    NORWEGIAN {
        @Override
        public final int compare(final Item o1, final Item o2) {
            return compareStrings(o1.getNorwegian(), o2.getNorwegian());
        }
    };

    private static int compareStrings(final String s1, final String s2) {
        if (s1 == null) {
            return s2 == null ? 0 : -1;
        }
        if (s2 == null) {
            return 1;
        }
        return s1.compareTo(s2);
    }
}

无需进一步将每个枚举成员与比较器相关联,因为枚举成员比较器。用法很简洁:

Collections.sort(items, SortBy.CATEGORY);

附录

在下面的评论中,您询问了常见的null安全比较。我不确定第三方库可能会提供什么,但您可以很容易地自己实现它们。这是我们内部库之一中的两个:

static <T extends Comparable<? super T>> int compare(final T o1, final T o2) {
    if (o1 == null) {
        return o2 == null ? 0 : -1;
    }
    if (o2 == null) {
        return 1;
    }
    return o1.compareTo(o2);
}

@SuppressWarnings("unchecked")
static int compare(final Object a, final Object b) {
    if (a == b) {
        return 0;
    }

    if (a == null) {
        return -1;
    }

    if (b == null) {
        return 1;
    }

    final Class<?> aClass = a.getClass();
    final Class<?> bClass = b.getClass();

    if (Comparable.class.isInstance(a) && aClass.isAssignableFrom(bClass)) {
        return ((Comparable<Object>)a).compareTo(b);
    }

    if (Comparable.class.isInstance(b) && bClass.isAssignableFrom(aClass)) {
        return ((Comparable<Object>)b).compareTo(a);
    }

    throw new IllegalArgumentException("Values must be comparable.");
}
于 2013-11-14T14:00:31.207 回答
2

你可以考虑这样的事情:

public static enum SortBy {

 CATEGORY(new CategoryComparator()), NORWEGIAN(new NorwegianComparator()), ENGLISH(new EnglishComparator());

    Comparator<Item> comparator;

    private SortBy(Comparator<Item> comparator) {
        this.comparator = comparator;
    }

}

如果您将在其他地方使用它们,您可以实现Comparator并创建新类,或者将它们实现为匿名内部类,如 vikingsteve 的回答。

于 2013-11-14T13:55:24.460 回答
1

好的,这是一种方法。这样好吗?

public static enum SortBy {
    CATEGORY(new Comparator<Item>() {
        @Override
        public int compare(Item o1, Item o2) {
            return o1.getCategory().compareTo(o2.getCategory());
        }
    }),
    NORWEGIAN(new Comparator<Item>() {
        @Override
        public int compare(Item o1, Item o2) {
            return o1.getNorwegian().compareTo(o2.getNorwegian());
        }
    }),
    ENGLISH(new Comparator<Item>() {
        @Override
        public int compare(Item o1, Item o2) {
            return o1.getEnglish().compareTo(o2.getEnglish());
        }
    });
    private Comparator<Item> comparator;

    private SortBy(Comparator<Item> comparator) {
        this.comparator = comparator;
    }

    public Comparator<Item> getComparator() {
        return comparator;
    }
}
于 2013-11-14T13:54:38.560 回答