Java LinkedHashMap get first or last entry

匿名 (未验证) 提交于 2019-12-03 01:10:02

问题:

I have used LinkedHashMap because it is important the order in which keys entered in the map.

But now I want to get the value of key in the first place (the first entered entry) or the last.

Should there be a method like first() and last() or something like that?

Do I need to have an iterator to just get the first key entry? That is why I used LinkedHashMap!

Thanks!

回答1:

The semantics of LinkedHashMap are still those of a Map, rather than that of a LinkedList. It retains insertion order, yes, but that's an implementation detail, rather than an aspect of its interface.

The quickest way to get the "first" entry is still entrySet().iterator().next(). Getting the "last" entry is possible, but will entail iterating over the whole entry set by calling .next() until you reach the last. while (iterator.hasNext()) { lastElement = iterator.next() }

edit: However, if you're willing to go beyond the JavaSE API, Apache Commons Collections has its own LinkedMap implementation, which has methods like firstKey and lastKey, which do what you're looking for. The interface is considerably richer.



回答2:

Can you try doing something like (to get the last entry):

linkedHashMap.entrySet().toArray()[linkedHashMap.size() -1]; 

it's O(N) :)



回答3:

LinkedHashMap current implementation (Java 8) keeps track of its tail. If performance is a concern and/or the map is large in size, you could access that field via reflection.

Because the implementation may change it is probably a good idea to have a fallback strategy too. You may want to log something if an exception is thrown so you know that the implementation has changed.

It could look like:

public static  Entry getFirst(Map map) {   if (map.isEmpty()) return null;   return map.entrySet().iterator().next(); }  public static  Entry getLast(Map map) {   try {     if (map instanceof LinkedHashMap) return getLastViaReflection(map);   } catch (Exception ignore) { }   return getLastByIterating(map); }  private static  Entry getLastByIterating(Map map) {   Entry last = null;   for (Entry e : map.entrySet()) last = e;   return last; }  private static  Entry getLastViaReflection(Map map) throws NoSuchFieldException, IllegalAccessException {   Field tail = map.getClass().getDeclaredField("tail");   tail.setAccessible(true);   return (Entry) tail.get(map); } 


回答4:

One more way to get first and last entry of a LinkedHashMap is to use "toArray" method of Set interface.

But I think iterating over the entries in the entry set and getting the first and last entry is a better approach.

The usage of array methods leads to warning of the form " ...needs unchecked conversion to conform to ..." which cannot be fixed [but can be only be suppressed by using the annotation @SuppressWarnings("unchecked")].

Here is a small example to demonstrate the usage of "toArray" method:

public static void main(final String[] args) {     final Map orderMap = new LinkedHashMap();     orderMap.put(6, "Six");     orderMap.put(7, "Seven");     orderMap.put(3, "Three");     orderMap.put(100, "Hundered");     orderMap.put(10, "Ten");      final Set> mapValues = orderMap.entrySet();     final int maplength = mapValues.size();     final Entry[] test = new Entry[maplength];     mapValues.toArray(test);      System.out.print("First Key:"+test[0].getKey());     System.out.println(" First Value:"+test[0].getValue());      System.out.print("Last Key:"+test[maplength-1].getKey());     System.out.println(" Last Value:"+test[maplength-1].getValue()); }  // the output geneated is : First Key:6 First Value:Six Last Key:10 Last Value:Ten 



回答5:

It's a bit dirty, but you can override the removeEldestEntry method of LinkedHashMap, which it might suit you to do as a private anonymous member:

private Splat eldest = null; private LinkedHashMap pastFutures = new LinkedHashMap() {      @Override     protected boolean removeEldestEntry(Map.Entry eldest) {          eldest = eldest.getValue();         return false;     } }; 

So you will always be able to get the first entry at your eldest member. It will be updated every time you perform a put.

It should also be easy to override put and set youngest ...

    @Override     public Splat put(Integer key, Splat value) {          youngest = value;         return super.put(key, value);     } 

It all breaks down when you start removing entries though; haven't figured out a way to kludge that.

It's very annoying that you can't otherwise get access to head or tail in a sensible way ...



回答6:

I would recommend using ConcurrentSkipListMap which has firstKey() and lastKey() methods



回答7:

Perhaps something like this :

LinkedHashMap myMap;  public String getFirstKey() {   String out = null;   for (int key : myMap.keySet()) {     out = myMap.get(key);     break;   }   return out; }  public String getLastKey() {   String out = null;   for (int key : myMap.keySet()) {     out = myMap.get(key);   }   return out; } 


回答8:

Suggestion:

map.remove(map.keySet().iterator().next()); 


回答9:

Though linkedHashMap doesn't provide any method to get first, last or any specific object.

But its pretty trivial to get :

  • Map orderMap = new LinkedHashMap();
    Set al = orderMap.keySet();

now using iterator on al object ; you can get any object.



回答10:

Yea I came across the same problem, but luckily I only need the first element... - This is what I did for it.

private String getDefaultPlayerType() {     String defaultPlayerType = "";     for(LinkedHashMap.Entry entry : getLeagueByName(currentLeague).getStatisticsOrder().entrySet())     {         defaultPlayerType = entry.getKey();         break;     }     return defaultPlayerType; } 

If you need the last element as well - I'd look into how to reverse the order of your map - store it in a temp variable, access the first element in the reversed map(therefore it would be your last element), kill the temp variable.

Here's some good answers on how to reverse order a hashmap:

How to iterate hashmap in reverse order in Java

If you use help from the above link, please give them up-votes :) Hope this can help someone.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!