我最近一直在处理有日期(实际上是字符串)和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循环有什么问题,但我想我错过了一些东西(而且它可能非常基本......)
答案 0 :(得分:2)
我认为尝试与邻居元素进行比较是错误的,因为没有必要这两个具有相同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%正确,但它应该有帮助作为一个例子
答案 1 :(得分:1)
您正在进行不必要的比较。您可以使用以下代码段将字符串转换为日期。
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()的输出来决定更高/更低的日期。您可以减少代码并进行调试。