2016-09-07 4 views
0

こんにちは、私はMapに含まれている最新の日付のIDを取得する必要があります。地図で最新の日付を取得するには<Long, Date>?

idは、日付を識別する一意のLongです。

Map<Long, Date> mapRetrieveMostRecent= new HashMap<Long, Date>(); 

私はこの方法でマップを埋め:

mapRetrieveMostRecent.put(id, xDate); 

を私はTreeMapが自動的に日付によるソートが、私の場合には、日付が一意ではないオブジェクトを挿入できることを知っています。 提案がありますか?

+0

Java 8を使用していますか? –

+0

はい私は@FranciscoTena – user2298581

+0

ですが、同じ最大日付のキーのリストが必要ですか? –

答えて

0

私はTreeMapを自動的に挿入することができることを知っては、日付によるソートオブジェクト が、私の場合は日付が一意ではありません。助言がありますか?

一つの選択肢は、グーグルグアバから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(); 

このアプローチでは、あなたが同じに一致する複数のIDを持つことができるよう、最新のDateに対応するすべてのIDを取得します。ここで


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()); 
1

それはあなたのために実現可能だ場合は、O(n)の中でマップの値を反復処理することができます:あなたがJava8を使用している場合

Map<Long, Date> mapRetrieveMostRecent= new HashMap<Long, Date>(); 
Date mostRecent = null; 
for(Date d : mapRetrieveMostRecent.values()) 
{ 
    if(mostRecent == null || d.after(mostRecent)) 
     mostRecent = d; 
} 
+0

ニース!このようにして、私は最も最近の日付を持っていますが、私はどのようにして彼のIDキーにマップでアクセスできますか? (不幸にも私の日付は一意ではありません) – user2298581

+0

このようなキーセットを反復することができます:\t mapRetrieveMostRecent = new HashMap (); \t日付mostRecent = null、現在; \t long mostRecentId = -1;用 \t(長いID:mapRetrieveMostRecent.keySet()) \t {\t \t電流= mapRetrieveMostRecent.get(ID)。 \t if(mostRecent == null || current.after(mostRecent)) \t { \t \t mostRecent = current; \t \t mostRecentId = id; \t} \t} – uoyilmaz

+0

これは完璧です! "MostRecent = null、current;日付" の末尾に "MostRecent"という文字列の意味を説明することはできますか?どのように変数が2つの異なる値を持つことは可能ですか? ありがとうございました! @uoyilmaz – user2298581

1

私はこのような比較可能な拡張機能を利用します:

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(); 
    } 
} 
0

を、それはソートするので、TreeMapは、idでソートうキーではなく、値です。

Dateオブジェクトは値であるため、最新のDateが見つかるまで地図を反復することができます。

ここでは、エントリセットを反復し、最新のDateのIDを取得するlong-ishの例を示します。あなたが他の人に比べて等しく、最も最近のある複数のDate秒を持っている場合は、id Date sが固有のものではないことを

注意、あなたは、最新のDate秒ののIDを取得することができます。

// 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 
+0

コードにsleepを追加するのではなく、新しいDate(long)のような他のコンストラクタを使用することを検討してください。 –

+0

@NicolasFilotto原則に同意しますが、これはテスト用です。 OPは実際には異なる「日付」で始まるでしょう。 – Mena

+0

@NicolasFilotto気にせず、あなたが言っているように、それはきれいです - 編集しました。 – Mena

3

あなたが最大の日付のキーを探している場合は、次のワンライナーを使用することができます

Long keyMax = Collections.max(mapRetrieveMostRecent.entrySet(), Map.Entry.comparingByValue()).getKey(); 
1

あなたは、エントリをストリーミングし、コンパレータを使用して、最大を取得できます。

Map<Long, Date> mapRetrieveMostRecent = new HashMap<Long, Date>(); 
mapRetrieveMostRecent.entrySet().stream() 
        .max(Entry::comparingByValue) 
        .map(Entry::getKey) 
        .orElse([default value here]); 
+0

あなたは正しいですが、OPは実際に複数の最大日付の場合に彼が望んでいることを言っていません。 – assylias

関連する問題