Java LinkedList.com包含执行速度
为什么Methode LinkedList.contains()的运行速度比这种实现快:Java LinkedList.com包含执行速度,java,algorithm,Java,Algorithm,为什么Methode LinkedList.contains()的运行速度比这种实现快: for (String s : list) if (s.equals(element)) return true; return false; 我不认为这与实现有很大的区别(我认为搜索对象不是空的),同样的迭代器,等于操作让我们看看(代码的)OpenGDK版本。java。UTIL.LIKEDLISTAB//COD>< /P> public boolean contains(Object
for (String s : list)
if (s.equals(element))
return true;
return false;
<>我不认为这与实现有很大的区别(我认为搜索对象不是空的),同样的迭代器,等于操作让我们看看(代码的)OpenGDK版本。java。UTIL.LIKEDLISTAB//COD>< /P>
public boolean contains(Object o) {
return indexOf(o) != -1;
}
public int indexOf(Object o) {
int index = 0;
if (o==null) {
/* snipped */
} else {
for (Entry e = header.next; e != header; e = e.next) {
if (o.equals(e.element))
return index;
index++;
}
}
return -1;
}
正如你所看到的,这是一个线性搜索,就像对每个解的搜索一样,所以它不是渐进的更快。看看你的数字是如何随着更长的列表而增长的是很有趣的,但这很可能是一个不变的因素
这样做的原因是,indexOf
在内部结构上工作,使用直接字段访问进行迭代,而for-each使用迭代器
,迭代器的方法还必须额外检查ConcurrentModificationException
等内容
回到源代码,您会发现LinkedList的迭代器返回的E next()
方法如下:
private class ListItr implements ListIterator<E> {
//...
public E next() {
checkForComodification();
if (nextIndex == size)
throw new NoSuchElementException();
lastReturned = next;
next = next.next;
nextIndex++;
return lastReturned.element;
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
私有类ListItr实现ListIterator{
//...
公共教育{
checkForComodification();
如果(nextIndex==大小)
抛出新的NoTouchElementException();
lastReturned=next;
next=next.next;
nextIndex++;
return lastReturned.element;
}
最终作废检查共修改(){
if(modCount!=预期的modCount)
抛出新的ConcurrentModificationException();
}
这比LinkedList中的e=e.next;
要忙得多。包含!迭代器()LinkedList的
实际上是一个,它具有更丰富的功能。在for-each循环中不需要它们,但不幸的是,无论如何你都必须为它们付费。更不用说对ConcurrentModificationException的所有防御性检查
都必须执行,即使在此期间不会对列表进行任何修改您正在迭代它
结论
因此,是的,使用for-each(或者更直接地说,使用其迭代器()/listIterator()
)作为客户端迭代LinkedList
)比LinkedList
本身内部所能做的成本更高。这是意料之中的,这就是为什么首先提供contains
内部工作为LinkedList提供了巨大的优势,因为:
- 它可以在防御检查中抄近路,因为它知道它没有违反任何不变量
- 它可以使用快捷方式并使用其内部表示
因此,您可以从中学到什么呢?熟悉API!看看已经提供了哪些功能;它们可能比作为客户机复制它们更快。我决定对此进行测试,并得出了一些有趣的结果
导入java.util.LinkedList
公共类包含{
private LinkedList<String> items = new LinkedList<String>();
public Contains(){
this.addToList();
}
private void addToList(){
for(int i=0; i<2000; i++){
this.items.add("ItemNumber" + i);
}
}
public boolean forEachLoop(String searchFor){
for(String item : items){
if(item.equals(searchFor))
return true;
}
return false;
}
public boolean containsMethod(String searchFor){
if(items.contains(searchFor))
return true;
return false;
}
有趣的是,当我运行JUnit测试时,结果是:
-testForEachLoop()-0.014s
-testContainsMethod()-0.025s
这是真的还是我做错了什么?您测试过它并发现它运行得更快吗?还是您在假设?LinkedList.contains()的优点是,其他程序员不需要了解您的意图。
import static org.junit.Assert.assertEquals;
import org.junit.Test;
public class ContainsTest {
@Test
public void testForEachLoop(){
Contains c = new Contains();
boolean result = c.forEachLoop("ItemNumber1758");
assertEquals("Bug!!", true, result);
}
@Test
public void testContainsMethod(){
Contains c = new Contains();
boolean result = c.containsMethod("ItemNumber1758");
assertEquals("Bug!!", true, result);
}
}