更好的做法是在ArrayList中创建临时副本以减少计算时间和复杂性吗?

huangapple go评论133阅读模式
英文:

Is it better to make temporary copies of elements in an ArrayLists to reduce computing time and complexity?

问题

以下是您要求的翻译内容:

我有一个包含对象 card 的 ArrayList,这些对象具有属性 (int) value(String) symbol(String) image,以及对应的 getter 方法。

ArrayList<card> cardDeck = new ArrayList<>();

cardDeck 包含了52个元素,每个元素都是一个卡片对象。现在,如果我想打印出 cardDeck 中的所有卡片,有两种简单的解决方案:

第一种解决方案:

for(int i = 0; i < cardDeck.size(); i++){
    System.out.println((i + 1) + ". card:");
    System.out.println(cardDeck.get(i).getValue());
    System.out.println(cardDeck.get(i).getSymbol());
    System.out.println(cardDeck.get(i).getImage());
}

第二种解决方案:

for(int i = 0; i < cardDeck.size(); i++){
    card temp = cardDeck.get(i);
    System.out.println((i + 1) + ". card:");
    System.out.println(temp.getValue());
    System.out.println(temp.getSymbol());
    System.out.println(temp.getImage());
}

我的问题是,这两种方法在执行时间或复杂性方面是否有任何明显的差异。一开始,第一种解决方案中,程序在打印信息之前每次都需要先在 ArrayList 中查找卡片。而在第二种解决方案中,由于创建了临时副本,情况并非如此。然而,再仔细考虑一下,在第二种解决方案中,程序仍然需要在每次调用时查找临时卡片对象的信息。欢迎提供任何帮助、想法或建议!

英文:

I've got an ArrayList consiting of objects card, which have the attributes (int) value, (String) symbol and (String) image and to them belonging getters.

ArrayList&lt;card&gt; cardDeck = new ArrayList&lt;&gt;();

cardDeck has self-explanatory 52 elements, each a card object.
Now, if I want to print out all the cards in cardDeck there are two simple solutions:
<hr>
First solution:

for(int i = 0; i &lt; cardDeck.size(); i++){
    System.out.println((i + 1) + &quot;. card:&quot;);
    System.out.println(cardDeck.get(i).getValue());
    System.out.println(cardDeck.get(i).getSymbol());
    System.out.println(cardDeck.get(i).getImage());
}

Second solution:

for(int i = 0; i &lt; cardDeck.size(); i++){
    card temp = cardDeck.get(i);
    System.out.println((i + 1) + &quot;. card:&quot;);
    System.out.println(temp.getValue());
    System.out.println(temp.getSymbol());
    System.out.println(temp.getImage());
}

My question is, if there are any noticeable difference in either execution time or complexity.
On the first thought, in the first solution the program would have to look up the card in the ArrayList first every time, before being able to print its info. Which isn't the case in the second solution, as a temporary copy was made.
On second thought though, even in the second solution, the program would still need to look up the info of the temporary card object with every call.
Any help / ideas / advice appreciated!

答案1

得分: 2

所以我们有

  • 在第一个解决方案中有3次数组查找(使用相同的索引且数组上无修改,因此编译器可能会进行优化)。
  • 在第一个解决方案中存在容易出错的代码(如果你需要将索引更改为i+1并忘记在所有3个位置修正代码会发生什么)。

相对地:

  • 在第二个解决方案中只有1次数组查找 - 经过优化,而不依赖于编译器。
  • 在第二个解决方案中有更易读的代码(如果你将temp替换为card,可以在正确将类名以大写字母开头的情况下这样做:Card card)。

在Java中,数组查找并不是那么廉价的操作 - 数组会受到保护(边界检查)以防止缓冲区溢出注入漏洞。

因此,有两个非常充分的理由建议你采用第二个解决方案

英文:

So we have

  • 3 array lookups (with the same index and no modification on the array, so the compiler MAY optimize it) in the first solution
  • error prone code in the first solution (what happens if you need to change the index to i+1 and forget to correct the code in all 3 places)

versus:

  • 1 array lookup in the second solution - optimized without relying on the compiler
  • better readable code in the second solution (if you replace temp by card, which you can do if you properly start the class name uppercase: Card card)

Array lookups are not that cheap in Java - the arrays are guarded (bounds checks) to prevent buffer overflow injection vulnerabilities.

So you have two very good reasons that tell you to go with the second solution.

答案2

得分: 1

使用Java 8,

    cardDeck.parallelStream().forEach(card -&gt; {System.out.println(card.getValue());System.out.println(card.getSymbol());System.out.println(card.getImage());});

这并不保证更好的性能,而是取决于可用的CPU核心数量。

英文:

Using Java 8,

    cardDeck.parallelStream().forEach(card -&gt; {System.out.println(card.getValue());System.out.println(card.getSymbol());System.out.println(card.getImage());});

This does not guarantee better performance, this depends on the number of CPU cores available.

答案3

得分: 1

Peter已经说过,从编程的角度来看,什么是更好的想法。
我想补充一下,楼主问了关于复杂性的问题。我理解这是指与卡牌组大小相关的渐近时间要求。

答案是,从理论复杂性的角度来看,这两种方法都是相同的。每次数组查找都会在所需的时间上添加一个恒定因子。都是O(n),其中n是卡牌数量。

另外,楼主也问了关于复制列表元素的问题。只是为了澄清一下:语句card temp = cardDeck.get(i)不会导致第i个列表元素被复制。temp变量现在只是指向在运行循环时位于cardDeck的第i位置的元素。

英文:

Peter has already said what would be the better idea from the programming perspective.
I want to add that the OP asked about complexity. I interpret that in the sense of asymptotical time required in relation to the size of the card deck.

The answer is that from a theoretical complexity perspective, both approaches are the same. Each array lookup adds a constant factor to required time. It's both O(n) with n being the number of cards.

On another note, the OP asked about copying elements of the list. Just to make it clear: The statement card temp = cardDeck.get(i) does not cause the ith list element to be copied. The temp variable now just points to the element that is located at the ith position of cardDeck at the time of running the loop.

答案4

得分: 0

首先,你还有其他的解决方案,例如使用 for-each 循环或者使用带有 lambda 表达式的 forEatch 方法。关于速度,只有当你的程序在普通计算机上运行并且不必处理性能较弱或低的处理器时,才不需要担心速度问题。但在你的情况下,你可以通过使用函数式编程使你的应用程序变得不那么复杂,例如:

cardDec.forEatch(card) -> {
    System.out.println(card.getValue());
    System.out.println(card.getSymbol());
    System.out.println(card.getImage());
};
英文:

First, you have other solutions for example, using for eatch loop or using forEatch method with lambda expressions.
And about speed, you don't have to worry about speed until your program runs in regular computers and you don't have to deal with weak or low processors, but in your case, you can make your app less complex with using functional programming e.g,

cardDec.forEatch(card) -&gt; {
    System.out.println(card.getValue());
    System.out.println(card.getSymbol());
    System.out.println(card.getImage());

};

huangapple
  • 本文由 发表于 2020年4月6日 18:48:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/61058049.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定