Search code examples
javaarrayslinkedhashmap

Create new Arrays from linkedHashMap with keys and values separately


I have a LinkedHashMap and I am trying to split its keys and values and refer to specific key in the keyset or value in valueset. For ex. Lets say I have the folowing LinkedHashMap:

4 | 2

3 | 1

I want a function to return 1, which is a value at index 1 in the set with values or return 2 for index = 0. And with another function I want to get 3 as value with index 1 in key values. So basically from the LinkedHashMap create an Array with only values/ keys and then look for some given place in this array. My code looks as follow:

    public static Integer getLHMValue(Map<Integer, Long> lhm, int index) { 
        Set<Map.Entry<Integer, Long>> valueSet = lhm.entrySet();
        Integer[] valueArray = valueSet.toArray(new Integer[valueSet.size()]);
        Integer value = valueArray[index];
        return value;
    }

    public static Integer getLHMKey(Map<Integer, Long> lhm, int index) { 
        Set<Integer> keySet = lhm.keySet();
        Integer[] keyArray = keySet.toArray(new Integer[keySet.size()]);
        Integer key = keyArray[index];
        return key;
}

Though, I get java.lang.ArrayStoreException: java.util.LinkedHashMap$Entry in: Integer[] keyArray = valueSet.toArray(new Integer[valueSet.size()]);. Any ideas?


Solution

  • The problem is that the entrySet would be needed to first have an array of Map.Entrys. Keeping such an array for both methods would be faster.

    List<Map.Entry<Integer, Long>> entries = new ArrayList<>(lhm.entrySet());
    
    public static long getLHMValue(Map<Integer, Long> lhm, int index) { 
        return entries.get(index).getValue();
    }
    
    public static int getLHMKey(Map<Integer, Long> lhm, int index) { 
        return entries.get(index).getKey();
    }
    

    There is no efficient solution if you do it directly, and so it is not advisable to offer these functions to access key and value.

    public static Long getLHMValue(Map<Integer, Long> lhm, int index) { 
        return lhm.entrySet().stream()
            .map(Map.Entry<Integer, Long>::getValue)
            .skip(index)
            .findFirst()
            .orElseThrow(IndexOutOfBoundsException::new);
    }
    
    public static Integer getLHMKey(Map<Integer, Long> lhm, int index) { 
        return lhm.entrySet().stream()
            .map(Map.Entry<Integer, Long>::getKey)
            .skip(index)
            .findFirst()
            .orElseThrow(IndexOutOfBoundsException::new);
    }