您好我需要获取Map
中包含的最新日期的ID。
ID是唯一的Long
数字,用于标识日期。
Map<Long, Date> mapRetrieveMostRecent= new HashMap<Long, Date>();
我用这种方式填充了地图:
mapRetrieveMostRecent.put(id, xDate);
我知道TreeMap
可以自动插入按日期排序的对象,但在我的情况下,日期并不是唯一的。
有什么建议吗?
答案 0 :(得分:3)
如果您要查找最大日期的关键字,可以使用以下单行
Long keyMax = Collections.max(mapRetrieveMostRecent.entrySet(), Map.Entry.comparingByValue()).getKey();
答案 1 :(得分:1)
如果可行,您可以在O(n)中迭代地图中的值:
Map<Long, Date> mapRetrieveMostRecent= new HashMap<Long, Date>();
Date mostRecent = null;
for( Date d : mapRetrieveMostRecent.values())
{
if( mostRecent == null || d.after( mostRecent))
mostRecent = d;
}
答案 2 :(得分:1)
如果你使用的是Java8,我会利用这样的Comparable扩展:
public static <K, V extends Comparable<? super V>> Map<K, V> sortByValue( Map<K, V> map ){
List<Map.Entry<K, V>> l = new LinkedList<>( map.entrySet() );
Collections.sort(l, new Comparator<Map.Entry<K, V>>()
{
@Override
public int compare( Map.Entry<K, V> one, Map.Entry<K, V> another )
{
return (one.getValue()).compareTo( another.getValue() );
}
} );
Map<K, V> r = new LinkedHashMap<>();
for (Map.Entry<K, V> item : l)
{
r.put( item.getKey(), item.getValue() );
}
return r;
}
当我得到这个解决方案时,我正在尝试Stream课程:
Map<Long, Date> mapRetrieveMostRecent= new HashMap<>();
Calendar cal = Calendar.getInstance();
mapRetrieveMostRecent.put(1l, cal.getTime());
cal.add(Calendar.DAY_OF_MONTH, -1);
mapRetrieveMostRecent.put(2l, cal.getTime());
cal.add(Calendar.DAY_OF_MONTH, 4);
mapRetrieveMostRecent.put(3l, cal.getTime());
Map<Long, Date> mapRetrieveMostRecentOrdered = sortMap(mapRetrieveMostRecent);
System.out.println("Sorted Map Ascending: " + Arrays.toString(mapRetrieveMostRecentOrdered.entrySet().toArray()));
public static <K, V extends Comparable<? super V>> Map<K,V> sortMap( Map<K,V> map){
return map.entrySet().stream()
.sorted(Map.Entry.comparingByValue())
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
(e1, e2) -> e2, LinkedHashMap::new));
}
相应的测试:
@Test
public void testSortByValue()
{
int testSize = 50;
Random random = new Random(System.currentTimeMillis());
Map<Long, Date> testMap = new HashMap<>(testSize);
for(long i = 0 ; i < testSize ; ++i) {
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DAY_OF_MONTH, random.nextInt());
testMap.put(i, cal.getTime());
}
testMap = TenaTest.sortByValue( testMap );//Using compare
//testMap = TenaTest.sortMap( testMap );//Using streams
Assert.assertEquals( testSize, testMap.size() );
Date previous = null;
for(Map.Entry<Long, Date> entry : testMap.entrySet()) {
Assert.assertNotNull( entry.getValue() );
if (previous != null) {
Assert.assertTrue( entry.getValue().after(previous) );
}
previous = entry.getValue();
}
}
答案 3 :(得分:1)
在您的情况下,TreeMap
将按id
排序,因为它会对键进行排序,而不是值。
由于您的Date
个对象是值,您可能需要迭代地图,直到找到最新的Date
。
这是一个长期的例子,它迭代条目集并检索最新Date
的ID。
请注意,Date
的ID不是唯一的,如果您有多个,则可能会获得最新Date
的一个的ID与其他人相比,Date
是平等且最新的。
// your map
Map<Long, Date> map = new HashMap<Long, Date>();
// putting values
map.put(0l, new Date());
// putting values
map.put(0l, new Date(0l));
map.put(1l, new Date(1l));
map.put(2l, new Date(2l)); // this will be the most recent
Date latest = null;
Long latestID = null;
// iterating entry set
for (Map.Entry<Long, Date> entry : map.entrySet()) {
Date value = entry.getValue();
Long key = entry.getKey();
// initial comparison
if (latest == null) {
latest = value;
latestID = key;
continue;
}
// further comparisons
if (value.after(latest)) {
latest = value;
latestID = key;
}
}
System.out.println(latestID); // will print 2
答案 4 :(得分:1)
您可以使用比较器流式传输条目并获得最大值:
Map<Long, Date> mapRetrieveMostRecent = new HashMap<Long, Date>();
mapRetrieveMostRecent.entrySet().stream()
.max(Entry::comparingByValue)
.map(Entry::getKey)
.orElse([default value here]);
答案 5 :(得分:0)
我知道
TreeMap
可以自动插入按日期排序的对象 但就我而言,日期并不是唯一的。有什么建议吗?
一种选择可能是使用 Google Guava 中的TreeMultimap
,它会像TreeMap
一样对其键进行排序,并接受重复值,以使其适用于您的情况你必须将键和值反转为下一个:
// Create my map
TreeMultimap<Date, Long> mapRetrieveMostRecent = TreeMultimap.create();
...
// Put an entry into my map
mapRetrieveMostRecent.put(xDate, id);
...
// Get all the ids corresponding to the most recent date
Collection<Long> ids = mapRetrieveMostRecent.asMap().lastEntry().getValue();
使用此方法,您将获得与最新 Date
相对应的所有ID ,因为您可以将多个ID匹配到同一Date
以下是使用Stream API在 Java 8 中完成的方法:
Collection<Long> ids = mapRetrieveMostRecent.entrySet().stream()
.collect(Collectors.groupingBy(Map.Entry::getValue, TreeMap::new, toList()))
.lastEntry()
.getValue()
.stream()
.map(Map.Entry::getKey)
.collect(toList());