如何在Java中自定义Set的排序

时间:2014-03-06 16:06:14

标签: java sorting data-structures enums enumeration

public static void main(String[] args) {
    // TODO Auto-generated method stub
    sortDates(Arrays.asList(new DAY[]{DAY.MON,DAY.WED,DAY.TUE,DAY.THU,DAY.SUN,DAY.SAT,DAY.FRI}));
}
public static void sortDates(List<DAY> dayList){
    Set<DAY> set = new TreeSet<DAY>(dayList);
    for(DAY day : set)
    {
        System.out.println(day);
    }
}
public enum DAY {
    MON("MONDAY"),TUE("TUESDAY"),WED("WEDNESDAY"),THU("THURSDAY"),FRI("FRIDAY"),SAT("SATURDAY"),SUN("SUNDAY");

    private String m_name;

    DAY(String name) {
        m_name=name;
    }
}

这段代码的输出是: MON TUE 星期三 THU FRI SAT SUN

但我希望输出是这样的 太阳 MON TUE 星期三 THU FRI SAT

这意味着我想自定义排序功能,将星期日移到第一个。

我该怎么做?谢谢你提前。

6 个答案:

答案 0 :(得分:3)

试试这个。

    import java.util.*;

public class SortDays {


     public static void main(String[] args) {
         // TODO Auto-generated method stub
         sortDates(Arrays.asList(new DAY[]{DAY.MON,DAY.WED,DAY.TUE,DAY.THU,DAY.SUN,DAY.SAT}));
     }
     public static void sortDates(List<DAY> dayList){
         Collections.sort(dayList, new Comparator<DAY>() {
                public int compare(DAY day1, DAY day2) {
                    return day1.getWeight() - day2.getWeight();
                }});
         System.out.println("sortedlist is" + dayList.toString());
     }



}

 enum DAY {
     MON("MONDAY", 2) ,TUE("TUESDAY", 3),WED("WEDNESDAY", 4),THU("THURSDAY", 5),FRI("FRIDAY", 6),SAT("SATURDAY", 7),SUN("SUNDAY", 1);

     private String m_name;
     private int m_weight;

     DAY(String name, int weight) {
         m_name=name;
         m_weight = weight;
     }

     public int getWeight() {
         return this.m_weight;
     }
 }

答案 1 :(得分:1)

到目前为止,@ Marco13的答案是最正确的:你需要一个自定义的比较器来强制你的订购。

幸运的是,Google Guava有一个实用工具:Ordering.explicit()。

private static Comparator<DAY> AM_ORD = Ordering.explicit(DAY.Sun, ... DAY.Sat);
private static Comparator<DAY> EU_ORD = Ordering.explicit(DAY.Mon, ... DAY.Sun);

public static void sortDates(List<DAY> dayList, boolean am)
{
    Set<DAY> set = new TreeSet<DAY>(am ? AM_ORD : EU_ORD);
    set.addAll(dayList);
    for (DAY day : set)
    {
        System.out.println(day);
    }
}

答案 2 :(得分:0)

你可以拥有的唯一不变的假设是日子的顺序。我们知道星期一是星期二之后,星期三之后。

public static final void printWeek(Day firstDayOfWeek) {

        Day[] days = Day.values();

        int offset = firstDayOfWeek.ordinal();

        for(int i = 0; i< days.length; i++) {
            System.out.println(days[offset % days.length]);
            offset++;
        }

    }

由于这个原因,您不仅可以在周一或周日创建订单,还可以从一周中的每一天创建订单。

祝你好运。

答案 3 :(得分:0)

以下方法(使用比较器)需要枚举类中的标识符:

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

public class week {

    public static void main(String[] args) {
        Comparator<DAY> myComparator = new Comparator<DAY>() {

            @Override
            public int compare(DAY o1, DAY o2) {
                if (o1.getPrio() == o2.getPrio()) {
                    return 0;
                } else if (o1.getPrio() < o2.getPrio()) {
                    return -1;
                }
                return 1;
            }
        };

        sortDates(Arrays.asList(new DAY[] { DAY.MON, DAY.WED, DAY.TUE, DAY.THU, DAY.FRI, DAY.SUN, DAY.SAT }),
                myComparator);

    }

    public static void sortDates(List<DAY> dayList, Comparator<DAY> comparator) {
        Set<DAY> setd = new TreeSet<DAY>(comparator);
        setd.addAll(dayList);

        Set<DAY> set = new TreeSet<DAY>(dayList);
        for (DAY day : set) {
            System.out.println(day);
        }
        System.out.println("comparator:");
        for (DAY day : setd) {
            System.out.println(day);
        }
    }

    public enum DAY {
        MON("MONDAY", 1), TUE("TUESDAY", 2), WED("WEDNESDAY", 3), THU("THURSDAY", 4), FRI("FRIDAY", 5), SAT("SATURDAY",
                6), SUN("SUNDAY", 0);

        private final String m_name;
        private final int prio;

        DAY(String name, int prio) {
            m_name = name;
            this.prio = prio;
        }

        public int getPrio() {
            return prio;
        }
    }

}

答案 4 :(得分:0)

建议在枚举中添加另一个字段(“优先级”或“权重”) - 仅仅因为它不是必需的,并且不会使维护更容易。相反,您可以创建Comparator,将“星期日”视为第一天:

private static Comparator<DAY> createComparator()
{
    return new Comparator<DAY>()
    {
        @Override
        public int compare(DAY d0, DAY d1)
        {
            if (d0 == DAY.SUN)
            {
                if (d1 == DAY.SUN)
                {
                    return 0;
                }
                else
                {
                    return -1;
                }
            }
            else if (d1 == DAY.SUN)
            {
                return 1;
            }
            return d0.ordinal() - d1.ordinal();
        }
    };
}
public static void sortDates(List<DAY> dayList)
{
    Set<DAY> set = new TreeSet<DAY>(createComparator());
    set.addAll(dayList);
    for (DAY day : set)
    {
        System.out.println(day);
    }
}

答案 5 :(得分:0)

默认情况下,TreeSet将使用提供的对象的自然顺序。对于枚举,这是基于枚举的序数值,并且这是根据枚举值的声明顺序设置的。因此,如果您选择按照要显示的顺序(DAYSUNDAY ...)声明MONDAY枚举,那么自然顺序就是您想要的。

另一种方法是在构造时向TreeSet提供Comparator的实现,然后您可以定义客户订单。在下面的示例中,我为您的DAY枚举添加了一个索引字段,并提供了一个查看索引的比较器。没有必要提供索引,这确实将星期几的顺序与DAY枚举联系起来,这可能是不可取的。

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

public class Question {

    public static void main(final String[] args) {
        // TODO Auto-generated method stub
        sortDates(Arrays.asList(new DAY[] { DAY.MON, DAY.WED, DAY.TUE, DAY.THU,
                DAY.SUN, DAY.SAT, DAY.FRI }));
    }

    public static void sortDates(final List<DAY> dayList) {
        final Set<DAY> set = new TreeSet<DAY>();
        set.addAll(dayList);
        for (final DAY day : set) {
            System.out.println(day);
        }
    }

    public enum DAY implements Comparable<DAY> {
        MON("MONDAY", 1), TUE("TUESDAY", 2), WED("WEDNESDAY", 3), THU(
                "THURSDAY", 4), FRI("FRIDAY", 5), SAT("SATURDAY", 6), SUN(
                "SUNDAY", 0);

        private final String m_name;
        private final int m_index;

        DAY(final String name, final int index) {
            m_name = name;
            m_index = index;
        }

    }

    public static class DAYComparator implements Comparator<DAY> {

        @Override
        public int compare(final DAY o1, final DAY o2) {
            int returnValue = 0;
            if (o1.m_index > o2.m_index) {
                returnValue = 1;
            } else if (o1.m_index < o2.m_index) {
                returnValue = -1;

            }
            return returnValue;
        }

    }
}