【问题标题】:Ways to do a 2 dimensional array in java?在java中做一个二维数组的方法?
【发布时间】:2009-10-14 02:21:37
【问题描述】:

我想存储二维值,即 B-1、C-2、D-3 等。

对可以使用的类或接口有什么建议吗?

【问题讨论】:

    标签: java spring


    【解决方案1】:

    多维数组有三种基本类型:

    1. 固定。想象一个棋盘,它总是 8x8(尽管有变体)。但这也可能意味着一些可变但在实例化时固定的东西;
    2. 稀疏。 值之间有大量空白的数组。电子表格通常符合这种描述,但稀疏和不稀疏通常是主观判断;和
    3. 密集。 稀疏的反义词。使用了大部分或所有可能的值。

    Java 没有原生多维数组类型。 Java 有数组数组,这并不完全相同。例如,这是合法的 Java:

    int arr[][] = new int[] {
      new int[3],
      new int[4],
      new int[5]
    };
    

    固定数组可以通过这种方式完成,但可能会很尴尬。使用带有对象包装器的一维数组通常更容易:

    public class Chessboard {
      public final static DEFAULT_X = 8;
      public final static DEFAULT_Y = 8;
      public final static DEFAULT_SIZE = DEFAULT_X * DEFAULT_Y;
    
      private final int x;
      private final int y;
      private final int size;
      private final Piece squares[];
    
      public Chessboard() {
        this(DEFAULT_X, DEFAULT_Y);
      }
    
      public Chessboard(int x, int y) {
        if (x < 2) {
          throw new IllegalArgumentException("x (" + x + ") must be 2+");
        }
        if (y < 2) {
          throw new IllegalArgumentException("y (" + y + ") must be 2+");
        }
        this.x = x;
        this.y = y;
        size = x * y;
        pieces = new Piece[size];
      }
    
      public Piece get(int x, int y) {
        return pieces[y * this.x + x];
      }
    
      public Piece get(String xy) {
        // eg 'h3' => (7,2)
        return get(xy.charAt(0) - 'a', xy.charAt(1) - '0');
      }
    
      // etc
    }
    

    这当然可以用数组的数组来代替。

    稀疏数组倾向于在 Java 中使用映射实现:

    public class Sparse2DArray<T> {
      public final static int MAX_X = 8192;
      public final static int MAX_Y = 8192;
    
      private final Map<String, T> array = new HashMap<String, T>();
      private final Pattern XY = Pattern.compile("^([A-Za-z]+)([0-9]+)");
    
      public T get(int x, int y) {
        if (x < 0 || x >= MAX_X) {
          throw new IllegalArgumentException("x (" + x + ") must be 0 to " + (MAX_X-1));
        }
        if (y < 0 || y >= MAX_Y) {
          throw new IllegalArgumentException("y (" + y + ") must be 0 to " + (MAX_Y-1));
        }
        return array.get(x + "," + y);
      }
    
      public T get(String xy) {
        Matcher m = XY.matcher(xy);
        if (!m.matches()) {
          throw new IllegalArgumentException("xy (" + xy + ") must be letters followed by digits");
        }
        String s = m.group(1).toUpperCase();
        int multiplier = 1;
        int x = 0;
        for (int i=s.length()-1; i>=0; i--) {
          x += (s.chartAt(i) - 'A') * multiplier;
          multiplier *= 26;
        }
        int y = Integer.valueOf(m.group(2));
        return array.get(x, y);
      }
    
      // etc
    }
    

    您也可以通过构造一个 N 维键类来用作映射键来做到这一点。它需要定义适当的 equals()hashCode() 方法,并且可能是更清洁的解决方案,但上述方法可行。

    显然,如果您要将 100x100 数组的每个值都存储在稀疏数组类中,则会产生开销(因为所有地图都有开销)。这带来了密集阵列。稀疏数组仅存储设置了值的值。密集数组为每个可能的键(在指定范围内)存储一个值。

    同样,稠密数组与固定数组相似,但又不完全相同。固定数组一旦创建就很难扩展(嗯,这是一项昂贵的操作,因此通常不允许这样做),而密集数组可能会被构建为扩展,就像您可以将它们用于电子表格并扩展最大 X 和 Y 值是用户使用越来越多的单元格,因此您可以定义一个包含所有使用值的矩形。

    【讨论】:

    • 天啊,那是什么.. :o +1 这篇论文
    【解决方案2】:

    如果您正在寻找一个电子表格类型的应用程序(从 spring-framework 标记和 B-1/C-2 名称推导出来,可能是错误的),稀疏数组可能是要走的路。

    Colt 有一个这样的实现。

    我回答了一个类似的问题here

    【讨论】:

      【解决方案3】:

      我假设您需要 Java 中的数据结构来存储这些值。

      您可以使用以下语法在 Java 中定义一个二维数组。

      String[][] strArr = new String[5][5]; //defines a 5*5 String array 
      String[][] strArr2 = new String[1][2]; //defines a 1*2 String array 
      

      请注意,数组只能保存 1 种数据类型的值。可以使用类似的方式取消引用特定项目

      System.out.println(strArr2[0][1]);
      

      对于您的具体示例,您还可以使用 java.util.Map 类并将数据存储为键值对,但这要求“键”是唯一的。例如,

      Map<String,Integer> keyval = new HashMap<String, Integer>();
      keyval.put("B",1);
      keyval.put("C",2);
      keyval.put("D",3);
      keyval.put("D",4); //wrong. will overwrite the previous entry.
      

      【讨论】:

        【解决方案4】:

        我猜你需要的是 ArrayLists 的 Map:

        HashMap<String, ArrayList<YourClass>> map;
        

        这样 B-1 将是 map.get("B").get(1);

        【讨论】:

          猜你喜欢
          • 2013-08-28
          • 2016-08-26
          • 1970-01-01
          • 2013-09-16
          • 1970-01-01
          • 2012-03-08
          • 1970-01-01
          • 1970-01-01
          • 2014-11-11
          相关资源
          最近更新 更多