【问题标题】:How to customize sort of Set in Java如何在 Java 中自定义 Set 类型
【发布时间】:2014-04-09 09:36:34
【问题描述】:
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;
    }
}

这段代码的输出是: 星期一 周二 星期三 周四 周五 SAT 孙

但我希望输出是这样的 太阳 星期一 周二 星期三 周四 周五 SAT

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

我该怎么做?提前致谢。

【问题讨论】:

  • 你能把它定义为树形图并将键分配为可排序字段吗?
  • 出于好奇:你为什么跳过星期五? hack:重新排序您枚举DAY中的天数声明相应地猜测解决方案:提供自定义Comparator&lt;DAY&gt;并使用Collections.sort(dayList, yourCustomComparator)
  • 对不起,我错过了星期五的错误,我已经编辑了我的问题

标签: java sorting data-structures enums enumeration


【解决方案1】:

试试这个。

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 这应该是答案。好东西greyfairer。
    【解决方案3】:

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

    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】:

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

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

      因此,您不仅可以从周一或周日创建订单,还可以从一周中的每一天创建订单。

      祝你好运。

      【讨论】:

        【解决方案5】:

        建议将另一个字段(“优先级”或“权重”)添加到枚举中 - 仅仅是因为它没有必要并且不会使事情更易于维护。相反,您可以创建一个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);
            }
        }
        

        【讨论】:

          【解决方案6】:

          默认情况下,TreeSet 将使用所提供对象的自然顺序。对于 Enum,这基于枚举的序数值,并且根据声明枚举值的顺序设置。因此,如果您选择按照您希望显示的顺序(SUNDAYMONDAY...)声明 DAY 枚举,那么自然顺序将如您所愿。

          另一种方法是在构造时为 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;
                  }
          
              }
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-06-23
            • 1970-01-01
            • 2013-10-05
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多