列表(List)
阿新 • • 發佈:2020-12-06
線性表
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