开发者

Alternatives to 2D Arrays in Java

I have a lookup table that should be accessed by two separate key values. One ugly way to do this is:

int[][] myArray = new int[256][256];
myArray[key1][key2] = 25;

where key1 and key2 are keys that were previously generated dynamically. But this is rather ugly. It seems that a better way to do this would be to use a Map, but those require a single 开发者_运维知识库key, not two. Java doesn't natively support tuples, so what should I use instead? (It also seems awkward to use an array as the key).

EDIT: The reason I say that this isn't particularly pretty is that my array is actually referenced by character values, not integers. They could be used interchangeably, but the responses to my previous question seem to suggest otherwise:

2D Array in Java, Indexed by Characters


What's so ugly about that? That's about as simple as 2D matrices can be in Java, and it's quick, too.

If you really want to use a map, just defined your own Tuple class to use as a key - but be sure that you override equals() and hashCode() correctly! I'd recommend implementing an immutable Tuple class because using mutable objects as map keys can cause serious issues.

Tuple.java

package q5128376;

import java.util.Arrays;

public class Tuple<T>
{
    private T[] values;
    private int hashCode;

    private Tuple(T... values)
    {
        this.values = values;
        this.hashCode = hashCode(values);
    }

    public static <T> Tuple<T> create(T... values)
    {
        return new Tuple<T>(values);
    }

    private static <T> int hashCode(T... values)
    {
        return 31 * Arrays.hashCode(values);
    }

    @Override
    public int hashCode()
    {
        return hashCode;
    }

    @Override
    public boolean equals(Object obj) 
    {
        if (this == obj) return true;
        if (!(obj instanceof Tuple<?>)) return false;
        Tuple<?> other = (Tuple<?>) obj;
        if (!Arrays.equals(values, other.values)) return false;
        return true;
    }
}


Your solution does not seem very ugly to me... It's very fast, at the expense of a little memory usage (64 K ints).

An alternative would be to define a Pair class to use as a key for a map.

Yet another solution would be to define a map that maps ints to a map mapping ints to int values:

Map<Integer, Map<Integer, Integer>> map;

However, this would require the creation of a lot of map objects.

The best approach depends on how sparse your lookup table is.


I agree with ChrisJ that your 2 dimensional array is not bad at all.

You could have a Map of a Map, like

Map<Integer, Map<Integer, Integer>> myMap;

But that can get even more ugly than your 2d array idea.


Alternatively, you could convert two int keys into one String key, like

Map<String, Integer> myMap = new HashMap<String, Integer>();
int key1 = 3;
int key2 = 4;
int value = 25;
myMap.put(key1 + "/" + key2, value);

But I recommend going with the solution you have, if you can guarentee that the highest value for either key is 255.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜