Java-如何从时间戳集合中删除重复项?

时间:2019-04-24 11:48:04

标签: java collections java-7

我有一个以毫秒为单位的时间戳列表,我想比较它们并删除不考虑毫秒部分的重复项。并处理每个唯一值。

例如,如果比较private void menuItemPropertyExpanderCollapse_Click(object sender, RoutedEventArgs e) { foreach (GroupItem gi in FindVisualChildren<GroupItem>(PropertyChangeList)) gi.Tag = false; } private static IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject { if (depObj != null) { for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++) { DependencyObject child = VisualTreeHelper.GetChild(depObj, i); if (child != null && child is T) { yield return (T)child; } foreach (T childOfChild in FindVisualChildren<T>(child)) { yield return childOfChild; } } } } <Expander Header="{Binding Name}" IsExpanded="{Binding Tag, RelativeSource={RelativeSource AncestorType=GroupItem}, TargetNullValue=true, FallbackValue=true}"> <ItemsPresenter /> </Expander> 而不截短毫秒部分(millis2millis3),则它们是不同的值。但是我需要忽略毫秒,如果将两个值截断为秒比较,它们将被视为重复。

因此,我决定创建一个时间戳列表,并以相反的顺序对其进行排序。然后遍历集合,检查截断值是否不相等。并将唯一值添加到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)
}

但是我希望在重复数据删除之后仅保留dedupedDeduped timestamps -> 1557023294200 1557023294100 1557023294100 1557023292000 1557023292000 1554052261000 1557023294。 我在这里想念什么?

1 个答案:

答案 0 :(得分:4)

如果可以使用Java 8,则可以使用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

相关问题