2017-04-03 141 views
0

基本上我有有一个名字且StartDate对象的ArrayList打印名单,他们是在一个类似的初始目的是:无法弄清楚如何在这个正确的顺序

弗兰克一九九零年十月二十○日

比尔1990年1月2日

弗兰克·1990年2月2日

约翰·1990年9月8日

比尔1990年4月4日

弗兰克·1990年5月1日

我试图把它们打印在声明的第一个名字的顺序,然后按日期,例如,最终印刷应打印:

弗兰克·1990年1月1日

弗兰克·1990年5月1日

弗兰克一九九零年十月二十零日

比尔1990年1月2日

比尔·1990年4月4日

约翰·1990年9月8日

+0

*“我试图按照声明的名字和按日期的顺序将它们打印出来”* - 到目前为止您尝试了什么? – MadProgrammer

+0

你有两个基本问题,都是以前解决过的。首先是,如何排序表示日期的'String',以及如何根据多于一个属性对对象进行排序 – MadProgrammer

+0

我已经为您的问题添加了两种不同的解决方案来回答我的问题,因为我不确定您正是想要的。也许你可以澄清这一点。 – JDC

回答

1

假设你对象类看起来是这样的:

private static class MyObject { 

    private final String name; 
    private final Date date; 

    private MyObject(String name, Date date) { 
    this.name = name; 
    this.date = date; 
    } 

    public String getName() { 
    return name; 
    } 

    public Date getDate() { 
    return date; 
    } 
} 

你可以通过下面的方法打印对象:

@Test 
public void printInOrder() { 
    List<MyObject> list = new ArrayList<>(); // List containing your objects 
    list.add(new MyObject("Frank", Date.from(LocalDate.of(1990, 10, 20).atStartOfDay(ZoneId.systemDefault()).toInstant()))); 
    list.add(new MyObject("Bill", Date.from(LocalDate.of(1990, 1, 2).atStartOfDay(ZoneId.systemDefault()).toInstant()))); 
    list.add(new MyObject("Frank", Date.from(LocalDate.of(1990, 2, 2).atStartOfDay(ZoneId.systemDefault()).toInstant()))); 
    list.add(new MyObject("John", Date.from(LocalDate.of(1990, 9, 8).atStartOfDay(ZoneId.systemDefault()).toInstant()))); 
    list.add(new MyObject("Bill", Date.from(LocalDate.of(1990, 4, 4).atStartOfDay(ZoneId.systemDefault()).toInstant()))); 
    list.add(new MyObject("Frank", Date.from(LocalDate.of(1990, 5, 1).atStartOfDay(ZoneId.systemDefault()).toInstant()))); 

    list.stream() 
     .sorted(Comparator.comparing(MyObject::getName) 
         .thenComparing(Comparator.comparing(MyObject::getDate))) 
     .map(obj -> obj.getName() + " " + obj.getDate()) 
     .forEach(System.out::println); 
} 

输出:

比尔星期二00年1月2日: 00:00 CET 1990
Bill Wed Apr 04 00:00:00 CEST 1990
弗兰克周五年2月2日00:00:00 CET 1990年
弗兰克周二05月01日00:00:00 CEST 1990年
弗兰克周六10月20日00:00:00 CET 1990年
约翰周六九月08 00:00:00 CEST 1990年


这使用Java 8流和比较链到你的对象进行排序。比较器通过给定的属性进行比较,thenComparing用于链接它们。


UPDATE:

由于我不知道如果我可能误解了你,这里是以下情况下的第二个版本:

你想以按名称排序,但在订单名称出现在原始列表中,因此名称首先出现在第一位。

在这种情况下,您必须记住单独的临时列表中的名称顺序(只包含原始顺序中的唯一名称),以后可以在比较器中使用它们。

此列表是通过将原始列表转换为集合(因此只有唯一名称)并将该集合转换回列表(以便能够在比较器中使用indexOf)生成的。

@Test 
public void printInOrder() { 
    List<MyObject> list = new ArrayList<>(); 
    list.add(new MyObject("Frank", Date.from(LocalDate.of(1990, 10, 20).atStartOfDay(ZoneId.systemDefault()).toInstant()))); 
    list.add(new MyObject("Bill", Date.from(LocalDate.of(1990, 1, 2).atStartOfDay(ZoneId.systemDefault()).toInstant()))); 
    list.add(new MyObject("Frank", Date.from(LocalDate.of(1990, 2, 2).atStartOfDay(ZoneId.systemDefault()).toInstant()))); 
    list.add(new MyObject("John", Date.from(LocalDate.of(1990, 9, 8).atStartOfDay(ZoneId.systemDefault()).toInstant()))); 
    list.add(new MyObject("Bill", Date.from(LocalDate.of(1990, 4, 4).atStartOfDay(ZoneId.systemDefault()).toInstant()))); 
    list.add(new MyObject("Frank", Date.from(LocalDate.of(1990, 5, 1).atStartOfDay(ZoneId.systemDefault()).toInstant()))); 

    List<String> declaredNameOrder = new ArrayList<>(list.stream() 
             .map(MyObject::getName) 
             .collect(Collectors.toCollection(LinkedHashSet::new))); 

    list.stream() 
     .sorted(Comparator.<MyObject>comparingInt(o -> declaredNameOrder.indexOf(o.getName())) 
        .thenComparing(Comparator.comparing(MyObject::getDate))) 
     .map(obj -> obj.getName() + " " + obj.getDate()) 
     .forEach(System.out::println); 
} 

输出:

弗兰克周五年2月2日00:00:00 CET 1990年
弗兰克周二05月01日00:00:00 CEST 1990年
弗兰克周六10月20日00:00:00 CET 1990年
比尔星期二1月2日00:00:00 CET 1990年
比尔周三4月4日00:00:00 CEST 1990年
约翰周六九月08 00:00:00 CEST 1990年

0

你应该做的两个步骤:

Collections.sort(myList, new Comparator<MyObject>() { 
     public int compare(MyObject o1, MyObject o2) { 
      return o1.getName().compareTo(o2.getName()); 
     } 
    }); 

和存储:按名称使用自定义比较喜欢

一阶

:在一个临时列表输出

二使用临时列表中的数据进行排序

然后您的列表将按您的要求排序。

+0

这不是按字母顺序排列吗?我无法弄清楚如何使用首先声明的名字打印所有对象,而不是按字母顺序排列 –