我有一个看起来或多或少的HashMap:
private HashMap<String, String> fu = new HashMap<String, String>();
fu.put("16:04:00.476", "A");
fu.put("16:09:58.228", "B");
fu.put("16:17:58.227", "C");
fu.put("16:22:42.478", "D");
fu.put("16:27:23.728", "E");
fu.put("16:38:34.977", "F");
fu.put("16:46:46.227", "G");
现在我有另一个名为bar的时间戳,我想找到合适的字母:
private String findLetter(String timestamp) {
return "";
}
HashMap中的时间戳可以视为开始时间。这意味着,A从16:04:00.476开始并持续到B开始。 B持续到C开始,依此类推。现在,此方法应返回作为参数传递的时间戳所在的字母。
我做的第一件事就是将时间戳转换为Date对象以使用Date#after方法来查看它是否在某个开始时间之后,但我怎样才能确保它也在下一次启动之前时间?
答案 0 :(得分:6)
HashMap没有排序,所以首先应该使用TreeMap。然后查看下一个条目,检查它是否在您当前的时间戳之后
答案 1 :(得分:0)
如果您的按键格式没有改变,您只需执行以下操作:
private NavigableMap<String, String> fu = new TreeMap<>();
然后
private String findLetter(String timestamp) {
return map.get(map.lowerKey(timestamp));
}
如果您打算将来更改格式,可以执行以下操作(但必须调整时间格式)
private static final DateFormat DATE_FORMAT = new SimpleDateFormat("HH:mm:ss.SSS");
private NavigableMap<String, String> fu = new TreeMap<>(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
try {
long t1 = DATE_FORMAT.parse(o1).getTime();
long t2 = DATE_FORMAT.parse(o2).getTime();
return Long.compare(t1, t2);
} catch (ParseException e) {
throw new IllegalArgumentException(e);
}
}
});
然后你可以简单地做
private String findLetter(String timestamp) {
return map.get(map.lowerKey(timestamp));
}
答案 2 :(得分:0)
这是基于TreeMap
的简单解决方案,如建议的那样。它假定您显示的所有时间点都在同一天内。
class Sample {
private static final SimpleDateFormat SDF = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.SSS");
private static final String DEFAULT_DAY_PREFIX = "1980-05-15 ";
public static void main(String[] args) throws ParseException {
TreeMap<Long, String> orderedDates = new TreeMap<Long, String>();
orderedDates.put(parseToDate("16:04:00.476"), "A");
orderedDates.put(parseToDate("16:09:58.228"), "B");
orderedDates.put(parseToDate("16:17:58.227"), "C");
System.out.println(orderedDates.floorEntry(parseToDate("16:04:00.500")).getValue());
System.out.println(orderedDates.floorEntry(parseToDate("16:09:58.100")).getValue());
System.out.println(orderedDates.floorEntry(parseToDate("16:09:58.300")).getValue());
System.out.println(orderedDates.floorEntry(parseToDate("16:17:58.300")).getValue());
}
private static long parseToDate(String dayPoint) throws ParseException {
return SDF.parse(DEFAULT_DAY_PREFIX + dayPoint).getTime();
}
}
答案 3 :(得分:0)
如果您已将String
解析为Date
,那么您可以使用唯一一种未弃用的方法getTime()
,这将返回long
代表毫秒。
然后你可以比较这个值,因为0是the Epoch,而我写这个答案是1370548040476
。
答案 4 :(得分:0)
我已经以更方便的方式修改了您的源代码,以向您展示如何正确执行此操作。我会让你按照自己想要的方式进行练习,但IMO可以非常直接地了解如何做到这一点。这使用JodaTime库。
package com.sandbox;
import org.joda.time.DateTime;
import org.joda.time.Interval;
import java.util.ArrayList;
import java.util.List;
public class Sandbox {
public static void main(String[] args) {
List<DateTime> dateTimes = new ArrayList<DateTime>();
dateTimes.add(new DateTime(100000));
dateTimes.add(new DateTime(105000));
dateTimes.add(new DateTime(110000));
dateTimes.add(new DateTime(115000));
dateTimes.add(new DateTime(120000));
List<Interval> intervals = new ArrayList<Interval>();
for (int i = 0; i < dateTimes.size() - 1; i++) {
DateTime start = dateTimes.get(i);
DateTime end = dateTimes.get(i + 1);
intervals.add(new Interval(start, end));
}
assert 0 == findIndex(100000L, intervals);
assert 0 == findIndex(100001L, intervals);
assert 3 == findIndex(115000L, intervals);
assert 3 == findIndex(115001L, intervals);
}
private static Integer findIndex(Long timestamp, List<Interval> intervals) {
DateTime dateTime = new DateTime(timestamp);
for (int i = 0; i < intervals.size(); i++) {
Interval interval = intervals.get(i);
if (interval.contains(dateTime)) {
return i;
}
}
return -1;
}
}
当您考虑@ Thierry的解决方案时,这比您需要的工作更多。但是,如果您的需求发生变化,这些代码可能会更灵活。不过,如果你不认为你的要求会改变,我会先使用他的建议。