当位置很重要时,数组与ArrayList

时间:2013-12-06 00:50:52

标签: java arrays arraylist

我是一个快速Array vs. ArrayList问题的Java新手。我有一个可以增大或缩小的对象数组,但对我来说保持它们在数组中相对于彼此的位置非常重要。我正在考虑因为这个我需要使用Array而不是ArrayList,如果它们被删除/添加,它们可以压缩/移动元素。

实际例子:在我的第一个Java应用程序中,我正在学习这种语言的细微差别,我正在制作一个基本的扑克游戏模拟器。我有一个数组中的Player对象代表他们所在的座位,重要的是要知道经销商按钮(索引)在旋转之前的位置。从ArrayList中删除或添加的玩家将改变玩家的指数,并且可以甩掉下一个玩家获得它。经销商按钮移动特定于玩家位置。

长话短说 - 使用数组是处理数组类型结构中需要保持其在数组中位置的元素的最佳方法吗?有没有更好的方法或逻辑来实现这一目标?我为这个简单的问题道歉,但我找不到任何其他选择,并想确认这是最佳路线。

编辑:

为了进一步说明,让我举一个例子说明为什么ArrayList的元素移动不起作用: 在阵列中取三个玩家及其指数:

0:玩家一(经销商按钮) 1:玩家二 2:玩家三

如果玩家2(索引1)在经销商按钮旋转之前从桌面起飞,根据规则,玩家将保持按钮并且百叶窗将相应调整(还有其他变体这个规则,但我喜欢使用的那个)。在ArrayList中,内部数组将被压缩,玩家三将最终在按钮之前获得额外的一轮。我需要跟踪在手中活动的空座位,但在圆形结束并且按钮移动之前已经清空。

我开始意识到“座位”的概念将变得更加复杂,我需要跟踪它的状态,包括“玩家只是在进行中坐下来”,“玩家在手上起身正在进行中,“等等@Stephen P - 我认为你是对的,我将需要单独跟踪它们,不能使用简单的数组结构来确定逻辑。添加和/或删除元素的时间对于应用程序逻辑至关重要,只需检查元素是否存在就不会将其删除。

对于Seats本身,我正在学习ArrayList,因为Seats现在总是在那里,没有空。如果一个人坐在那里以及该玩家到达时,座位将只有一个玩家对象的引用。谢谢大家!

4 个答案:

答案 0 :(得分:2)

使用ArrayList,您可以使用set(int index,T value)让玩家坐稳。您只需要首先使用null填充arrayList:

List<Player> seats = new ArrayList<>(Collections.nCopies(numPlayers,(Player)null));
seats.set(2,player); // Place a player in the third chair
seats.set(1,null); // Empty the second chair

答案 1 :(得分:1)

  

长话短说 - 使用Array是处理元素的最佳方式   在数组类型结构中需要保持其位置   阵列?有没有更好的方法或逻辑来实现这一目标?一世   为简单的问题道歉,但我找不到任何其他问题   替代方案,并希望确认这是最佳途径   取。

位置不应该是选择数组与ArrayList最重要的标准,至少我不相信它应该是。

阵列是协变的,大多数时候性能更高。它们与Java泛型混合得很差(如果有的话),这在很多时候都是非常重要的。您无法创建对不可重新生成类型的数组的新实例的引用(尽管您可以收到一个,但买家要注意)。

作为Java Collections API的一部分,ArrayLists是不变的。因此,他们使用Java泛型可以更好地工作,并且根据Joshua Bloch(Essential Java,2nd Ed)的说法,它应该在很多时候都受到青睐。 ArrayLists通常应该比数组更低性能(并且更简洁)。此外,作为Java Collections API的一部分,ArrayLists更灵活,因为它们扩展了List接口,使您可以将实现从ArrayList更改为任何其他List,前提是您自己的实现List的类被很好地封装(即ArrayList不是你班级导出的API的一部分。)

当然,还有其他差异,但这些是真正脱颖而出的。如果你真的关心性能,你可以创建自己的List实现,它由数组支持(比如ArrayList),以获得你真正想要的功能或API契约。否则,对我来说,听起来你应该使用ArrayList(甚至是其他Collection类型,如Map(建议))。

答案 2 :(得分:0)

如果您拥有恒定数量的座位,则可以使用数组或ArrayAist。如果您想增加席位数,则需要Arraylist,因为常规数组是不可变的。有关阵列不变性的更多信息,请参阅此内容:Why is an array's length immutable?如果您仅使用ArrayListget(int index)

set(int index, E element)将永远不会移动其内容

此外,让null表示某些东西是不好的做法,即使这些东西什么都没有。

代码:

安排ArrayList初始化

List<Person> seats = new ArrayList<Person>(max_Number_Of_Seats_here);
for(Person person : seats)
{
    person = new Person("");
}
//You can then set people like this:
seats.set(seat_index_here, new Person("Darkprozac"));

将类Person的构造函数的参数作为其名称。

人员构造函数

...
public String name;
public Person(String name)
{
    this.name = name;
...

然后,您可以检查Person的{​​{1}}是否为name,如果是,请跳过该人:

检查座位是否为空

""

您还可以将... for(Person person : seats) { if(person.name.equals("")) { //do nothing } else { doSomething(); } } ... 包裹在Person类中:

座位等级

Seat

然后修改座位ArrayList初始化检查座位是否为空

感谢MrBackend指出我错误地将public class Seat { public Person person; public String state; public Seat(String name) { if(name.equals(""); { state = "empty"; } else { state = "full"; person = new Person(name); } } } 初始化为null。

答案 3 :(得分:0)

我会使用地图,特别是TreeMap

NavigableMap<Integer, Player> seats = new TreeMap<Integer, Player>();
Integer first = seats.firstKey();
Integer next = seats.nextKey(first);

这提供了地图的好处,您不必担心座位转移(甚至意外),您仍然可以轻松导航座位。

地图管理自己的存储(与数组不同),并且没有转移索引的风险(与ArrayList不同)。