Java 排序字符串数组列表时出现问题

Java 排序字符串数组列表时出现问题,java,Java,可能重复: 我有一个从文件中读取的字符串数组列表,每个字符串的第一部分是日期,例如:12/01/2012。当我使用Collections.sort()时;它在一年内从最老的到最新的分类都很好,但到了2013年1月1日,它将其与最老的一起排在榜首。我怎样才能把年份作为分类的一部分呢?我试着用Date,但效果也一样。每个字符串都有很多信息,我想保存在其中,并按开头进行排序。我认为没有必要发布代码,因为它正在工作,我遇到的问题只是排序。我在这里搜索了一段时间,并尝试了一些不同的排序选项,但没有结果。

可能重复:


我有一个从文件中读取的字符串数组列表,每个字符串的第一部分是日期,例如:12/01/2012。当我使用Collections.sort()时;它在一年内从最老的到最新的分类都很好,但到了2013年1月1日,它将其与最老的一起排在榜首。我怎样才能把年份作为分类的一部分呢?我试着用Date,但效果也一样。每个字符串都有很多信息,我想保存在其中,并按开头进行排序。我认为没有必要发布代码,因为它正在工作,我遇到的问题只是排序。我在这里搜索了一段时间,并尝试了一些不同的排序选项,但没有结果。所以我一定是糊涂了或者忘了什么。如果任何人有任何想法如何排序字符串与日期在开始,请帮助!谢谢


字符串示例:“12/01/2012 34023843项目编号”

如果字符串的格式始终相同,则可以实现自定义并使用Collections.sort(列表、比较器) 该比较器将首先检查年、月、日


或者,(最好的解决方案ahma),您可以重新设计一个包含多个字段(和日期)的对象列表,并使用日期实现一个比较器。直接使用字符串永远不会保存(例如,这里使用字符串上的比较器,您将无法使用其他日期格式)

如果字符串总是相同的格式,您可以实现自定义并使用集合。排序(列表,比较器) 该比较器将首先检查年、月、日


或者,(最好的解决方案ahma),您可以重新设计一个包含多个字段(和日期)的对象列表,并使用日期实现一个比较器。直接使用字符串永远不会保存(例如,这里使用字符串上的比较器,您将无法使用其他日期格式)

您当前正在使用字符串排序进行排序。这意味着“01/01/2013”排序在“12/31/2012”之前,因为“0”小于“1”

您可以使用一个来使用不同的逻辑。在比较器中,您将:

  • 拆分字符串以仅获取日期
  • 使用SimpleDataFormat将字段0转换为日期
  • 然后在两次约会时打电话给compare

  • 您当前正在使用字符串排序进行排序。这意味着“01/01/2013”排序在“12/31/2012”之前,因为“0”小于“1”

    您可以使用一个来使用不同的逻辑。在比较器中,您将:

  • 拆分字符串以仅获取日期
  • 使用SimpleDataFormat将字段0转换为日期
  • 然后在两次约会时打电话给compare

  • 您需要一个自定义比较器。按自然顺序比较字符串(即使用
    String
    实现
    compariable
    )将得到您看到的结果,因为
    0
    低于
    1
    ,所以这是意料之中的

    下面是一个示例类,它可以执行您想要的操作,但请注意,它假定所有日期的格式都正确(如果日期不正确,
    DateFormat
    parse()
    方法抛出一个未选中的
    IllegalArgumentException
    ):

    公共最终类MyComparator
    执行比较器
    {
    //日期解析
    //注意:SimpleDataFormat不是线程安全的,如果可能,请使用Joda Time
    私有静态最终日期格式fmt=新的SimpleDataFormat(“dd/MM/YYYY”);
    private static final Comparator实例=new MyComparator();
    私人MyCompariator()
    {
    }
    公共静态比较器getInstance()
    {
    返回实例;
    }
    @凌驾
    公共整数比较(字符串o1、字符串o2)
    {
    //抓取日期
    字符串s1=o1.子字符串(0,10);
    日期d1=fmt.parse(s1);
    字符串s2=o2.子字符串(0,10);
    日期d2=fmt.parse(s2);
    //日期实现可比较,所以我们可以使用。。。
    int ret=d1。与(d2)相比;
    //如果日期相等,则比较其余字符串。
    return ret!=0?ret:o1.子串(10).比较(o2.子串(10));
    }
    }
    

    然后可以使用集合.sort(数组,MyComparator.getInstance())

    您需要一个自定义比较器。按自然顺序比较字符串(即使用
    String
    实现
    compariable
    )将得到您看到的结果,因为
    0
    低于
    1
    ,所以这是意料之中的

    下面是一个示例类,它可以执行您想要的操作,但请注意,它假定所有日期的格式都正确(如果日期不正确,
    DateFormat
    parse()
    方法抛出一个未选中的
    IllegalArgumentException
    ):

    公共最终类MyComparator
    执行比较器
    {
    //日期解析
    //注意:SimpleDataFormat不是线程安全的,如果可能,请使用Joda Time
    私有静态最终日期格式fmt=新的SimpleDataFormat(“dd/MM/YYYY”);
    private static final Comparator实例=new MyComparator();
    私人MyCompariator()
    {
    }
    公共静态比较器getInstance()
    {
    返回实例;
    }
    @凌驾
    公共整数比较(字符串o1、字符串o2)
    {
    //抓取日期
    字符串s1=o1.子字符串(0,10);
    日期d1=fmt.parse(s1);
    字符串s2=o2.子字符串(0,10);
    日期d2=fmt.parse(s2);
    //日期实现可比较,所以我们可以使用。。。
    int ret=d1。与(d2)相比;
    //如果日期相等,则比较其余字符串。
    return ret!=0?ret:o1.子串(10).比较(o2.子串(10));
    }
    }
    

    然后可以使用集合.sort(数组,MyComparator.getInstance())

    @fge的答案有效,但比较器必须多次拆分和转换字符串。事实上,对于典型的排序算法,这需要执行
    O(NlogN)
    次,其中
    N
    是len
    public final class MyComparator
        implements Comparator<String>
    {
        // Date parsing
        // Note: SimpleDateFormat is not thread-safe, if possible use Joda Time instead
        private static final DateFormat fmt = new SimpleDateFormat("dd/MM/YYYY");
    
        private static final Comparator<String> INSTANCE = new MyComparator();
    
        private MyComparator()
        {
        }
    
        public static Comparator<String> getInstance()
        {
            return INSTANCE;
        }
    
        @Override
        public int compare(String o1, String o2)
        {
            // Grab dates
            String s1 = o1.subString(0, 10);
            Date d1 = fmt.parse(s1);
            String s2 = o2.subString(0, 10);
            Date d2 = fmt.parse(s2);
    
            // Date implements Comparable<Date>, so we can use that...
            int ret = d1.compareTo(d2);
    
            // If dates are equal, compare the rest of the strings instead.
            return ret != 0 ? ret : o1.subString(10).compareTo(o2.subString(10));
        }
    }