java - 无法删除列表中的重复项

标签 java algorithm list duplicates

我最近一直在处理具有日期(实际上是字符串)和 ID 的对象列表。日期以这种方式存储在一个字符串中:“yyyy-mm-dd”。 所以我有一个很长的列表(大约 80 000 个元素),看起来像这样:

[{id:"15655454", date:"2014-11-15"}, {id:"15655454", date:"2014-11-15"}, {id:"15655454", date:"2014-11-15"}, {id:"15655454", date:"2014-10-17"}, {id:"15655454", date:"2014-10-17"}, {id:"15655454", date:"2014-10-17"}, {id:"15655454", date:"2014-10-17"}, {id:"15655454", date:"2014-10-17"}, {id:"15655455", date:"2014-09-23"}, ...]

其实就是一个java类,稍微复杂一点,但是全局思路就到这里了。 (实际上它确实不止两个字段,但我认为在这里并不重要)

如您所见,它是按 ID 排序的。

我想做的是: - 如果一个 ID 有多个日期:只保留最新的日期。 - 如果一个 ID 有多个相同的最新日期:全部保留。

到目前为止,这是我尝试过的:

List<Element> results = new ArrayList<Element>();
results.initiateList();

int count = 0;

while(count < results.size()-1) {
    if (results.get(count).getID().equals(results.get(count+1).getID())) {
            String[] dateI = results.get(count).getDate().split("-");
            String[] dateJ = results.get(count+1).getDate().split("-");
            int yearI = Integer.parseInt(dateI[0]);
            int yearJ = Integer.parseInt(dateJ[0]);
            int monthI = Integer.parseInt(dateI[1]);
            int monthJ = Integer.parseInt(dateJ[1]);
            int dayI = Integer.parseInt(dateI[2]);
            int dayJ = Integer.parseInt(dateJ[2]);

            if (results.get(count).getDate()== null) {
                results.remove(count);
                if (count != 0) {
                    count--;
                }
            } else if (results.get(count+1).getDate()== null) {
                results.remove(count+1);
            } else if ( yearI > yearJ ) {
                results.remove(count+1);
            } else if ( yearI < yearJ ) {
                results.remove(count);
                if (count != 0) {
                    count--;
                }
            } else if ( yearI == yearJ && monthI > monthJ ) {
                results.remove(count+1);
            } else if ( yearI == yearJ && monthI < monthJ ) {
                results.remove(count);
                if (count != 0) {
                    count--;
                }
            } else if ( yearI == yearJ && monthI == monthJ && dayI > dayJ ) {
                results.remove(count+1);
            } else if ( yearI == yearJ && monthI == monthJ && monthI < monthJ ) {
                results.remove(count);
                if (count != 0) {
                    count--;
                }
            } else if ( yearI == yearJ && monthI == monthJ && dayI == dayJ ) {
                count++;
            }
        } else {
            count++;
        }


    }

但这行不通,我不明白为什么。我觉得我已经考虑了所有可能的情况,但仍然没有删除所有重复项。问题是我仍然有一些重复项,例如,该列表仍将包含一个 ID 的多个不同日期。

方法 initiateList()、getDate() 和 getID() 得到了正确的实现,因为我在许多其他不同的地方使用它们,并且它们在那里工作得很好。 InitiateList() 将所有元素放入列表中,如果我尝试在控制台上显示它们,它会正常工作。

我看不出 while 循环有什么问题,但我想我错过了一些东西(这可能是非常基本的......)

最佳答案

我认为尝试与相邻元素进行比较是错误的,因为它们不一定具有相同的 id。也许您应该通过在收集器中使用 groupBy 来尝试不同的方法,比如这样

 public List<Element> removeDuplicates(List<Element> theList) {
    // Getting a map where key is an id of element and the list is all the elements with the same id
    Map<String, List<Element>> theData = theList.stream().collect(Collectors.groupingBy(elem -> elem.getId()));

    List<Element> result = new ArrayList<>();
    //Now we go over the map and from each list we take the element with newes date
    theData.forEach((id, elementsList) -> {
        Element elementWithNewstDate = getNewest(elementsList);
        result.add(elementWithNewstDate);
    });

    return result;
}

private Element getNewest(List<Element> elementsList) {
    // Sorting by newest date
    elementsList.sort(Comparator.comparing(element -> getDateFromElement(element)));
    //Taking the first one becouse it supose to be the newst if i am wrong take the last element
    return elementsList.get(0);
}

private Date getDateFromElement(Element element) {
    Date result = null;
    try {
        result = new SimpleDateFormat("yyyy-MM-dd").parse(element.getDate());
    } catch (ParseException e) {
        e.printStackTrace();
    }
    return result;
}

请注意,它不是 100% 正确,但作为示例应该有所帮助

关于java - 无法删除列表中的重复项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44516673/

相关文章:

java - 将轴标签和标题添加到简单的折线图/图表

java - 将图像移动到 JFrame 上单击的光标位置

python - 计算机代数软件,用于最小化一组多项式中的运算次数

python - 如何在使用python匹配条件后从列表的开始迭代开始for循环

python - 遍历列表列表并使用迭代器

java - 将 map 拆分为两个列表

java - 获取 .com 域名 whois.verisign-grs.com 的 Whois 数据

java - Algo 获取 Integer.MAX_VALUE 的超时

algorithm - 结合了 mergeSort 和 heapsort 的算法的运行时间是多少?

python - 将txt文件读入列表Python