问题 在Java中使用什么集合代替2D数组?


我想使用一个集合来代替2D数组,这样我就不需要在声明时给出它的大小,我可以动态地添加任意数量的元素。


10483
2018-01-12 16:31


起源

您将使用哪些模式来访问数组中的元素?随机访问,整行,整列? - Robert Christie


答案:


List>的问题是,如果要重新定义矩阵,则必须重新定义每一行。

如果您想使用稀疏矩阵,或者可能是无限矩阵,您可以执行以下操作:

class SparseMatrix<X> {
  private Map<Coord, X> values = new HashMap<Coord, X>();

  public SparseMatrix() {
  }

  public X get(int x, int y) {
     return values.put(new Coord(x,y)); // null if there's no value
  }

  public void set(int x, int y, X value) { // you can use null (like in a List)
     values.set(new Coord(x,y), value);
  }

  private static class Coord {
    int x; int y;
    public Coord(int x, int y) {
       this.x = x;
       this.y = y;
    }

    @Override
    public boolean equals(Object other) {
       if (other instance of Coord) {
          Coord o = (Coord) other;
          return o.x == x && o.y == y;
       }
       return false;
    }

    @Override
    public int hashCode() {
       return o.x + o.y; // or some more clever implementation :)
    }

  }
}

编辑:  Apache Commons HashCodeBuilder 是一个生成哈希码的好工具。


7
2018-01-12 16:52



你的hashCode可能会溢出 - 不过你 做 已相应评论... :) - Esko
锐视!!!有一个实用方法:java.util.Arrays.hashCode(int [])为int []创建一个哈希码,当然,每次需要hashChode时创建一个数组都不是很好(或者有它创造了)。也许我们可以只为两个整数复制它的实现:(31 + o.x)* 31 + o.y.但它似乎溢出了......(我认为这没关系,它是循环的吗?)。 - helios
在hashCode()中,x + y == y + x是否重要? - Adam
不,没关系。 hashCodes的重要之处在于它们提供了相当分散的值,所以如果你有N个桶,你可以使用那个hashCode或多或少地统一分配它们(把对象放在桶中) hasCode(X) % N。这就是我的实现不好的原因:如果你使用低坐标,它会提供低哈希码。我将添加对Apache HashCodeBuilder的引用。它非常好地封装了这个问题。 - helios


你想用它做什么?我可能只是使用一个 Collection<Collection<Element>> (其中Collection可能被List替换)。

或者,您可以使用metod创建自己的类,以根据需要迭代行或列或所有元素。


2
2018-01-12 16:35





最简单的方法是使用嵌套集合...说(假设你的值是字符串) List<List<String>>  然后可以像这样使用:

List<List<String>> fakeArray = new ArrayList<List<String>>();

// Pretend you fill it with values between these calls
String retrieve = fakeArray.get(0).get(0);

编辑:这本来是一个 Map<String,List<String>> 在这种情况下真的没有意义。

但是,您可能想看看是否 Google Collections 要么 Apache Commons Collections 你可以使用更专业的东西。


2
2018-01-12 16:34





我个人正在使用 向量 虽然不同的要求可能最终决定使用其他更专业的类,但是为此目的的类。


0
2018-01-12 16:33



Vector几乎已被弃用,已被ArrayList取代。 - Yoni
@mortiz - java.util.Vector 通常应该避免 - 它的线程安全性对于大多数多线程场景并不是非常有用,只会增加单线程使用的开销。大多数人使用 ArrayList 作为他们的默认 List 键入而不是。 - McDowell
学到了点什么,谢谢! - moritz


java.util.ArrayList是我的首选。

http://java.sun.com/j2se/1.5.0/docs/api/java/util/ArrayList.html


0
2018-01-12 16:34



我想当我们想要动态一维数组时使用它 - Yatendra Goel
你可以有一个ArrayList,它的每个元素都是另一个ArrayList(正如rsp和我在我们的答案中提出的那样)。通过这种方式,ArrayList也可以用于2D阵列。 - Alex


这取决于你想要做什么,但我会推荐ArrayList。它比Vector快。除非你关心同步!如果您希望它作为二维列表,那么您创建一个ArrayList,此列表的每个元素将是另一个ArrayList。


0
2018-01-12 16:35





你可以试一试 ArrayList 有 ArrayLists作为项目。如果这样做不符合您的要求,它将为您自己构建的内容提供绝对的信息。


0
2018-01-12 16:35





这取决于您想要使用数据结构的方式。你的选择是:

  • 两个清单;你的工作就是他们之间的同步。
  • 一张地图;而不是键值关系,您的地图条目将只是对象的元组。
  • 2单元对象数组列表;列表中的每个项目都是大小为2的对象数组。

编辑: 我完全误解了这个问题;我以为它是关于宽度为2的2D数组。

正确阅读了问题(我希望:-)),我同意那些列出名单的人。


0
2018-01-12 16:35





进口 java.util.ArrayList;

ArrayList 是你想要的,你不需要在创建时设置它的大小,你可以使用动态添加元素 add 方法。


0
2018-01-12 16:34