Java - 如何从时间戳集合中删除重复项?
Java - how to remove duplicates from a collection of timestamps?
我有一个以毫秒为单位的时间戳列表,我想比较它们并删除不考虑毫秒部分的重复项。并处理每个唯一值。
例如,如果在不截断毫秒部分的情况下进行比较,millis2
和 millis3
是不同的值(2:28:14.100
与 2:28:14.200
)。但是我需要忽略毫秒,如果将两个值截断为秒进行比较,它们将被视为重复项。
所以我决定创建一个时间戳列表,并以相反的顺序对其进行排序。然后遍历集合检查截断值是否不相等。并将唯一值添加到 List<Long> deduped
。
Long millis0 = 1554052261000L; // Sunday, March 31, 2019 5:11:01 PM
Long millis1 = 1557023292000L; // Sunday, May 5, 2019 2:28:12 AM
Long millis2 = 1557023294100L; // Sunday, May 5, 2019 2:28:14.100 AM
Long millis3 = 1557023294200L; // Sunday, May 5, 2019 2:28:14.200 AM
List<Long> initialTimestamps = Arrays.asList(millis2, millis3, millis0, millis1);
Comparator<Long> comparator = Collections.reverseOrder();
Collections.sort(initialTimestamps, comparator);
Long prevTs = null;
List<Long> deduped = new ArrayList<>();
for (Long ts: initialTimestamps) {
if (prevTs != null && !millisToSeconds(prevTs).equals(millisToSeconds(ts))) {
deduped.add(prevTs);
process(prevTs)
}
prevTs = ts;
deduped.add(prevTs);
process(prevTs)
}
但是打印出deduped
的内容时,出现重复:
Deduped timestamps ->
1557023294200
1557023294100
1557023294100
1557023292000
1557023292000
1554052261000
但我预计在去重之后将只剩下1557023294
、1557023292
和1554052261
。
我在这里错过了什么?
如果可以使用java8,那么就可以使用stream().distinct()
:
public static void main(String[] args) throws Exception {
Long millis0 = 1554052261000L; // Sunday, March 31, 2019 5:11:01 PM
Long millis1 = 1557023292000L; // Sunday, May 5, 2019 2:28:12 AM
Long millis2 = 1557023294100L; // Sunday, May 5, 2019 2:28:14.100 AM
Long millis3 = 1557023294200L; // Sunday, May 5, 2019 2:28:14.200 AM
List<Long> initialTimestamps = Arrays.asList(millis2, millis3, millis0, millis1);
List<Long> unique = initialTimestamps.stream().distinct().collect(Collectors.toList());
System.out.println(unique);
}
对于 java < 8,您可以将它们放在 Set
:
public static void main(String[] args) throws Exception {
Long millis0 = 100L; // Sunday, March 31, 2019 5:11:01 PM
Long millis1 = 100L; // Sunday, May 5, 2019 2:28:12 AM
Long millis2 = 200L; // Sunday, May 5, 2019 2:28:14.100 AM
Long millis3 = 200L; // Sunday, May 5, 2019 2:28:14.200 AM
List<Long> initialTimestamps = Arrays.asList(millis2, millis3, millis0, millis1);
Set<Long> unique = new HashSet<Long>(initialTimestamps);
System.out.println(unique);
}
更新
根据您忽略毫秒的要求,您可以使用 Map
(如果您想保留毫秒)或使用上述方法之一,如果您不关心毫秒。在那种情况下,只需将值除以 1_000
public static void main(String[] args) throws Exception {
Long millis0 = 1554052261000L; // Sunday, March 31, 2019 5:11:01 PM
Long millis1 = 1557023292000L; // Sunday, May 5, 2019 2:28:12 AM
Long millis2 = 1557023294100L; // Sunday, May 5, 2019 2:28:14.100 AM
Long millis3 = 1557023294200L; // Sunday, May 5, 2019 2:28:14.200 AM
List<Long> initialTimestamps = Arrays.asList(millis2, millis3, millis0, millis1);
Map<Long, Long> unique = new HashMap<>();
for (Long timestamp : initialTimestamps) {
unique.put(timestamp / 1000, timestamp);
}
System.out.println(unique.values());
}
如果要保留每个副本的第一个值,请使用
if (!unique.containsKey(timestamp / 1000)) {
unique.put(timestamp / 1000, timestamp);
}
而不仅仅是 put()
。如果你想保留所有时间戳的初始顺序,你应该使用 LinkedHashMap
而不是 HashMap
我有一个以毫秒为单位的时间戳列表,我想比较它们并删除不考虑毫秒部分的重复项。并处理每个唯一值。
例如,如果在不截断毫秒部分的情况下进行比较,millis2
和 millis3
是不同的值(2:28:14.100
与 2:28:14.200
)。但是我需要忽略毫秒,如果将两个值截断为秒进行比较,它们将被视为重复项。
所以我决定创建一个时间戳列表,并以相反的顺序对其进行排序。然后遍历集合检查截断值是否不相等。并将唯一值添加到 List<Long> deduped
。
Long millis0 = 1554052261000L; // Sunday, March 31, 2019 5:11:01 PM
Long millis1 = 1557023292000L; // Sunday, May 5, 2019 2:28:12 AM
Long millis2 = 1557023294100L; // Sunday, May 5, 2019 2:28:14.100 AM
Long millis3 = 1557023294200L; // Sunday, May 5, 2019 2:28:14.200 AM
List<Long> initialTimestamps = Arrays.asList(millis2, millis3, millis0, millis1);
Comparator<Long> comparator = Collections.reverseOrder();
Collections.sort(initialTimestamps, comparator);
Long prevTs = null;
List<Long> deduped = new ArrayList<>();
for (Long ts: initialTimestamps) {
if (prevTs != null && !millisToSeconds(prevTs).equals(millisToSeconds(ts))) {
deduped.add(prevTs);
process(prevTs)
}
prevTs = ts;
deduped.add(prevTs);
process(prevTs)
}
但是打印出deduped
的内容时,出现重复:
Deduped timestamps ->
1557023294200
1557023294100
1557023294100
1557023292000
1557023292000
1554052261000
但我预计在去重之后将只剩下1557023294
、1557023292
和1554052261
。
我在这里错过了什么?
如果可以使用java8,那么就可以使用stream().distinct()
:
public static void main(String[] args) throws Exception {
Long millis0 = 1554052261000L; // Sunday, March 31, 2019 5:11:01 PM
Long millis1 = 1557023292000L; // Sunday, May 5, 2019 2:28:12 AM
Long millis2 = 1557023294100L; // Sunday, May 5, 2019 2:28:14.100 AM
Long millis3 = 1557023294200L; // Sunday, May 5, 2019 2:28:14.200 AM
List<Long> initialTimestamps = Arrays.asList(millis2, millis3, millis0, millis1);
List<Long> unique = initialTimestamps.stream().distinct().collect(Collectors.toList());
System.out.println(unique);
}
对于 java < 8,您可以将它们放在 Set
:
public static void main(String[] args) throws Exception {
Long millis0 = 100L; // Sunday, March 31, 2019 5:11:01 PM
Long millis1 = 100L; // Sunday, May 5, 2019 2:28:12 AM
Long millis2 = 200L; // Sunday, May 5, 2019 2:28:14.100 AM
Long millis3 = 200L; // Sunday, May 5, 2019 2:28:14.200 AM
List<Long> initialTimestamps = Arrays.asList(millis2, millis3, millis0, millis1);
Set<Long> unique = new HashSet<Long>(initialTimestamps);
System.out.println(unique);
}
更新
根据您忽略毫秒的要求,您可以使用 Map
(如果您想保留毫秒)或使用上述方法之一,如果您不关心毫秒。在那种情况下,只需将值除以 1_000
public static void main(String[] args) throws Exception {
Long millis0 = 1554052261000L; // Sunday, March 31, 2019 5:11:01 PM
Long millis1 = 1557023292000L; // Sunday, May 5, 2019 2:28:12 AM
Long millis2 = 1557023294100L; // Sunday, May 5, 2019 2:28:14.100 AM
Long millis3 = 1557023294200L; // Sunday, May 5, 2019 2:28:14.200 AM
List<Long> initialTimestamps = Arrays.asList(millis2, millis3, millis0, millis1);
Map<Long, Long> unique = new HashMap<>();
for (Long timestamp : initialTimestamps) {
unique.put(timestamp / 1000, timestamp);
}
System.out.println(unique.values());
}
如果要保留每个副本的第一个值,请使用
if (!unique.containsKey(timestamp / 1000)) {
unique.put(timestamp / 1000, timestamp);
}
而不仅仅是 put()
。如果你想保留所有时间戳的初始顺序,你应该使用 LinkedHashMap
而不是 HashMap