Javaコレクションのリスト

7421 ワード

目次
  • 前言
  • 本文
  • Listの特徴は?
  • Listの一般的な方法は?
  • Listの常用サブクラス?
  • ArrayList?
  • LinkedList?
  • Vector?



  • 前言
    本編は集合フレームワークの第2編(第1編は集合フレームワーク(一)を参照可能)であり、主な内容は、Listインタフェースの特徴、Listインタフェースの常用方法、Listインタフェースの常用サブクラスである.重点部分は依然として赤いフォントで表示されます.
    本文
    リストの特徴は?
  • jdkドキュメントのListに対する記述では、まず目に入る2つの字が「秩序」である.この順序とは、具体的には、データが集合に格納される順序が、昇順または降順ではなく、集合からデータを取り出す順序と一致することを意味する.
  • Listには「インデックス」があるので、リスト内の各要素の挿入位置を正確に制御できます.
  • リストでは、通常、重複する要素が許可されます.

  • リストの一般的な方法は?
    リストにインデックスがあると述べたので、リスト特有の一般的な方法には、インデックスを操作できるという共通の特徴があります.
    // List           
    
    1、  
        void add(index, element);
        void add(index, collection);
    
    2、  ;
        Object remove(index):      //  :      
    
    3、  :
        Object set(index, element);
    
    4、  :
        Object get(index);      //     iterator    
        int indexOf(object);
        int lastIndexOf(object);
        List subList(from, to);
    
    

    次のコードに注意してください.
    
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;
    
    public class Test {
    
        public static void main(String[] args) {
            List list = new ArrayList();
    
            list.add("abc1");
            list.add("abc2");
            list.add("abc3");
    
            Iterator it = list.iterator();    // 1
            while(it.hasNext()) {
                Object obj = it.next();    // ConcurrentModificationException
    
                if(obj.equals("abc2")) {
                    list.add("abc9");   // 2
                }
                else {
                    System.out.println("next:" + obj);
                }
            }
    
        }
    }
    
    

    jdkドキュメントでは、メソッドがオブジェクトの同時変更を検出したが、この変更が許可されていない場合に、この例外を放出することについて、上記のC o n c u r r e ntModificationExceptionについて説明しています.上のコードを解析すると,コード1の反復器オブジェクトは3つの要素を持つlist集合に基づいて取得され,コード2の場合はlist集合にもう1つの要素を追加したいが,反復器オブジェクトが集合オブジェクトを操作すると同時に集合もこれらのオブジェクトを操作しているため,エラーが報告される.ソリューションは次のとおりです.
    
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;
    import java.util.ListIterator;
    
    public class Test {
    
        public static void main(String[] args) {
            List list = new ArrayList();
    
            list.add("abc1");
            list.add("abc2");
            list.add("abc3");
            System.out.println("list:" + list);
    
            ListIterator it = list.listIterator();    //                             。 :  list     。
    
            while(it.hasNext()) {
                Object obj = it.next();
    
                if(obj.equals("abc2")) {
                    it.add("abc9");
    //                it.set("abc9");
                }
            }
    
            System.out.println("list:" + list);
        }
    }
    
    

    Listの常用サブクラス?
    この部分について私たちの説明の構想は:まずそれぞれの特徴を明確にして、具体的なシーンがどれを使うべきかを知っています;それぞれが持っているいくつかの方法を再分析します.どちらもjdkドキュメントを表示することで知ることができます.
    ArrayList?
    ArrayList内部のデータ構造は配列であり、50%延長により可変長配列を実現する.jdk 1から2同期ではなく、Vectorに代わって現れ始めました.配列が持つ特性(メモリ内の空間連続)のため、クエリー操作が高速です.
    ArrayListは一般的にカスタムオブジェクトを格納するために使用されます.以下のようにします.
    
    import java.util.ArrayList;
    import java.util.Iterator;
    
    class Person {
    
        private String name;
        private int age;
    
        public Person() {
            super();
        }
        public Person(String name, int age) {
            super();
            this.name = name;
            this.age = age;
        }
    
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
        public String toString(){
            return name+":"+age;
        }
    
    }
    
    class Demo {
        public static void main(String[] args) {
            ArrayList al = new ArrayList();
            al.add(new Person("lisi1", 21));
            al.add(new Person("lisi2", 22));
            al.add(new Person("lisi3", 23));
            al.add(new Person("lisi4", 24));
    
            Iterator it = al.iterator();
            while(it.hasNext()){
                Person p = (Person) it.next();     //            
                System.out.println(p.getName() + ":" + p.getAge());
            }
        }
    }
    
    

    ArrayListにはensureCapacity()があり、ArrayListに多くの要素を追加する前にこのメソッドを呼び出すことができ、インクリメンタル再割り当ての回数を減らすことができます.
    
    import java.util.*;
    
    public class Test {
        public static void main(String[] args) {
            ArrayList list = new ArrayList();
            final int N = 10000000;
            list = new ArrayList();
            long startTime1 = System.currentTimeMillis();
            list.ensureCapacity(N);
            for (int i = 0; i < N; i++) {
                list.add(i);
            }
            long endTime1 = System.currentTimeMillis();
            System.out.println("  ensureCapacity   :"+(endTime1 - startTime1));
        }
    
    }
    
    import java.util.*;
    
    public class Test {
        public static void main(String[] args) {
            ArrayList list = new ArrayList();
            final int N = 10000000;
            long startTime = System.currentTimeMillis();
            for (int i = 0; i < N; i++) {
                list.add(i);
            }
            long endTime = System.currentTimeMillis();
            System.out.println("  ensureCapacity   :"+(endTime - startTime));
        }
    }
    
    

    LinkedList?
    LinkedList内部のデータ構造は双方向チェーンテーブルである.同期していませんチェーンテーブルの特性(メモリ内の空間が不連続)のため、削除操作が速くなります.
    LinkedListメソッドの使用については、次の点に注意してください.
  • LinkedListのaddXxx()とremoveXxx()を参照してください:
  • 
    import java.util.LinkedList;
    
    class Demo {
        public static void main(String[] args) {
            LinkedList link = new LinkedList();
    
            link.addFirst("abc1");
            link.addFirst("abc2");
            link.addFirst("abc3");
            link.addFirst("abc4");
    		System.out.println(link);
    		System.out.println(link.getFirst());      //          。
    		System.out.println(link.getFirst());
            System.out.println();
    
    		System.out.println(link.removeFirst());   //          。
    		System.out.println(link.removeFirst());
            System.out.println(link);
        }
    }
    
    

    上記のコードがあれば、LinkedListのaddFirst()とremoveFirst()[またはaddLast()とremoveLast()でスタックデータ構造を実現し、addFirst()とremoveLast()[またはaddLast()とremoveFirst()]でキューデータ構造を実現することができます.
  • jdk 1から.6バージョンからLinkedListにはofferXxx()、peekXxx()、pollXxx()が追加され、これら3つの機能はそれぞれaddXxx()、getXxx()、removeXxx()に相当します.違いはLinkedListに要素がない場合、getXxx()、removeXxx()は「NoSuchElementException」を投げ出し、peekXxx()、pollXxx()はnullを返すことであり、これらの方法を操作する前に判断できることを意味する.

  • Vector?
    Vector内部のデータ構造も配列であり、100%延長することで可変長配列を実現する.jdk 1から0は同期しています削除やクエリーの操作が遅いです.
    Vectorメソッドの使用について注意しなければならないのはEnumerationインタフェースです.
    
    import java.util.Enumeration;
    import java.util.Iterator;
    import java.util.Vector;
    
    class Demo {
        public static void main(String[] args) {
    
            Vector v = new Vector();
    
            v.addElement("abc1");
            v.addElement("abc2");
            v.addElement("abc3");
            v.addElement("abc4");
    
            Enumeration en = v.elements();
            while (en.hasMoreElements()) {
                System.out.println("nextelment:" + en.nextElement());
            }
        }
    }
    
    

    Enumerationインタフェースの機能はIteratorインタフェースの機能と重複している.さらに、Iteratorインタフェースには、オプションの削除操作が追加され、短いメソッド名が使用されます.新しい実装では、EnumerationインタフェースではなくIteratorインタフェースの使用を優先する必要があります.