2012-02-10 69 views
4

我知道我无法在尚未使用的ArrayList的索引处存储值,即小于大小。换句话说,如果myArrayList.size()是5,那么如果我尝试做Java:存储ArrayList的任意索引的最佳方法

myArrayList.set(10, "Hello World") 

我会得到一个出界失误。但我的应用程序需要这个。除了在每个中间插槽中存储空循环之外,还有更优雅的方式吗?

它看起来对我来说:

  • 此行为是在矢量
  • 相同的,如果我需要能够随机访问(在pos X即要素),那么我的选择是Vector和ArrayList。
  • 我可以使用HashMap并使用索引作为关键字,但这真的是效率低下。

那么什么是典型的解决方案,看起来像一个常见的情况。我必须错过一些东西......

+3

你为什么说Map解决方案真的效率低下?您的空间要求有多严格? – 2012-02-10 16:23:07

+0

为什么使用HashMap的效率低于你用ArrayList提出的方式? – 2012-02-10 16:23:56

+0

另外,您是否事先知道最高指数会是多少? – 2012-02-10 16:23:56

回答

4

我可以使用HashMap并使用索引作为关键,但这是真的低效。

取决于。如果您使用的索引非常稀疏,那么使用Map可能会更好。如果指数趋于一致,我认为没有更好的办法比用空值填补它。只写它实用的功能,可以反复使用,而不是到处重复循环的你需要它,像这样:

private void padTo(List<?> list, int size) { 
    for (int i=list.size(); i<size; i++) 
     list.add(null); 
} 
+3

考虑在循环之前调用'list.ensureCapacity(size)'来避免不必要的内存重新分配。 – Mersenne 2012-02-10 16:48:38

+0

请注意,ensureCapacity(大小)实际上并不填充数组 - http://stackoverflow.com/questions/7688151/java-arraylist-ensurecapacity-not-working – 2016-02-09 23:18:27

3

您可以改为使用Map<Integer, MyClass>。具体而言,如果您使用HashMap,它也将是O(1) - 虽然它会比ArrayList慢。

1

听起来像是你想要的规则阵列:

  • 你想随机存取
  • 你想指定一些大尺寸
+0

您可以指定ArrayList的大小 – blank 2012-02-10 16:24:13

+3

不要这样想。这是最初分配的容量,但开始时的大小为零。 – pitosalas 2012-02-10 16:32:53

+0

如果存储在列表中的项目是通用的,则常规数组不是常规选项。 – 2017-05-23 15:33:21

1

如果你一定要使用列表,而不是一个地图,那么最好重写arraylist的add和set方法,以便先在索引中放置null。没有其他更好的办法IMO

3

您可以使用TreeMap<key, value>,这是在自然顺序由value排序。

在这里你可以保留价值作为索引。你可以插入任何值,它不需要按顺序。这似乎是最简单的解决方案。

+0

有关更多信息:https://github.com/谷歌/番石榴/维基/ UsingAndAvoidingNullExplained#特定案例 – Yar 2017-07-28 18:06:18

1

HashMap可能比你想象的低得多,试试吧。否则,我认为没有办法比循环和填充null更优雅。如果你至少想要展示高雅,那么你总是可以对ArrayList进行子类化并添加一个expandingSet(position,value)方法来隐藏所有的循环等等。也许这不是一个选项,但?如果不是只是在其他地方有一个实用方法,但这不是很好的imho,虽然它也可以与其他类型的列表也工作,我猜...

也许一个包装类将是两全其美的,或者它只是导致不必要的开销......

0

如果你正在寻找一个稀疏阵列(其中大部分指标将是空的),某种类型的地图(可能是HashMap)将是您最好的选择。任何阵列式解决方案将被迫为所有空索引预留空间,这不是非常节省空间的,并且HashMap对于大多数正常目的来说足够快。

如果您最终将阵列填充到n,您需要在循环中添加空值以获取所需的索引。你可以通过给它一个你最终想要存储的元素个数的初始容量来提高它的效率(这可以防止ArrayList需要调整自己的大小)。 new ArrayList(n)将正常工作。不幸的是,除了在创建循环时添加东西外,没有一种简单的方法可以使其成为特定的大小。

+0

我相信,设置“容量”不是'大小' – pitosalas 2012-02-10 16:32:23

+0

@pitosalas良好的捕获。现在修复它。 – Retief 2012-02-10 16:39:43