ホームページ Java &#&チュートリアル Java で ArrayList と LinkedList を使用する場合は?

Java で ArrayList と LinkedList を使用する場合は?

Nov 28, 2019 pm 04:10 PM
arraylist linkedlist

Java で ArrayList と LinkedList を使用する場合は?

ArrayList または LinkedList をいつ使用する必要がありますか?

ArrayList と LinkedList は、Java コレクションにオブジェクトを格納するために使用されます。フレームワーク リストを参照する 2 つのクラス。 ArrayList と LinkedList はどちらも List インターフェイスを実装します。まず、リストについて簡単に理解しましょう。

リスト (リスト) は、順序付けられた要素のコレクションであり、シーケンスとも呼ばれます。これは、リスト内の特定のインデックス位置にある要素にすばやくアクセス、追加、削除するのに役立つ要素位置ベースの操作を提供します。 List インターフェイスは、Collection と Iterable を親インターフェイスとして実装します。重複値や null 値を保存でき、インデックスを介した要素へのアクセスもサポートされます。

この記事を読んだ後に明確にするべき質問: ArrayList と LinkedList の違いは何ですか?どのような場合に ArrayList を使用し、どのような場合に LinkedList を使用する必要がありますか?

(推奨ビデオ: java ビデオ チュートリアル)

以下を追加しますArrayList と LinkedList の違いを比較するために要素を削除する例を取り上げます。

リストの末尾に要素を追加します:

要素をリストの末尾に追加するコードArrayList のキューは次のとおりです。

public boolean add(E e){
   ensureCapacity(size+1);//确保内部数组有足够的空间
   elementData[size++]=e;//将元素加入到数组的末尾,完成添加
   return true;      
}
ログイン後にコピー

ArrayList の add() メソッドのパフォーマンスは、ensureCapacity() メソッドによって決まります。 ensureCapacity() の実装は次のとおりです。

public vod ensureCapacity(int minCapacity){
  modCount++;
  int oldCapacity=elementData.length;
  if(minCapacity>oldCapacity){    //如果数组容量不足,进行扩容
      Object[] oldData=elementData;
      int newCapacity=(oldCapacity*3)/2+1;  //扩容到原始容量的1.5倍
      if(newCapacitty<minCapacity)   //如果新容量小于最小需要的容量,则使用最小
                                                    //需要的容量大小
         newCapacity=minCapacity ;  //进行扩容的数组复制
         elementData=Arrays.copyof(elementData,newCapacity);
  }
}
ログイン後にコピー

ArrayList の現在の容量が十分に大きい限り、add() 操作は非常に効率的であることがわかります。拡張は、ArrayList の容量要件が現在の配列サイズを超える場合にのみ必要です。拡張プロセス中に、多数の配列コピー操作が実行されます。配列がコピーされると、最終的に System.arraycopy() メソッドが呼び出されるため、add() 操作の効率は依然として非常に高くなります。

LinkedList の add() オペレーションは次のように実装されます。また、任意の要素をキューの末尾に追加します:

public boolean add(E e){
   addBefore(e,header);//将元素增加到header的前面
   return true;
}
ログイン後にコピー

addBefore() メソッドが実装されます

private Entry<E> addBefore(E e,Entry<E> entry){
     Entry<E> newEntry = new Entry<E>(e,entry,entry.previous);
     newEntry.provious.next=newEntry;
     newEntry.next.previous=newEntry;
     size++;
     modCount++;
     return newEntry;
}
ログイン後にコピー

LinkeList はリンク リストの構造を使用しているため、容量のサイズを維持する必要がないことがわかります。この観点から見ると、ArrayList よりもパフォーマンスに一定の利点がありますが、要素を追加するたびに新しい Entry オブジェクトと追加の代入操作が必要になります。頻繁なシステムコールはパフォーマンスに一定の影響を与えます。

リスト内の任意の位置に要素を追加する

List インターフェースは、List の最後に要素を提供するだけでなく、任意の位置に要素を挿入するメソッドも提供します。 Position: void add(int index,E element);

実装が異なるため、このメソッドの ArrayList と LinkedList の間には特定のパフォーマンスの違いがあります。ArrayList は配列に基づいて実装されており、配列は連続メモリであるためです。配列内のスペース (配列内の場合) 任意の位置に要素を挿入すると、必然的にその位置以降のすべての要素が再配置されるため、効率は比較的低くなります。

次のコードは ArrayList での実装です:

public void add(int index,E element){
   if(index>size||index<0)
      throw new IndexOutOfBoundsException(
        "Index:"+index+",size: "+size);
         ensureCapacity(size+1);
         System.arraycopy(elementData,index,elementData,index+1,size-index);
         elementData[index] = element;
         size++;
}
ログイン後にコピー

各挿入操作で配列のコピーが発生することがわかります。リストの末尾に要素を追加する場合、この操作は存在しません。配列の再編成操作が多数行われると、システムのパフォーマンスが低下します。また、挿入された要素がリスト内で前にあるほど、配列の再編成のコストが大きくなります。

そして、現時点での LinkedList の利点を示します。

public void add(int index,E element){
   addBefore(element,(index==size?header:entry(index)));
}
ログイン後にコピー

LinkedList の場合、リストの最後にデータを挿入することは、任意の位置にデータを挿入することと同じであることがわかります。挿入されたデータの影響を受けませんが、挿入メソッドのパフォーマンスは前方位置により低下します。

任意の位置の要素を削除する

要素を削除する場合、List インターフェイスには任意の位置の要素を削除するメソッドが用意されています。

public E remove(int index);
ログイン後にコピー

ArrayList の場合、remove() メソッドと add() メソッドは同じです。任意の位置の要素を削除した後は、配列を再編成する必要があります。 ArrayList の実装は次のとおりです。

public E remove(int index){
   RangeCheck(index);
   modCount++;
   E oldValue=(E) elementData[index];
  int numMoved=size-index-1;
  if(numMoved>0)
     System.arraycopy(elementData,index+1,elementData,index,numMoved);
     elementData[--size]=null;
     return oldValue;
}
ログイン後にコピー

ArrayList 内のすべての有効な要素削除操作の後に、配列を再編成する必要があることがわかります。また、削除された位置が早いほど、配列の再編成のオーバーヘッドが大きくなります。

public E remove(int index){
  return remove(entry(index));         
}
private Entry<E> entry(int index){
  if(index<0 || index>=size)
      throw new IndexOutBoundsException("Index:"+index+",size:"+size);
      Entry<E> e= header;
      if(index<(size>>1)){//要删除的元素位于前半段
         for(int i=0;i<=index;i++)
             e=e.next;
     }else{
         for(int i=size;i>index;i--)
             e=e.previous;
     }
         return e;
}
ログイン後にコピー

LinkedList の実装では、最初に削除する要素をループによって見つける必要があります。削除する位置がリストの前半の場合は前から後ろへ、後半の場合は後ろから前へ検索します。したがって、前の要素を削除する場合も後の要素を削除する場合も非常に効率的ですが、リストの途中の要素を削除するには、リストのほぼ半分を走査する必要があります。効率が非常に低いです。

Capacity パラメーター

capacity パラメーターは、ArrayList や Vector などの配列ベースのリストの一意のパフォーマンス パラメーターです。初期化された配列のサイズを表します。 ArrayList に格納されている要素の数が既存のサイズを超えた場合。これは拡張され、配列の拡張により配列全体のメモリ コピーが発生します。したがって、適切な配列サイズは配列拡張の回数を減らし、システムのパフォーマンスを向上させるのに役立ちます。

public  ArrayList(){
  this(10);  
}
public ArrayList (int initialCapacity){
   super();
   if(initialCapacity<0)
       throw new IllegalArgumentException("Illegal Capacity:"+initialCapacity)
      this.elementData=new Object[initialCapacity];
}
ログイン後にコピー

ArrayList は、初期配列サイズを指定できるコンストラクターを提供します:

public ArrayList(int initialCapacity)
ログイン後にコピー

现以构造一个拥有100万元素的List为例,当使用默认初始化大小时,其消耗的相对时间为125ms左右,当直接制定数组大小为100万时,构造相同的ArrayList仅相对耗时16ms。

遍历列表

遍历列表操作是最常用的列表操作之一,在JDK1.5之后,至少有3中常用的列表遍历方式:

● forEach操作

● 迭代器

● for循环。

String tmp;
long start=System.currentTimeMills();    //ForEach 
for(String s:list){
    tmp=s;
}
System.out.println("foreach spend:"+(System.currentTimeMills()-start));
start = System.currentTimeMills();
for(Iterator<String> it=list.iterator();it.hasNext();){    
   tmp=it.next();
}
System.out.println("Iterator spend;"+(System.currentTimeMills()-start));
start=System.currentTimeMills();
int size=;list.size();
for(int i=0;i<size;i++){                     
    tmp=list.get(i);
}
System.out.println("for spend;"+(System.currentTimeMills()-start));
ログイン後にコピー

构造一个拥有100万数据的ArrayList和等价的LinkedList,使用以上代码进行测试,测试结果:

Java で ArrayList と LinkedList を使用する場合は?

什么情况用ArrayList or LinkedList呢?

可以看到,最简便的ForEach循环并没有很好的性能表现,综合性能不如普通的迭代器,而是用for循环通过随机访问遍历列表时,ArrayList表项很好,但是LinkedList的表现却无法让人接受,甚至没有办法等待程序的结束。这是因为对LinkedList进行随机访问时,总会进行一次列表的遍历操作。性能非常差,应避免使用。

总结

ArrayList和LinkedList在性能上各有优缺点,都有各自所适用的地方,总的说来可以描述如下:

1.对ArrayList和LinkedList而言,在列表末尾增加一个元素所花的开销都是固定的。

对ArrayList而言,主要是在内部数组中增加一项,指向所添加的元素,偶尔可能会导致对数组重新进行分配;

而对LinkedList而言,这个开销是统一的,分配一个内部Entry对象。

2.在ArrayList的中间插入或删除一个元素意味着这个列表中剩余的元素都会被移动;而在LinkedList的中间插入或删除一个元素的开销是固定的。

3.LinkedList不支持高效的随机元素访问。

4.ArrayList的空间浪费主要体现在在list列表的结尾预留一定的容量空间,而LinkedList的空间花费则体现在它的每一个元素都需要消耗相当的空间

本文来自php中文网,java教程栏目,欢迎学习!  

以上がJava で ArrayList と LinkedList を使用する場合は?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Java ArrayList を走査するときに要素を削除するために foreach と iterator を使用することの違いは何ですか? Java ArrayList を走査するときに要素を削除するために foreach と iterator を使用することの違いは何ですか? Apr 27, 2023 pm 03:40 PM

1. Iterator と foreach の違いはポリモーフィックな違いです (foreach の最下層は Iterator です) Iterator はインターフェイス型であり、コレクションや配列の型を気にしません; for と foreach の両方がコレクションの型を知る必要がありますまず、コレクション内の要素の種類についても; 1. foreach の最下層はイテレータによって記述されたコードであると言われる理由: 逆コンパイルされたコード: 2. foreach の削除とイテレータの違い まず、Alibaba を見てください。 Java 開発マニュアル。ただし、ケース 1 ではエラーは報告されず、ケース 2 (java.util.ConcurrentModificationException) では最初にエラーが報告されます。

JavaでArrayListに特定の要素が含まれているかどうかを確認するにはどうすればよいですか? JavaでArrayListに特定の要素が含まれているかどうかを確認するにはどうすればよいですか? Sep 03, 2023 pm 04:09 PM

List インターフェイスの contains() メソッドを使用して、リストにオブジェクトが存在するかどうかを確認できます。 contains() メソッド booleancontains(Objecto) このリストに指定された要素が含まれる場合、true を返します。より正式には、このリストに (o==null?e==null:o.equals(e)) のような要素 e が少なくとも 1 つ含まれる場合にのみ true を返します。パラメータ c - このリスト内の存在がテストされる要素。戻り値 このリストに指定された要素が含まれている場合は true を返します。 ClassCastException をスローします - 指定された要素の型がこのリストと互換性がない場合 (オプション)。 NullP

JavaのArrayList.remove()関数を使用してArrayListから要素を削除します。 JavaのArrayList.remove()関数を使用してArrayListから要素を削除します。 Jul 24, 2023 pm 01:21 PM

Java の ArrayList.remove() 関数を使用して、ArrayList から要素を削除します。Java では、ArrayList は、要素のセットを保存および操作するためによく使用されるコレクション クラスです。 ArrayList クラスは、コレクション内の要素を追加、削除、変更、クエリするためのメソッドを多数提供します。より頻繁に使用されるメソッドの 1 つは、ArrayList から要素を削除できる Remove() です。 ArrayList のremove() メソッドには 2 つのオーバーロード形式があります。

LinkedList クラスのremoveLast() メソッドを使用して、リンク リストの最後の要素を削除します。 LinkedList クラスのremoveLast() メソッドを使用して、リンク リストの最後の要素を削除します。 Jul 24, 2023 pm 05:13 PM

リンク リストの最後の要素を削除するには、LinkedList クラスの RemoveLast() メソッドを使用します。LinkedList は、Java コレクション フレームワークの一般的なデータ構造です。要素は二重リンク リストの形式で格納されます。 LinkedList クラスが提供するメソッドを使用すると、要素の追加、削除、変更など、リンク リストを簡単に操作できます。シナリオによっては、リンクされたリストの最後の要素を削除する必要がある場合があります。 LinkedList クラスは、removeLas を提供します

Java の ArrayList の初期容量が 10 である理由は何ですか? Java の ArrayList の初期容量が 10 である理由は何ですか? May 10, 2023 pm 02:19 PM

HashMap の初期容量が 16 なのはなぜですか? ArrayList の初期化能力について話すときは、まず HashMap の初期化能力を確認する必要があります。 Java8 ソース コードを例にとると、HashMap には初期化容量と負荷係数という 2 つの関連要素があります。 /***Thedefaultinitialcapacity-MUSTbeapoweroftwo.*/staticfinalintDEFAULT_INITIAL_CAPACITY=1>1);if(newCapacity-minCapacity0)newCapacity=hugeCapacity

Java の ArrayList.clear() 関数を使用して、ArrayList 内の要素をクリアします。 Java の ArrayList.clear() 関数を使用して、ArrayList 内の要素をクリアします。 Jul 24, 2023 pm 02:04 PM

Java の ArrayList.clear() 関数を使用して、ArrayList 内の要素をクリアします。Java プログラミングでは、ArrayList は、要素を動的に保存およびアクセスできる非常に一般的に使用されるデータ構造です。ただし、場合によっては、メモリを再利用または解放するために、ArrayList 内のすべての要素をクリアする必要がある場合があります。このとき、ArrayList の clear() 関数を使用してこれを実現できます。 ArrayList.clear()

Java は、ArrayList クラスの contains() 関数を使用して、要素が存在するかどうかを判断します。 Java は、ArrayList クラスの contains() 関数を使用して、要素が存在するかどうかを判断します。 Jul 24, 2023 pm 07:33 PM

Java は、ArrayList クラスの contains() 関数を使用して、要素が存在するかどうかを判断します。ArrayList は、Java プログラミングで非常に一般的に使用されるデータ構造です。これは、一連のデータを保存および操作するための柔軟な方法を提供します。 ArrayList は、単純に要素を追加、削除、アクセスするだけでなく、要素が ArrayList に存在するかどうかを判断するために使用される contains() 関数など、いくつかの便利なメソッドも提供します。 contains() 関数は A

LinkedList に要素を追加する Java プログラム LinkedList に要素を追加する Java プログラム Aug 26, 2023 pm 10:21 PM

LinkedList は JavaCollectionFramework の一般クラスで、List、Deque、Queue の 3 つのインターフェイスを実装します。これは、各要素が相互にリンクされている線形データ構造である LinkedList データ構造の機能を提供します。 LinkedList に対して、要素の追加、削除、走査などのさまざまな操作を実行できます。 LinkedList コレクションに要素を追加するには、add()、addFirst()、addLast() などのさまざまな組み込みメソッドを使用できます。これらのメソッドを使用して要素を LinkedList に追加する方法を検討します。 Javaで

See all articles