How Get Value from Linkedhashmap Based on Index Not on Key

How get value from LinkedHashMap based on index not on key?

You can't get the value of the Map based on index, Maps just don't work that way. A workaround would be to 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(0);

how to get a linkedhashmap value using index?

A crude way to do it would be

new ArrayList<String>(MonthlyCPIMenu.keySet()).get(index);

but LinkedHashMap generally doesn't support efficient indexed retrieval, and it doesn't provide any API for the purpose. The best algorithm to do it is just to take MonthlyCPIMenu.keySet().iterator(), call next() index times, and then return the result of one final next():

<K, V> K getKey(LinkedHashMap<K, V> map, int index) {
Iterator<K> itr = map.keySet().iterator();
for (int i = 0; i < index; i++) {
itr.next();
}
return itr.next();
}

fetching from LinkedHashMap HashMap based on index

I believe there is no straightforward way to do it but you can implement an utility method that would fulfil your need:

public class IndexedMap
{
public static void main(String[] args)
{
LinkedHashMap hm = new LinkedHashMap();
hm.put("a",1);
hm.put("b",2);
hm.put("c",3);
hm.put("d",4);
hm.put("e",5);
System.out.println(getNextItem(hm, "d"));
}

public static Object getNextItem(LinkedHashMap<String, String> hMap, String item){

int index = 0;
List<String> keys = new ArrayList<String>(hMap.keySet());
for (String key : keys)
{
if (item.equals(key))
break;

index++;
}
return (index < keys.size() - 1) ? hMap.values().toArray()[++index] : 0;
}

}

How to get position of key/value in LinkedHashMap using its key

HashMap implementations in general are un-ordered for Iteration.

LinkedHashMap is predictablely ordered for Iteration ( insertion order ) but does not expose the List interface and a LinkedList ( which is what mirrors the key set insertion order ) does not track index position itself either, it is very in-efficient to find the index as well. The LinkedHashMap doesn't expose the reference to the internal LinkedList either.

The actual "Linked List" behavior is implementation specific. Some
may actually use an instance of LinkedList some many just have
Entry track a previous and next Entry and use that as its
implementation. Don't assume anything without looking at the source.

The KeySet that contains the keys does not guarantee order as well because of the hashing algorithms used for placement in the backing data structure of the inherited HashMap. So you can't use that.

The only way to do this, without writing your own implementation, is to walk the Iterator which uses the mirroring LinkedList and keep a count where you are, this will be very in-efficient with large data sets.

Solution

What it sounds like you want is original insertion order index positions, you would have to mirror the keys in the KeySet in something like an ArrayList, keep it in sync with updates to the HashMap and use it for finding position. Creating a sub-class of HashMap, say IndexedHashMap and adding this ArrayList internally and adding a .getKeyIndex(<K> key) that delegates to the internal ArrayList .indexOf() is probably the best way to go about this.

This is what LinkedHashMap does but with a LinkedList mirroring the KeySet instead of an ArrayList.

Get LinkedHashMap index of a key

Adding to Louis Wasserman answer instead of creating a new map,you can move the index and value to a Pojo and save that as the value in the Map.

class Test{
int index;
int value;
public int getIndex();
public int getValue();
}

Use the LinkedHashMap as LinkedHashMap String,Test>

Java HashMap: How to get a key and value by index?

You can iterate over keys by calling map.keySet(), or iterate over the entries by calling map.entrySet(). Iterating over entries will probably be faster.

for (Map.Entry<String, List<String>> entry : map.entrySet()) {
List<String> list = entry.getValue();
// Do things with the list
}

If you want to ensure that you iterate over the keys in the same order you inserted them then use a LinkedHashMap.

By the way, I'd recommend changing the declared type of the map to <String, List<String>>. Always best to declare types in terms of the interface rather than the implementation.

LinkedHashMap access by index vs Performance

As said by Stephen C, the time complexity is the same, as in either case, you have a linear iteration, but the efficiency still differs, as the second variant will only iterate to the specified element, instead of creating a complete copy.

You could optimize this even further, by not performing an additional lookup after finding the entry. To use the pointer to the actual location within the Map, you have to make the use of its Iterator explicit:

public boolean removeItem(int position) {
if(position >= items.size()) return false;
Iterator<?> it=items.values().iterator();
for(int counter = 0; counter < position; counter++) it.next();
boolean result = it.next() != null;
it.remove();
return result;
}

This follows the logic of your original code to return false if the key was mapped to null. If you never have null values in the map, you could simplify the logic:

public boolean removeItem(int position) {
if(position >= items.size()) return false;
Iterator<?> it=items.entrySet().iterator();
for(int counter = 0; counter <= position; counter++) it.next();
it.remove();
return true;
}

You may retrieve a particular element using the Stream API, but the subsequent remove operation requires a lookup which makes it less efficient as calling remove on an iterator which already has a reference to the position in the map for most implementations.

public boolean removeItem(int position) {

if(position >= items.size() || position < 0)
return false;

Product key = items.keySet().stream()
.skip(position)
.findFirst()
.get();

items.remove(key);
return true;
}

How do I get the index of an Item in a LinkedHashMap in a List?

You can try this:

 productsNeeded.entrySet().stream()
.filter(e -> e.getValue()
.contains(matchingElement))
.map(Map.Entry::getKey)
.findFirst();

Provided that matchingElement is the object of type OrderLine you're looking for. Here you're getting Optional. To get value you can call get or orElse to provide a default one, for example:

 productsNeeded.entrySet().stream()
.filter(e -> e.getValue()
.contains(matchingElement))
.map(Map.Entry::getKey)
.findFirst().orElse(null);

`ArrayList of HashMap` or `LinkedHashMap` to get item by index

I went with experimentating it myself. Turns out the method of creating an ArrayList of HashMaps is about 40 times faster with 1000 elements.

public class HashMapVsArrayOfHashMap {

public static void main(String[] args){
ArrayList<HashMap<String, String>> listOfMaps=new ArrayList<HashMap<String,String>>();
for( int i=0;i<1000;i++){
final int finalI=i;
listOfMaps.add(new HashMap<String, String>(){{put("asdfasdfasdfasdfadsf"+finalI,"asdfsdafasdfsadfasdf"+finalI);}});
}
LinkedHashMap<String, String> map=new LinkedHashMap<String, String>();
for(int i=0;i<1000;i++)
map.put("asdfasdfasdfasdfadsf"+i,"asdfsdafasdfsadfasdf"+i);
int position=700;
testArrayList("Method1:ArrayListOfHashMaps",position,listOfMaps);
testHashMap("Method2:LinkedHashMap",position,map);
}

private static void testArrayList(String string, int position,
ArrayList<HashMap<String, String>> listOfMaps) {
long start, end;
start=System.nanoTime();
listOfMaps.get(position).get("asdfasdfasdfasdfadsf"+position);
end=System.nanoTime();
System.out.println(string+"|Difference = "+(end-start));
}
private static void testHashMap(String string, int position,
LinkedHashMap<String, String> map) {
long start, end;
start=System.nanoTime();

String s= new ArrayList<String>(map.keySet()).get(position);

end=System.nanoTime();
System.out.println(string+"|Difference = "+(end-start));
}
}

Sample Image

Sample Image

Sample Image

When you increase the size to 30,000 elements - the difference is HUGE.

Sample Image

Sample Image

Sample Image

retrieve Hashmap Elements by index based

First of all, you will have to use LinkedHashMap.

Map pins = new LinkedHashMap();

and then after putting in the values, you can do the following:

List keys = new ArrayList(pins.keySet());
List values = new ArrayList(pins.values());
System.out.print((String)keys.get(0) + " " + (String)values.get(0));


Related Topics



Leave a reply



Submit