Peter Penzov
Peter Penzov

Reputation: 1728

How to get element position from Java Map

I have this Java Map:

Can you tell me how I can get the 6-th element of the Map?

private static final Map<String, Users> cache = new HashMap<>();

is this possible? Or I have to use another Java collection?

Upvotes: 18

Views: 59665

Answers (13)

Sage
Sage

Reputation: 15428

Though a bit late to answer. But the option is to use LinkedHashMap: this map preserves the order according to insertion of elements, as everyone has suggested. However, As a warning, it has a constructor LinkedHashMap(int initialCapacity, float loadFactor, boolean accessOrder) which will create a linked hash map whose order of iteration is the order in which its entries were last accessed. Don't use this constructor for this case.

However, if I needed such functionality, i would extend it and implement my necessary function to re-use them in OOP way.

class MyLinkedMap<K, V> extends LinkedHashMap<K, V>
{

    public V getValue(int i)
    {

       Map.Entry<K, V>entry = this.getEntry(i);
       if(entry == null) return null;

       return entry.getValue();
    }

    public Map.Entry<K, V> getEntry(int i)
    {
        // check if negetive index provided
        Set<Map.Entry<K,V>>entries = entrySet();
        int j = 0;

        for(Map.Entry<K, V>entry : entries)
            if(j++ == i)return entry;

        return null;

    }

}

Now i can instantiate it and can get a entry and value either way i want:

MyLinkedMap<String, Integer>map = new MyLinkedMap<>();
map.put("a first", 1);
map.put("a second", 2);
map.put("a third", 3);

System.out.println(map.getValue(2));
System.out.println(map.getEntry(1)); 

Output:

3
a second=2

Upvotes: 30

MaVRoSCy
MaVRoSCy

Reputation: 17849

According to documentation, HashMap is a Hash table based implementation of the Map interface. This implementation provides all of the optional map operations, and permits null values and the null key. (The HashMap class is roughly equivalent to Hashtable, except that it is unsynchronized and permits nulls.) This class makes no guarantees as to the order of the map; in particular, it does not guarantee that the order will remain constant over time.

That's why it is not wise to use this kind of Collection.

UPDATE:

Based on @Prateek implementation of LinkedHashMap I would suggest something like:

LinkedHashMap<String,User> linkedHashMap = new LinkedHashMap<String,User>();
// or LinkedHashMap<String,User> linkedHashMap = new LinkedHashMap<>(); //for java 7+

linkedHashMap.put("1",userObj1);
linkedHashMap.put("2",userObj2);
linkedHashMap.put("3",userObj3);

/* Get by position */
int pos = 1; // Your position
User tmp= (new ArrayList<User>(linkedHashMap.values())).get(pos);
System.out.println(tmp.getName());

Upvotes: 3

Prateek
Prateek

Reputation: 6975

HashMaps do not preserve ordering:

LinkedHashMap which guarantees a predictable iteration order.

Example

public class Users 
{
 private String Id;

 public String getId()
 {
    return Id;
 }

 public void setId(String id) 
 {
    Id = id;
 }
}


Users user;
LinkedHashMap<String,Users> linkedHashMap = new LinkedHashMap<String,Users>();

for (int i = 0; i < 3; i++)
{
  user = new Users();
  user.setId("value"+i);
  linkedHashMap.put("key"+i,user);
}

/* Get by position */
int pos = 1;
Users value = (new ArrayList<Users>(linkedHashMap.values())).get(pos);
System.out.println(value.getId());

Upvotes: 3

rachana
rachana

Reputation: 3424

Use LinkedHashMap instead of HashMap It will return keys in same order (as insertion) when calling keySet().

For mare detail about LinkedHashMap see this

For example to get the element from specific index

Create a new list from your values and get the value based on index.

 LinkedHashMap<String, List<String>> hMap;
 List<List<String>> l = new ArrayList<List<String>>(hMap.values());
 l.get(6); 

Upvotes: 1

Ruchira Gayan Ranaweera
Ruchira Gayan Ranaweera

Reputation: 35587

HashMap doesn't grantee the order. If you concern about order you should use LinkedHashMap

Map<String, Users> orderedMap=new LinkedHashMap<>();

Now when you put an element it will keep the order what you put.

If you want to get 6th element, now you can do it since you have your elements in order.

 orderedMap.values().toArray()[5]// will give you 6th value in the map. 

Example

 Map<String, String> orderedMap=new LinkedHashMap<>();
 orderedMap.put("a","a");
 orderedMap.put("b","b");
 System.out.println(orderedMap.values().toArray()[1]);  // you will get b(value)
 System.out.println(orderedMap.keySet().toArray()[1]);  // you will get b(key)
    }

Upvotes: 11

Abimaran Kugathasan
Abimaran Kugathasan

Reputation: 32488

There is no Order in HashMap. You can obtain the list of may keys using map.keySet() but there's no guarantee the key set will be in the order which you add it in. Use LinkedHashMap instead of HashMap It will always return keys in same order (as insertion)

Upvotes: 2

Vignesh Vino
Vignesh Vino

Reputation: 1238

The HashMap has no defined ordering of keys.It's Unordered.

You can use LinkedHashMap which will store your keys in order of insertion.You can retrieve them by calling keySet().

Upvotes: 6

Adam Arold
Adam Arold

Reputation: 30578

You need to use a LinkedHashMap in order to be able to tell the order of the inserted elements. HashMap is not capable of doing so.

Upvotes: 2

vikingsteve
vikingsteve

Reputation: 40438

If the ordering is to mean anything significant, you could consider using a SortedMap.

Concrete implementation: TreeMap

Upvotes: 1

Kayaman
Kayaman

Reputation: 73578

A HashMap doesn't have a position. You can iterate through its KeySet or EntrySet, and pick the nth element, but it's not really the same as a position. A LinkedHashMap does have a position, since it has a predictable iteration order.

Upvotes: 2

Rahul
Rahul

Reputation: 45090

A HashMap does not maintain the order of the elements inserted in it. You can used a LinkedHashMap instead which maintains the order of the elements inserted in it.

Though you need to note that even a LinkedHashMap has no such method which would give the element at a particular index. You will have to manually iterate through the entries and extract the element at the 6th iteration.

Upvotes: 7

Foolish
Foolish

Reputation: 4202

Correct!! you will have to use other collection for getting values on index(position). You can use ArrayList

Upvotes: 1

kutschkem
kutschkem

Reputation: 8163

With guava's Iterables

Iterables.get(map.entrySet(),6);

Upvotes: 6

Related Questions