1. 程式人生 > 實用技巧 >列表(List)

列表(List)

線性表

1. List是一個介面

介面:沒有欄位的抽象類

  • 類似於陣列,但陣列只能放統一型別的資料

  • 而List可以在其中放物件,物件可以用於許多個不同型別的屬性

    • 如Student的物件中可以包含name、age、hobby等等
  • 直接new List()需要重寫介面中的所有方法

    public class Test {
        public static void main(String[] args) {
            new List() {
                @Override
                public int size() {
                    return 0;
                }
    
                @Override
                public boolean isEmpty() {
                    return false;
                }
    
                @Override
                public boolean contains(Object o) {
                    return false;
                }
    
                @Override
                public Iterator iterator() {
                    return null;
                }
    
                @Override
                public Object[] toArray() {
                    return new Object[0];
                }
    
                @Override
                public boolean add(Object o) {
                    return false;
                }
    
                @Override
                public boolean remove(Object o) {
                    return false;
                }
    
                @Override
                public boolean addAll(Collection c) {
                    return false;
                }
    
                @Override
                public boolean addAll(int index, Collection c) {
                    return false;
                }
    
                @Override
                public void clear() {
    
                }
    
                @Override
                public boolean equals(Object o) {
                    return false;
                }
    
                @Override
                public int hashCode() {
                    return 0;
                }
    
                @Override
                public Object get(int index) {
                    return null;
                }
    
                @Override
                public Object set(int index, Object element) {
                    return null;
                }
    
                @Override
                public void add(int index, Object element) {
    
                }
    
                @Override
                public Object remove(int index) {
                    return null;
                }
    
                @Override
                public int indexOf(Object o) {
                    return 0;
                }
    
                @Override
                public int lastIndexOf(Object o) {
                    return 0;
                }
    
                @Override
                public ListIterator listIterator() {
                    return null;
                }
    
                @Override
                public ListIterator listIterator(int index) {
                    return null;
                }
    
                @Override
                public List subList(int fromIndex, int toIndex) {
                    return null;
                }
    
                @Override
                public boolean retainAll(Collection c) {
                    return false;
                }
    
                @Override
                public boolean removeAll(Collection c) {
                    return false;
                }
    
                @Override
                public boolean containsAll(Collection c) {
                    return false;
                }
    
                @Override
                public T[] toArray(Object[] a) {
                    return new T[0];
                }
            };
        }
    }
    

2. 通常使用ArrayList和LinkedList去實現List介面

  • ArrayList通過陣列實現,便於遍歷查詢
    • 追加元素,會新建一個把長度擴大一倍的陣列,把原來的元素都拷貝新的陣列中
  • LinkedList通過連結串列實現,便於增刪改

3. List不加泛型預設為Object型別的物件

public class Test01 {

    public static void main(String[] args) {
        List list = new ArrayList();
        list.add("hello");
        list.add("world");
        list.add("!");
        for (Object s : list) {
            System.out.println(s);
        }
    }

}
  • 但如果不規定泛型,當多個list出現,都是Object型別,難以區分,因此最好還是加上泛型約束

    public class Test01 {
    
        public static void main(String[] args) {
            List<String> list = new ArrayList();
            list.add("hello");
            list.add("world");
            list.add("!");
            for (String s : list) {
                System.out.println(s);
            }
        }
    
    }
    

4. List中都是引用物件,而不是在List中建立一個真實物件

  • 8種基本資料型別不能建立物件,因此會用到對應的包裝類

    //整型
    short ---> Short
    int ---> Integer
    long ---> Long
    //浮點型
    float ---> Float
    double ---> Double
    //字元型
    byte ---> Byte
    char ---> Character
    //布林型
    boolean ---> Boolean
    
    • 包裝類會進行自動裝箱和拆箱

      //自動裝箱
      Integer a = 10;//把10包裝成Integer型別賦給Integer型別的a
      //自動拆箱
      int b = a;//把a拆包裝後成為int型別賦值給int型別的b
      
      public class Test01 {
      
          public static void main(String[] args) {
              List<Integer> list = new ArrayList<>();
      
              list.add(10);
              list.add(100);
              list.add(1000);
      
              for (int num : list) {
                  System.out.println(num);
              }
          }
      }
      
  • 既然是引用物件需要滿足三個條件

    • 自反——x.equals(x) == true
    • 對稱性——x.equals(y) == y.equals(x)
    • 傳遞性——x.equals(y),y.equals(z),則x.equals(z)
public class Main {
    public static void main(String[] args) {
        List<Student> list = new ArrayList();
        list.add(new Student("小明",2345));
        list.add(new Student("小紅",2347));


        Student man = new Student("小明", 2345);

        //因為不是一個物件,所有直接列印會出false,需要重寫equals方法
        System.out.println(list.contains(man));//true
    }
}

class Student {
    String name;
    int age;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public boolean equals(Object obj) {
        boolean nameTF = false;
        boolean ageTF = false;

        if (obj instanceof Student) {
            Student stu = (Student) obj;
            if (this.name == null && stu.name == null) {
                nameTF =  true;
            } else if (this.name != null) {
                nameTF =  this.name.equals(stu.name);
            } else {
                nameTF =  false;
            }

            if (this.age == 0 && stu.age == 0) {
                ageTF =  true;
            } else if (this.age != 0) {
                ageTF =  (this.age ==stu.age);
            } else {
                ageTF =  false;
            }
        }

        return nameTF && ageTF;

    }
}
  • 在java9中還提供建立不可改變的List建立方式

    List<String> list = List.of("哈哈","嘿嘿");
    
    //無法改變
    list.set(1, "嗚嗚"); // Fails
    //不支援null
    List.of("haha", "嘿嘿", null); // 異常:NullPointerException