如何将2d数组的输入作为关键字放入地图中

时间:2018-03-31 23:19:17

标签: java collections hashmap

有一个包含set的2d数组,我想把它作为键放在地图上。请有人建议如何正确地做到这一点。预期和实际产出如下。

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

3 个答案:

答案 0 :(得分:2)

您正在观察的输出的原因在What's the simplest way to print a Java array?中进行了解释。底线是:输出[I@16b4a017基本上是&#34;内存位置&#34;数组,而不是数组的内容

我之所以没有将其作为副本关闭,原因在于此处的输出只是一个更大缺陷的无关症状:您的方法在概念上错误

您不能将int[]数组用作基于散列的数据结构中的键!

有人可能会说,如果依赖于数组的身份,它会起作用。但这种情况很少发生。

原因是equalshashCode方法没有以这种方式实现的方式在数组上实现。省略一些可以在别处阅读的技术细节。

如果您的代码应该处理平面中的2D点,那么您应该使用适当的类来表示这些点。然后,此类可以包含hashCodeequalstoString的正确实现。

幸运的是,Java标准API中已经存在这样的类,即java.awt.Point

以下说明了原始实现usingArraysAsKeys方法中按预期工作的原因,以及如何在usingPointsAsKeys方法中正确实现:

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);

    }

}

使用Point类的另一个好处是它已经有几个方便的方法 - 最重要的是,一个Point2D#distance方法允许你计算一个点到另一个点的距离:

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

(顺便说一下:如果地图应该存储距离,那么它的值类型应该是Double而不是Integer

答案 1 :(得分:0)

试试这个:

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

输出(例如):

[1, 2] 1

或者,如果您想要与预期输出完全相同:

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

答案 2 :(得分:0)

此方法可以帮助您:

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();
    }
}

你可以像这样使用它:

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

此解决方案的好处是您可以根据需要自定义它。