将Java ArrayList修剪为具有最新日期的不同行
我有一个将Java ArrayList修剪为具有最新日期的不同行,java,arraylist,Java,Arraylist,我有一个MyData列表,如下所示。 它由多行MyData对象组成。 有一些具有相同的键,但不同的日期和名称 public class MyData { String name; String key; String date; // ... constructor and other codes omitted here } List<MyData> myDataList; 那么修剪结果应该是 *Name* *key* *date* DEF
MyData
列表,如下所示。
它由多行MyData对象组成。
有一些具有相同的键
,但不同的日期
和名称
public class MyData {
String name;
String key;
String date;
// ... constructor and other codes omitted here
}
List<MyData> myDataList;
那么修剪结果应该是
*Name* *key* *date*
DEF 12 2016-10-19
FGH 10 2016-10-18
从算法上来说,最好的方法是什么
注意:我使用的是Java7,不能使用Java8的流特性。(这是针对Android开发的,目前还不支持Java 8) 您可以使用流,请看以下示例:
ArrayList<String> strings = new ArrayList<>();
strings.add("cbab");
strings.add("abab");
strings.add("dabab");
strings.add("ddabab");
Map<Integer, Optional<String>> collect = strings
.stream()
.collect(Collectors.groupingBy(String::length,
Collectors.maxBy(Comparator.comparingInt((c) -> (int) charAt(0)))));
System.out.println(collect);
ArrayList strings=new ArrayList();
字符串。添加(“cbab”);
字符串。添加(“abab”);
字符串。添加(“dabab”);
字符串。添加(“ddabab”);
Map collect=字符串
.stream()
.collect(收集器).groupingBy(字符串::长度,
收集器.maxBy(比较器.comparingit((c)->(int)字符(0 '));
系统输出打印项次(收集);
将
String::length
更改为MyData::key
并将comparator更改为比较日期(Collectors.maxBy((MyData d1,Mydate d2)->d1.getDate().compareTo(d2.getDate())
您可以使用一个HashMap并更新与key相对应的对象,只要该对象是最近的。我让您编写函数来比较两个日期
HashMap<Integer, MyData> trimedData = new HashMap<>();
for (MyData d : myDataList){
MyData dataSaved= trimedData.get(d.key);
if (dataSaved!= null){
if(d.date > dataSaved.data){ // Here use correct method to compare date
trimedData.put(d.key, d);
}
}
else trimedData.put(d.key, key);
}
HashMap trimedData=newhashmap();
对于(MyData d:myDataList){
MyData dataSaved=trimedData.get(d.key);
if(dataSaved!=null){
如果(d.date>dataSaved.data){//这里使用正确的方法来比较日期
trimedData.put(d.key,d);
}
}
否则修剪数据。放置(d键,键);
}
假设您对date
属性使用实际日期类型,则可以执行以下操作:
private Collection<MyData> trim(List<MyData> data) {
Map<String, MyData> result = new HashMap<>();
for (MyData item : data) {
MyData lastItem = result.get(item.getKey());
if (lastItem == null || lastItem.getDate().before(item.getDate())) {
result.put(item.getKey(), item);
}
}
return result.values();
}
private Collection trim(列表数据){
映射结果=新的HashMap();
对于(MyData项:数据){
MyData lastItem=result.get(item.getKey());
如果(item.getDate())之前的(lastItem==null | | lastItem.getDate()){
result.put(item.getKey(),item);
}
}
返回result.values();
}
您可能可以使用streams获得相同的结果。请在投票前告知我此问题是否存在问题。我将对其进行改进,如果不合适,则将其删除。谢谢。您可以按键和日期排序,然后迭代并保留每个“键组”的最后一项.如果两个
MyData
实例具有相同的密钥,那么它们是否被视为相等?(即,您是否覆盖了equals
和hashCode
)不,我没有重写equal或hashcode。但是如果这样做可以提高性能,我不介意这样做。不过,有一件事是,我想保留最新的日期数据。如果你想使用Java Streams,这将是一个重复:谢谢你的答案。的确很好。我支持它。我也喜欢函数本身做这项工作。我也在这里打勾他回答。非常感谢!如果你认为我的问题是合适的,也许你可以帮我投票。我认为它不应该得到-1。谢谢!嗨@Boris,我们可以把集合放回列表吗?找到它,只需新建ArrayList(result.values)
对不起,我不能使用stream。如果你认为我的问题是合适的,也许你可以帮我投票。我认为它不应该得-1。谢谢!我认为你的问题不愚蠢,没有投反对票。我知道你没有投反对票。只是想如果你认为合适的话,你可以帮我投票,将其中和为0。谢谢!
private Collection<MyData> trim(List<MyData> data) {
Map<String, MyData> result = new HashMap<>();
for (MyData item : data) {
MyData lastItem = result.get(item.getKey());
if (lastItem == null || lastItem.getDate().before(item.getDate())) {
result.put(item.getKey(), item);
}
}
return result.values();
}