user7748519
user7748519

Reputation:

How to put entry of 2d array in map as key

There is a 2d array with contains set and I want to put it on a map as key. Please, someone, suggest how to do it correctly. Expected and actual outputs are attached below.

public class trysome
{
        static int[][] points = {{1,2}, {1,1},{5,7}};
        public static void some()
        {
          HashMap<int[], Integer> map= new HashMap<int[], Integer>();
            for(int i =0;i<points.length;i++)
            {
                map.put(points[i], 1);
            }
            for(Entry<int[], Integer> entry : map.entrySet())
            {
                System.out.println(entry.getKey() + " "+entry.getValue());
            }

        }
    public static void main(String[] args) 
    {
        trysome.some();
    }

}

Actual Output: 
[I@16b4a017 1
[I@8807e25 1
[I@2a3046da 1

Expected Output: 
{1,2}  1
{1,1}  1
{5,7}  1

Upvotes: 1

Views: 1811

Answers (3)

Jan Čern&#253;
Jan Čern&#253;

Reputation: 1386

This method can help you:

private static String intArrayToString(int[] inputArray) {
        StringBuilder output = new StringBuilder().append('{');
        for (int i = 0; i < inputArray.length - 1; i++) {
            output.append(inputArray[i]);
            output.append(',');
        }
        output.append(inputArray[inputArray.length - 1]);
        return output.append('}').toString();
    }
}

You can use it like this:

System.out.println(intArrayToString(entry.getKey()) + " " + entry.getValue());

Benefits of this solution are that you can customize it as you wish.

Upvotes: 0

Marco13
Marco13

Reputation: 54679

The reason for the output that you are observing is explained in What's the simplest way to print a Java array?. The bottom line is: The output [I@16b4a017 is basically the "memory location" of the array, and just not the contents of the array.

The reason why I'm not closing this as a duplicate is that the output here is just an irrelevant symptom of a much greater flaw: Your approach is conceptually wrong.

You cannot use an int[] array as the key in a hash-based datastructure!

One might argue that it would work if one relied on the identity of the arrays. But that's rarely the case.

The reason for that is that the equals and hashCode methods are not implemented on arrays in the way that would be necessary for this to work. Omitting some technical details that can be read elsewhere.

If your code is supposed to handle 2D points in a plane, then you should use a proper class to represent these points. This class could then include proper implementations of hashCode, equals and toString.

Fortunately, there already is such a class in the Java standard API, namely, java.awt.Point.

The following shows why your original implementation would not work as expected, in the usingArraysAsKeys method, and how it could be implemented properly in the usingPointsAsKeys method:

import java.awt.Point;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

public class PointsAsKeys
{
    public static void main(String[] args)
    {
        usingArraysAsKeys();
        usingPointsAsKeys();
    }

    public static void usingPointsAsKeys()
    {
        Point points[] =
        {
            new Point(1, 2),
            new Point(1, 1),
            new Point(5, 7) 
        };
        Map<Point, Integer> map = new HashMap<Point, Integer>();
        for (int i = 0; i < points.length; i++)
        {
            map.put(points[i], 1);
        }
        for (Entry<Point, Integer> entry : map.entrySet())
        {
            Point p = entry.getKey();
            String s = "{" + p.x + ", " + p.y + "}";
            System.out.println(s + " " + entry.getValue());
        }

        //=====================================================================
        // Important: This shows that it WILL work as expected!
        Point somePoint = new Point(1, 2);
        Integer value = map.get(somePoint);
        System.out.println("Value for " + somePoint + " is " + value);

    }


    public static void usingArraysAsKeys()
    {
        int[][] points =
        {
            { 1, 2 },
            { 1, 1 },
            { 5, 7 } 
        };
        HashMap<int[], Integer> map = new HashMap<int[], Integer>();
        for (int i = 0; i < points.length; i++)
        {
            map.put(points[i], 1);
        }
        for (Entry<int[], Integer> entry : map.entrySet())
        {
            // This would print the arrays as "[I@139a55"
            //System.out.println(entry.getKey() + " " + entry.getValue());

            // This will print the arrays as [1, 2]:
            System.out.println(
                Arrays.toString(entry.getKey()) + " " + entry.getValue());
        }

        //=====================================================================
        // Important: This shows that it will NOT work as expected!
        int somePoint[] = { 1, 2 };
        Integer value = map.get(somePoint);
        System.out.println(
            "Value for " + Arrays.toString(somePoint) + " is " + value);

    }

}

Another advantage of using the Point class is that it already has several convenient methods - most importantly, a Point2D#distance method that allows you to compute the distance of a point to another one:

// Computes the distance of the point to the point at (0,0) (i.e. the origin)
double distanceToOrigin = point.distance(new Point(0,0));

(By the way: If the map is supposed to store distances, then its value type should probably be Double and not Integer)

Upvotes: 3

Svichkarev Anatoly
Svichkarev Anatoly

Reputation: 739

Try this:

System.out.println(Arrays.toString(entry.getKey()) + " "+entry.getValue());

Output (for example):

[1, 2] 1

Or if you want to exact as Expected Output:

System.out.println(String.format("{%d,%d}", entry.getKey()[0], entry.getKey()[1]) +
                   "  " + entry.getValue());

Upvotes: 0

Related Questions