Java - 时间排序数组

3

首先:我使用数组存储像这样的信息:

// Tuesday
array[2][1] = "tuesday";
array[2][2] = "20:00";

// Wednesday 
array[3][1] = "Wednesday";
array[3][2] = "15:00";

// Thursday 
array[4][1] = "Thursday";
array[4][2] = "20:00";

// Friday
array[5][1] = "Friday";
array[5][2] = "18:00";

// Saturday
array[6][1] = "Saturday";
array[6][2] = "15:00";

// Sunday
array[7][1] = "Sunday";
array[7][2] = "15:00";

我该如何按实际时间和星期对数组进行排序? 例如:现在是星期三-11:13。第一个数组项将是array[3],然后是4、5、6、7,然后再次是2。
非常感谢。

13
你的代码存在“对象拒绝”异味,这会使得包括你当前遇到的问题在内的所有事情都变得更加困难。Java希望你编写类,不要抗拒。 - Marko Topolnik
今天是德国时间星期三11:35。 3(今天,15:00),4(星期三之后是星期四),5,6,7,2(因为在这个数组中,星期日之后是星期二(没有星期一))。我编辑了我的问题:实际上是时间和星期几。 - user1878413
我倾向于说,数组不是用于此目的的最佳数据结构。 - maloney
难道不能改变保存信息的方式吗?例如,您不能使用Joda Time或XMLGregorianCalendar或自己的对象吗? - iberbeu
可以的iberbeu。目标是要学会的。 :) - user1878413
显示剩余2条评论
5个回答

6
你应该使用Arrays.sort(array,comparator),例如像这样:
Arrays.sort(array, new Comparator<String[]>() {
    public int compareTo(String[] one, String[] two) {
         // implement compareTo here
    }
});

但是,使用二维数组代替自定义类型的一维数组来存储不同的数据是非常不好的做法,例如:

public class DayTime {
    private String day;
    private String time;
    // constructors, setters, getters
}

现在按照以下方式创建数组:
DayTime[] days = new DayTime[] {
    new DayTime("tuesday", "20:00").
    new DayTime("Wednesday", "15:00"),
    // etc, etc
};


Arrays.sort(array, new Comparator<DayTime>() {
    public int compareTo(DayTime one, DayTime two) {
         // implement compareTo here
    }
});

您还可以让DateTime实现Comparable接口。这种情况下,只需调用Arrays.sort(array)即可。

3
class CalendarEntry implements Comparable<CalendarEntry> {
  String entry;
  Date start;

  // constructors, getters, setters

  int compareTo(CalendarEntry o) {
    if (o==null) return 1;
    return start.compareTo(o.start);
  }

}

List<CalendarEntry> entriesList = new ArrayList<CalendarEntry>();
// add contents
Collections.sort(entriesList);
// and you are done

2
这里的其他答案都不错,但使用了过时的类。

java.time

使用Java 8及更高版本,我们现在内置了java.time框架(对于Java 6、7和Android也有后续支持)。它比旧的日期时间类有了巨大的改进。
java.time类包括一对恰好符合您需求的类:
- DayOfWeek:一个方便的枚举,表示每周七天,根据ISO 8601标准从星期一到星期日。 - LocalTime:表示没有日期和时区的时间。
有了这些预定义类型,您甚至不需要像其他评论和答案建议的那样定义自己的类。至少如果您将星期一至星期日作为排序天数的定义。枚举类型DayOfWeek按照那个顺序预定义了一周中的天。如果在您的项目中有意义,您可以结合DayOfWeekLocalTime创建自己的类。

Java 枚举非常方便、灵活和强大(如果您不熟悉它们,请了解更多)。枚举有自己特殊的SetMap实现,分别命名为EnumSetEnumMap。我们可以使用一个EnumMap来跟踪一周中的每一天,将其映射到时间(一个LocalTime对象)。

EnumMap<DayOfWeek , LocalTime> dayToTimeMap = new EnumMap<> ( DayOfWeek.class );

dayToTimeMap.put ( DayOfWeek.TUESDAY , LocalTime.parse ( "20:00" ) );
dayToTimeMap.put ( DayOfWeek.WEDNESDAY , LocalTime.of ( 15 , 0 ) );
dayToTimeMap.put ( DayOfWeek.THURSDAY , LocalTime.parse ( "20:00" ) );
dayToTimeMap.put ( DayOfWeek.FRIDAY , LocalTime.parse ( "18:00" ) );
dayToTimeMap.put ( DayOfWeek.SATURDAY , LocalTime.parse ( "15:00" ) );

获取当前星期几和时间。
DayOfWeek today = DayOfWeek.WEDNESDAY;
LocalTime now = LocalTime.of ( 11 , 13 );

创建一对空集合,一个用于跟踪与今天-现在相同或更晚的日期时间,另一个用于跟踪较早的日期时间。由于它们是EnumSet,因此它们的自然顺序是在DayOfWeek枚举中声明的顺序(星期一至星期日,1-7)。
EnumSet<DayOfWeek> earlier = EnumSet.noneOf ( DayOfWeek.class );
EnumSet<DayOfWeek> later = EnumSet.noneOf ( DayOfWeek.class );

循环遍历 DayOfWeek 到 LocalTime 的映射。查看 DayOfWeek 是否在今天之前、等于今天还是今天之后。如果等于今天,则将其 LocalTime 对象与我们的 now 对象进行比较。将此 DayOfWeek 对象分配给 earlier 集合或 later 集合中的一个。
for ( Map.Entry<DayOfWeek , LocalTime> entry : dayToTimeMap.entrySet () ) {
    DayOfWeek key = entry.getKey ();
    LocalTime value = entry.getValue ();
    int comparison = key.compareTo ( today );
    if ( comparison < 0 ) { // if earlier day…
        earlier.add ( key );
    } else if ( comparison == 0 ) { //If same day…
        if ( value.isBefore ( now ) ) {
            earlier.add ( key );
        } else {  // Else same time as now or later than now…
            later.add ( key );
        }
    } else if ( comparison > 0 ) {
        later.add ( key );
    } else {
        throw new RuntimeException ( "Unexpectedly reached IF-ELSE for comparison: " + comparison );
    }
}

将文本转换为中文:在控制台上输出。我们希望首先循环later集,然后按照问题中的要求循环earlier集。
System.out.println ( "dayToStringMap: " + dayToTimeMap );
System.out.println ( "sorted by today: " + today + " " + now + " is: " );
for ( DayOfWeek dayOfWeek : later ) {
    LocalTime localTime = dayToTimeMap.get ( dayOfWeek );
    System.out.println ( dayOfWeek + " " + localTime );
}
for ( DayOfWeek dayOfWeek : earlier ) {
    LocalTime localTime = dayToTimeMap.get ( dayOfWeek );
    System.out.println ( dayOfWeek + " " + localTime );
}

当运行时。
dayToStringMap: {TUESDAY=20:00, WEDNESDAY=15:00, THURSDAY=20:00, FRIDAY=18:00, SATURDAY=15:00}
sorted by today: WEDNESDAY 11:13 is: 
WEDNESDAY 15:00
THURSDAY 20:00
FRIDAY 18:00
SATURDAY 15:00
TUESDAY 20:00

1
排序本身可以通过使用带有自定义比较器的Arrays.sort来实现。

http://docs.oracle.com/javase/7/docs/api/java/util/Arrays.html

http://docs.oracle.com/javase/7/docs/api/java/util/Comparator.html

public static void main(String[] args) {

  String[][] array = createArray();

  Arrays.sort(array, new Comparator<String[]>() {
    @Override public int compare(String[] o1, String[] o2) {
      String day1 = o1[0];
      String day2 = o2[0];
      String time1 = o1[1];
      String time2 = o2[1];

      // Perform comparison, first of the days, then - if they're
      // identical of the times.
      return ...
    }
  });

}

然而,正如其他评论中所写的那样:我强烈建议您采用更加面向对象的方法来解决问题。


1
不要在此处使用某些你知道但Java不知道的“虚拟类型结构”的数组。使用强类型类建模。实现Comparable以进行排序。然后使用collections - 将对象实例添加到List中并使用其sort方法。
 class Event implements Comparable<Event> {
    String day;
    String time;

    public Event(String day, String time) { this.day = day; this.time = time; }
    public String getDay() { return this.day; }
    public String getTime() { return this.time; }

    @Override
    public boolean equals(Object other) {
        boolean result = false;
        if (other != null && other instanceof Event) {
            Event otherEvent = (Event)other;
            result = this.getDay().equals(otherEvent.getDay()) && 
                     this.getTime().equals(otherEvent.getTime());
        }
        return result;
    }

    @Override
    public int hashCode() {
         return this.getDay().hashCode()*7 + this.getDay().hashCode();
    }

    @Override
    public int compareTo(Event otherEvent) {
        int result = this.getDay().compareTo(otherEvent.getDay());
        if (result == 0) result = this.getTime().compareTo(otherEvent.getTime());
        return result;
    }
}

然后在其他类或主方法中:
List<Event> eventList = new ArrayList<Event>();
eventList.add(new Event("tuesday","20:00"));
eventList.add(new Event("tuesday","20:00"));
// etc

eventList.sort();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接