2017-06-13 37 views
0

最近我一直在處理有日期(實際上是字符串)和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()把所有的元素放在列表中,如果我試圖在控制檯上顯示它們,它可以正常工作。

我看不出有什麼不對的,而循環,但我想我錯過了一些東西(它可能是非常基本的...)

+2

嘗試使用調試器。並逐步查看它。創建一個代碼失敗的小例子(並將其添加到您的問題中)。 – MrSmith42

+0

是你能夠使用一個集合,爲什麼不實現equals,compareTo和使用Collections方法??? –

+2

考慮使用'Map'來存儲你的''''''''''''對。如果存在'id',那麼檢查'date'是否是最新的 - 是的,存儲它,否則忽略。此外,解析你的日期像'LocalDate',讓生活更輕鬆。 – Abubakkar

回答

2

我想嘗試比較相鄰元素是錯誤的,因爲它是沒有必要的兩者具有相同id.Maybe你應該在收藏家使用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%正確的,但它應該有助於作爲示例

+0

你的第一個短語錯了 - 列表按ID排序 –

+0

你是對的沒有注意到 – urag

+0

非常感謝。現在它工作正常。我不得不修改一下getNewest(),以便它可以返回一個列表(因爲我可以有幾個日期等於最新的日期,在這種情況下,我將它們全部保留),但這很容易從你的工作中得到。我對比較器不太好,這是如何使用它的一個很好的例子。 – kazu

1

你正在做不必要的comparisions。您可以使用下面的代碼片段將字符串轉換爲日期。

String sDate1="2014-11-15"; 
    Date date1=new SimpleDateFormat("yyyy-MM-dd").parse(sDate1); 
    System.out.println("Date : "+date1); 
    System.out.println("Date value :"+date1.getTime()); 

您可以比較相應日期的輸出getTime()來決定更高/更低的日期。然後你可以減少你的代碼和調試。

+0

實際上字符串可以直接比較,如果格式爲'yyyy-MM-dd' –