Search code examples
javaeclipse-collections

How convert/adapt ByteObjectHashMap to a JDK Map?


Primitive maps don't seem to implement java.util.Map.

If I have a function, accepting JDK Map as an argument and now want to pass eclipse collection implementation, for example ByteObjectHashMap, what's the easiest way to do that?

it stated here, that package org.eclipse.collections.impl.map.mutable contains implementations of the MutableMap interface. Primitive are in sub-package of mutable and I expected them to implement MutableMap, which, in turn, implements java.util.Map.


Solution

  • The easiest way to accomplish this today is to copy the contents of the ByteObjectMap to a Map<Byte, Object> using forEachKeyValue.

    Here is an example converting a ByteObjectMap<String> to Map<Byte, String>.

    @Test
    public void byteObjectHashMapToMap()
    {
        ByteObjectMap<String> map =
                ByteObjectMaps.mutable.<String>empty()
                        .withKeyValue((byte) 1, "1")
                        .withKeyValue((byte) 2, "2")
                        .withKeyValue((byte) 3, "3")
                        .withKeyValue((byte) 4, "4");
    
        Map<Byte, String> target = new HashMap<>();
        map.forEachKeyValue(target::put);
    
        Map<Byte, String> expected = Map.of((byte) 1, "1",
                (byte) 2, "2",
                (byte) 3, "3",
                (byte) 4, "4");
        Assert.assertEquals(expected, target);
    }
    

    Update: The Eclipse Collections 11.1 release will have a new method on object and primitive maps called injectIntoKeyValue. The following will be possible as a solution once it is released.

    // Eclipse Collections MutableMap as target
    Map<Byte, String> target =
            map.injectIntoKeyValue(Maps.mutable.empty(), MutableMap::withKeyValue);
    
    // JDK Map as target
    Map<Byte, String> jdkTarget =
            map.injectIntoKeyValue(new HashMap<>(), 
                    (m, k, v) -> {m.put(k, v); return m;});
    

    It would be a reasonable contribution from the OSS community to add Map views for primitive maps, but this hasn't been done yet. This is probably because it is not a trivial amount of work. When Project Valhalla is available in the JDK, it would be more reasonable for the primitive maps in Eclipse Collections to implement Map<byte, String>. This is not possible without primitive specialization over generics in Java.

    The package documentation you linked to refers to "Related Packages", but this is clearly something worth clarifying as I can see how it may be confusing. Thank you for pointing this out.