Java 有没有一种通过枚举实现多个比较器的好方法?

Java 有没有一种通过枚举实现多个比较器的好方法?,java,enums,comparator,Java,Enums,Comparator,假设我有一个名为SortBy的枚举的域对象,以便对来自服务和/或dao层的数据进行排序 public class Item { public static enum SortBy { CATEGORY, NORWEGIAN, ENGLISH; } private String category; private String norwegian; private String English; } 因此,这种操作是可能的:itemDao.getItems(It

假设我有一个名为
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)

现在,有没有一种设计模式或很好的方法将
排序的
值与java
比较器
关联起来

我问这个问题是因为我最初想到的方法是使用
静态
,这是一种糟糕的做法(对吧?)


  • A
    Map好的,这里有一种方法。这样好吗

    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;
        }
    }
    
    公共静态枚举排序{
    类别(新的比较国(){
    @凌驾
    公共整数比较(项目o1、项目o2){
    返回o1.getCategory().compareTo(o2.getCategory());
    }
    }),
    挪威(新的比较国(){
    @凌驾
    公共整数比较(项目o1、项目o2){
    返回o1.getNorwegian().compareTo(o2.getNorwegian());
    }
    }),
    英文(新的比较法){
    @凌驾
    公共整数比较(项目o1、项目o2){
    返回o1.getEnglish().compareTo(o2.getEnglish());
    }
    });
    专用比较器;
    专用排序(比较器-比较器){
    这个比较器=比较器;
    }
    公共比较器getComparator(){
    返回比较器;
    }
    }
    
    好的,这里有一种方法。这样好吗

    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;
        }
    }
    
    公共静态枚举排序{
    类别(新的比较国(){
    @凌驾
    公共整数比较(项目o1、项目o2){
    返回o1.getCategory().compareTo(o2.getCategory());
    }
    }),
    挪威(新的比较国(){
    @凌驾
    公共整数比较(项目o1、项目o2){
    返回o1.getNorwegian().compareTo(o2.getNorwegian());
    }
    }),
    英文(新的比较法){
    @凌驾
    公共整数比较(项目o1、项目o2){
    返回o1.getEnglish().compareTo(o2.getEnglish());
    }
    });
    专用比较器;
    专用排序(比较器-比较器){
    这个比较器=比较器;
    }
    公共比较器getComparator(){
    返回比较器;
    }
    }
    
    你可以这样想:

    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的回答中那样将它们实现为匿名内部类。

    您可以考虑以下内容:

    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的回答中那样将它们实现为匿名内部类。

    最简单的方法是让
    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);
        }
    }
    

    附录

    在下面的评论中,您询问了常见的,
    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.");
    }
    
    static aClass=a.getClass();
    最终类b类=b.getClass();
    if(可比类isInstance(a)和类isAssignableFrom(B类)){
    回报率((可比)a)。与(b)相比;
    }
    if(可比类isInstance(b)和&b类isAssignableFrom(aClass)){
    回报率((可比)b)。与(a)相比;
    }
    抛出新的IllegalArgumentException(“值必须是可比较的”);
    }
    
    最简单的方法是让
    枚举
    本身实现
    比较器

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

    附录

    在下面的评论中,您询问了常见的,
    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.");
    }
    
    static aClass=a.getClass();
    最终类b类=b.getClass();
    if(可比类isInstance(a)和类isAssignableFrom(B类)){
    回报率((可比)a)。与(b)相比;
    }
    if(可比类isInstance(b)和&b类isAssignableFrom(aClass)){
    回报率((可比)b)。与(a)相比;
    }
    抛出新的IllegalArgumentException(“值必须是可比较的”);
    }
    
    是。虽然您可以通过使用BeanComparator并仅在构造函数中传递属性使其更加简洁。他在哪里可以找到类
    BeanComparator
    ?。我相信它在Apache Commons库中<代码>公用小动物
    ,也许?是的。虽然您可以通过使用BeanComparator并仅在构造函数中传递属性使其更加简洁。他在哪里可以找到类
    BeanComparator
    ?。我相信它在Apache Commons库中<代码>公用小动物
  • ,也许?很好,正是我想要的。谢谢。很高兴能帮忙!直到我刚才试过它,我才100%确定这是可能的,所以我也学到了一些东西:)。我还看到你输入了空安全字符串比较,所以我也学到了一些东西。那也是在公共场所或类似的地方吗?我不确定。我们这里不使用很多第三方(甚至J2SE)代码。我从我们自己的
    Compare
    类中发布了几个示例。我还看到commons lang3
    ObjectUtils.Compare()
    也可以使用,它看起来与上面的代码相当