Java集合Set,List和Map等
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Java集合Set,List和Map等
1 Java集合框架
因為Java是面向對象的語言,對事物的體現都是以對象的形式,為了方便對多個對象的操作,就要對對象進行存儲。另一方面,使用Array存儲對象方面具有一些弊端 。Java集合就像一個容器,可以把多個對象的引用放入容器中,它們可以幫我們方便地組織和管理一組對象。
數據的弊端:①數組初始化后,就確定長度了(長度不可改變,便于擴展)②聲明時的類型,就決定了進行元素初始化時的類型③提供的屬性和方法少,不便于進行添加、刪除、插入等操作,且效率不高,也無法直接獲取存儲元素的個數④數組存儲的數據是有序的、可以重復的(比較單一)。
Java 集合類可以用于存儲數量不等的多個對象,還可用于保存具有映射關系的關聯數組。
Java 集合可以分為兩大集合體系Collection和Map。集合框架圖如下。
2 Collection接口
Collection接口:是單列數據,定義了存取一組對象的方法和集合。Collection 接口是 List、Set 和 Queue 接口的父接口,該接口里定義的方法 既可用于操作 Set 集合,也可用于操作 List 和 Queue 集合。 在 Java5 之前,Java 集合會丟失容器中所有對象的數據類型,把所有對象都 當成 Object 類型處理;從 JDK 5.0 增加了泛型以后,Java 集合可以記住容器中對象的數據類型。
set接口:存放無序不可重復的數據。set接口下有HashSet,LinkedHashSet,TreeSet
List接口:存放有序可以重復數據。List接口下有ArrayList,Vector,LinkedList
Collection的常用API:
| API | 描述 |
| ? ? ? ? ? ? ? ? ? ? ? boolean add(E e) | 添加元素 |
| boolean addAll(Collection<? extends E> c) | 添加集合元素 |
| void clear() | 清除集合中的所有元素 |
| boolean remove(Object o) | 刪除集合中的某一個元素,通過元素的equals方法判斷是否是要刪除的那個元素 |
| boolean removeAll(Collection<?> c) | 刪除多個元素,也就是取當前集合的差集 |
| boolean isEmpty() | 判斷集合中的元素是否為空 |
| boolean contains(Object o) | 判斷集合中是否包含該元素,是通過元素的equals方法來判斷是否是同一個對象 |
| boolean containsAll(Collection c) | 也是調用元素的equals方法來比較的。拿兩個集合的元素挨個比較。 |
| Iterator<E> iterator() | 返回迭代器對象,用于集合遍歷 |
| int size() | 獲取集合中元素個數 |
| Object[] toArray() | 集合轉換數組 |
| Arrays.asList(T… t) | 數組轉換集合 |
?
2.1 List接口
特點:有序(存儲順序和取出順序一致),可重復。
List容器中的元素都對應一個整數型的序號記載其在容器中的位置,可以根據序號存取容器中的元素。
2.1.1?ArrayList
優點:底層數據結構是數組,查詢快,增刪慢。缺點:線程不安全,效率高
常用API:
| API | 描述 |
| ? ? ? ? ? ?boolean?add(E e) | 添加單個元素 |
| void add(int index, E element) | 在指定的下標處添加元素 |
| E get(int index) | 通過下標來獲取元素 |
| int indexOf(Object o) | 獲取集合某一元素的下標(從左到向查找) |
| int lastIndexOf(Object o) | 獲取集合某一元素的下標(從右向左查找) |
| boolean remove(Object o) | Collection接口中的方法,根據元素刪除? |
| E remove(int index) | List接口中的方法,根據下標刪除,E代表返回刪除對象 |
| boolean retainAll(Collection<?> c) | 交集 |
| E set(int index, E element) | 修改某一下標對應的元素 |
| List<E> subList(int fromIndex, int toIndex) | 返回當前集合的一個子集,從開始下標(包含)到結束下標(不包含) |
注意:要刪除int類型要用Integer()方法,因為傳int類型的話刪除的得是索引。
本質上,ArrayList是對象引用的一個”變長”數組 ,在JDK1.7:ArrayList像餓漢式,直接創建一個初始容量為10的數組 。在JDK1.8:ArrayList像懶漢式,一開始創建一個長度為0的數組,當添加第一個元素時再創建一個始容量為10的數組 。
Arrays.asList(…) 方法返回的 List 集合,既不是 ArrayList 實例,也不是 Vector 實例。 Arrays.asList(…) 返回值是一個固定長度的 List 集合
2.1.2?LinkedList
優點:底層數據結構是鏈表,查詢慢,增刪快。 缺點:線程不安全,效率高
常用API:
| API | 描述 |
| ? ? ? ? ? ?void addFirst(E e) | 添加第一個位置? |
| void addLast(E e) | 添加在末尾 |
| E getLast() | 獲取最后一個元素 |
| E getFirst() | 獲取第一個位置元素 |
| E removeFirst() | 刪除第一個元素?=>?remove() ?刪除此列表的頭(第一個元素) |
| E removeLast() | 刪除最后一個元素 |
LinkedList 是個雙向鏈表,內部沒有聲明數組,而是定義了Node類型的first和last, 用于記錄首末元素。同時,定義內部類Node,作為LinkedList中保存數據的基本結構。Node除了保存數據,還定義了兩個變量:prev變量記錄前一個元素的位置,next變量記錄下一個元素的位置 。
private static class Node<E> {E item;Node<E> next;Node<E> prev;Node(Node<E> prev, E element, Node<E> next) {this.item = element;this.next = next;this.prev = prev;}}2.1.3?Vector
優點:底層數據結構是數組,查詢快,增刪慢。? 缺點:線程安全,效率低
常用API:void addElement(E obj) ; ???//添加元素的方法。? ? ? int capacity() ; ???????????//默認為10
2.1.4 ArrayList,LinkedList,Vector的異同
(1)ArrayList和LinkedList:都是線程不安全的,相對于線程安全的Vector,執行效率要高。ArrayList是基于動態數據的數據結構,LinkedList是基于鏈表的數據結構。隨機訪問查詢,ArrayList的效率要比LinkedList高,因為LinkedList要移動指針,對于新增和刪除,LinkedList效率比較高,因為ArrayList要移動數據
(2)ArrayList和Vector:他們幾乎是相同的,唯一的區別是Vector是同步類,屬于強同步,正常情況下使用ArrayList而不是Vector,因為同步可以由我們自己控制。Vector每次擴容請求增大2倍空間,ArrayList請求增大1.5倍空間。
?
2.2 Set接口
特點:無序(存儲順序和取出順序不一致),唯一
2.2.1 HashSet
底層數據結構是哈希表(無序,唯一)。
保證唯一性:依賴hashCode()和equals()方法。使用HashCode算法,獲取對象存儲的位置。如果沒有,就會將對象存儲在這個位置。如果有(對象的HashCode一樣),會調用equals方法。
如果兩個對象相同,那么它們的hashCode值一定要相同;如果兩個對象的hashCode相同,它們并不一定相同。
public class TestHashSet {@Testpublic void test2() {HashSet set = new HashSet();set.add(new Person("小明",20));set.add(new Person("小張",23));set.add(new Person("小明",20)); // set.add("abc"); // System.out.println("abc".hashCode()); // // System.out.println(new String("abc").hashCode()); //System.out.println(set.size()); //輸出2System.out.println(set);} } class Person{String name;int age;@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + age;result = prime * result + ((name == null) ? 0 : name.hashCode());return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;Person other = (Person) obj;if (age != other.age)return false;if (name == null) {if (other.name != null)return false;} else if (!name.equals(other.name))return false;return true;}}HashSet底層也是數組,初始容量為16,使用率超過0.75,則擴容為原來的2倍。
向HashSet中添加元素的過程:①向HashSet 存入一個元素,會調用該對象的hashCode方法得到hashCode值,根據這個hashCode值通過某種散列函數覺得這個對象在HashSet 底層數組中的存儲位置。②如果2個元素的hashCode值相等,繼續調用equals方法,如果equals方法結果為true,添加失敗;如果為false,那么會保存該元素,但是該數組的位置已經有元素了,那么會通過鏈表的方式繼續鏈接。
總結:hashCode不一樣會添加元素,不會驗證euqals方法;hashCode一樣會驗證equals方法,如果相同則不會添加后元素,否則會添加后元素。
2.2.2 LinkedHashSet
繼承自HashSet,底層數據結構是鏈表和哈希表,由鏈表保證元素有序,由哈希表保證元素唯一。根據元素的 hashCode 值來決定元素的存儲位置。
與hashSet區別:遍歷時LinkedHashSet比hashSet效率高;插入和刪除元素hash效率高。
2.2.3?TreeSet
TreeSet 底層數據結構是紅黑樹。(唯一,有序)。是 SortedSet 接口的實現類,TreeSet 可以確保集合元素處于排序狀態。
特點:(1)TreeSet添加元素的類型要一致。
(2)輸出的順序可以按一定的規則輸出。
(3)排序方式:①自然排序?實現Comparable接口;②定制排序?實現Comparator 接口
public class Test1 {//自然排序測試@Testpublic void test() {TreeSet<Employee> tree = new TreeSet<>();tree.add(new Employee("cc",10,new MyDate(2010,1,1)));tree.add(new Employee("ff",10,new MyDate(2011,1,1)));tree.add(new Employee("a",8,new MyDate(2010,1,5)));tree.add(new Employee("e",13,new MyDate(2013,1,1)));tree.add(new Employee("cca",12,new MyDate(2015,5,1)));System.out.println(tree);}//自定義排序測試@Testpublic void test1() {TreeSet<Employee1> tree = new TreeSet<>(new Comparator<Employee1>() {//比較o1和o2的大小:如果方法返回正整數,則表示o1大于o2;如果返回0,表示相等;返回負整數,表示o1小于o2。@Overridepublic int compare(Employee1 o1, Employee1 o2) {if(o1.getBirthday().getYear() == o2.getBirthday().getYear()) {if(o1.getBirthday().getMonth()==o2.getBirthday().getMonth()) {if(o1.getBirthday().getDay()==o2.getBirthday().getDay()) {return 0;}return o1.getBirthday().getDay()-o2.getBirthday().getDay();}return o1.getBirthday().getMonth()-o2.getBirthday().getMonth();}return o1.getBirthday().getYear() - o2.getBirthday().getYear();}});tree.add(new Employee1("cc",10,new MyDate(2010,1,1)));tree.add(new Employee1("ff",10,new MyDate(2011,1,1)));tree.add(new Employee1("a",8,new MyDate(2010,1,5)));tree.add(new Employee1("e",13,new MyDate(2013,1,1)));tree.add(new Employee1("cca",12,new MyDate(2015,5,1)));System.out.println(tree);} } class Employee implements Comparable<Employee>{private String name;private int age;private MyDate birthday;public Employee() {super();}public Employee(String name, int age, MyDate birthday) {super();this.name = name;this.age = age;this.birthday = birthday;}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 MyDate getBirthday() {return birthday;}public void setBirthday(MyDate birthday) {this.birthday = birthday;}@Overridepublic String toString() {return "[name=" + name + ", age=" + age + ", birthday=" + birthday + "]";}@Overridepublic int compareTo(Employee o) {return this.name.compareTo(o.name);}}class MyDate{private int month;private int day;private int year;public MyDate() {}public MyDate(int year, int month, int day) {this.month = month;this.day = day;this.year = year;}public int getMonth() {return month;}public void setMonth(int month) {this.month = month;}public int getDay() {return day;}public void setDay(int day) {this.day = day;}public int getYear() {return year;}public void setYear(int year) {this.year = year;}@Overridepublic String toString() {return "[" +year + "-"+ month + "-" + day + "]";}}class Employee1{private String name;private int age;private MyDate birthday;public Employee1() {super();}public Employee1(String name, int age, MyDate birthday) {super();this.name = name;this.age = age;this.birthday = birthday;}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 MyDate getBirthday() {return birthday;}public void setBirthday(MyDate birthday) {this.birthday = birthday;}@Overridepublic String toString() {return "[name=" + name + ", age=" + age + ", birthday=" + birthday + "]";}}3 Map接口
Map接口:雙列數據,保存具有映射關系的K-V對的集合。Map接口有三個比較重要的實現類,分別是HashMap、TreeMap和HashTable。Map接口和Collection接口是并列的。
Map 中的 key 和 value 都可以是任何引用類型的數據 。因為Map 中的 key 用Set來存放,所以不允許重復,即同一個 Map 對象所對應的類,須重寫hashCode()和equals()方法。key 和 value 之間存在單向一對一關系,即通過指定的 key 總能找到唯一的、確定的。
3.1 HashMap
HashMap是 Map 接口使用頻率最高的實現類。 允許使用null鍵和null值,與HashSet一樣,不保證映射的順序。
所有的key構成的集合是Set:無序的、不可重復的。所以,key所在的類要重寫: equals()和hashCode() 。所有的value構成的集合是Collection:無序的、可以重復的。所以,value所在的類 要重寫:equals() 。
一個key-value構成一個entry,所有的entry構成的集合是Set:無序的、不可重復的。
HashMap 判斷兩個 key 相等的標準是:兩個 key 通過 equals() 方法返回 true, hashCode 值也相等。HashMap 判斷兩個 value相等的標準是:兩個 value 通過 equals() 方法返回 true。
Map接口常用API如下:
| 添加刪除操作API | 描述 |
| ? ? ? ? ? ? ? ? ? Object put(Object key,Object value)? | 添加元素 |
| Object remove(Object key) | 刪除 |
| void putAll(Map t) | 添加map集合 |
| void clear() ? | 清除 |
| 查詢操作API | 描述 |
| ? ? ? ? ? ? ? ? Object get(Object key) | 通過key獲取vclue |
| boolean containsKey(Object key) | 判斷key在map集合是否存在 |
| boolean containsValue(Object value) | 判斷value在map集合是否存在 |
| int size() ?? | map集合元素的個數 |
| boolean isEmpty() ??? | 是否為空??如果空返回是true |
| boolean equals(Object obj) | 比較 |
| 集合操作 | 描述 |
| ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? Set keySet() | 鍵的集合 |
| Collection values() | 值的集合 |
| Set entrySet() | 鍵\值集合 |
注意:如果key相同,后者會替換前者。與HashSet不同,HashSet相同的話不添加后者
HashMap存儲結構在JDK7以前是:數組+鏈表,在JDK8后是:數組+鏈表+紅黑樹
JDK 1.8之前HashMap的存儲結構說明:內部存儲結構是數組和鏈表的結合。 當實例化一個HashMap時,系統會創建一個長度為Capacity(哈希表中被稱為容量 )的Entry數組,數組中可以存放元素的位置稱為“桶(bucket)”,每個桶有自己的索引,系統可以根據索引快速的找到桶中的元素。每個桶存儲一個元素,即一個Entry對象,但是每個Entry對象可以帶一個引用變量,用于指向下一個元素。所以在一個桶中,就有可能生成一個Entry鏈,新添加的元素作為鏈表的head。
添加元素的過程:①首先計算entry(key,value)中key的hashCode值,得到在底層Entry數組中要存儲的位置,如果這個位置上沒有元素,直接添加成功;如果這個位置上已經存在一個entry1或者存在一個entry鏈表了,則循環比較每一個entry中你的key和要插入的entry的key,如果hash值不同,添加到entry鏈表;如果hash值相同,再比較equals,如果相同則用待插入的entry的value替換鏈表中與他equals相同的entry的value,如果遍歷一遍以后發現所有的equals都不相等,則插入鏈表,這個entry指向原有的entry元素。
HashMap擴容:當HashMap中的元素越來越多的時候,因為數組的長度時固定的,那么hash沖突的概率也越來越高,為了提高查詢效率就需要對數組進行擴容。當 HashMap 中的元素個數超過數組長度的loadFactor (默認值是0.75)就會進行擴容。默認數組大小DEFAULT_INITIAL_CAPACITY 是16,當HashMap中元素個數超過16*0.75=12個時就進行擴容,擴大一倍,即為32。在HashMap數組擴容之后,最消耗性能的點就是原數組中的數據必須重新計算其在新數組中的位置并插入。所以如果我們已經預知HashMap中元素的個數,預設元素的個數能有效提高HashMap的性能
JDK 1.8之后HashMap的存儲結構說明:內部存儲結構是數組+鏈表+紅黑樹,當實例化一個HashMap的時候,會初始化initialCapacity和loadFactor,在插入第一個entry的時候,系統創建一個長度為initialCapacity的Node數組,數組中可以存放元素的位置稱為“桶(bucket)”,每個桶有自己的索引,系統可以根據索引快速的找到桶中的元素。每個桶存儲一個元素,即一個Node對象,但是每個Node對象可以帶一個引用變量,用于指向下一個元素。所以在一個桶中,就有可能生成一個Node鏈。也由可能是一個個TreeNode對象,每個TreeNode對象有兩個葉子節點left和right。新添加的元素就可能作為鏈表的最后一個或者樹的葉子節點。
HashMap擴容:當HashMap中的元素越來越多的時候,因為數組的長度時固定的,那么hash沖突的概率也越來越高,為了提高查詢效率就需要對數組進行擴容。當 HashMap 中的元素個數超過數組長度的loadFactor (默認值是0.75)就會進行擴容。默認數組大小DEFAULT_INITIAL_CAPACITY 是16,當HashMap中元素個數超過16*0.75=12個時就進行擴容,擴大一倍,即為32。在HashMap數組擴容之后,最消耗性能的點就是原數組中的數據必須重新計算其在新數組中的位置并插入。
HashMap樹形化:①當HashMap中其中一個鏈的對象個數達到了8個,如果Capacity還沒有到64,會進行擴容解決。②如果Capacity已經到64那么這個鏈表會變成樹,節點的類型也有Node變成TreeNode類型。如果當映射關系被移除后,下次resize方法時判斷樹的結點個數低于6個,也會把樹再轉為鏈表。
JDK 1.8之后HashMap與JDK 1.8之前HashMap的比較:①JDK 1.8默認情況下,先不創建長度為16的數組,只有在第一次插入數據的時候才創建長度為16的數組 ②數組為Node類型,在JDK 1.7中稱為Entry類型 ③JDK 1.8形成鏈表結構時,新添加的key-value對在鏈表的尾部(七上八下) ④當數組指定索引位置的鏈表長度>8時,且map中的數組的長度> 64時,此索引位置上的所有key-value對使用紅黑樹進行存儲。
?loadFactor負載因子的值對HashMap的影響:負載因子的大小決定了HashMap的數據密度,負載因子越大發碰撞的概率就越大,導致鏈表長度越長,造成查詢和插入時比較的次數越多,性能下降;負載因子越小,數據密度越小,就越容易觸發擴容,碰撞的概率越小,數組中鏈表越短,查詢和插入時比較的次數會減少,性能更高,但是會浪費一定的內存空間,并且經常擴容對性能也有影響。初始化可以預設大一點。
3.2 LinkedHashMap
在HashMap存儲結構的基礎上,使用了一對雙向鏈表來記錄添加 元素的順序 。與LinkedHashSet類似,LinkedHashMap 可以維護 Map 的迭代,存儲順序和輸出順序一致。
public class TestLinkedHashMap{@Testpublic void test2(){LinkedHashMap link = new LinkedHashMap();link.put("aa", 90); link.put("cc",88);link.put(new Date(),99);link.put(null, null);//keysetSet keys = link.keySet();for(Object o : keys) {System.out.println(o+"===="+link.get(o));}} }3.3 TreeMap
TreeMap存儲 Key-Value 對時,需要根據 key-value 對進行排序 ,按照添加的key屬性排序,TreeSet底層使用紅黑樹結構存儲數據。
自然排序:實現接口Comparable重寫int CompareTo(Object obj)方法;
定制排序:實現接口Comparator重寫int CompareTo(Object obj1,Object obj2)方法;
import java.util.Comparator; import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.TreeMap; import org.junit.Test;public class TestTreeMap {@Testpublic void test2() {Comparator com = new Comparator() {@Overridepublic int compare(Object o1, Object o2) {if(o1 instanceof Person && o2 instanceof Person) {Person p1 = (Person)o1;Person p2 = (Person)o2;return p1.name.compareTo(p2.name);}return 0;}};Map tree =new TreeMap(com);tree.put(new Person("a"),90);tree.put(new Person("e"),30);tree.put(new Person("d"),50);tree.put(new Person("c"),70);Set set = tree.keySet();Iterator it = set.iterator();while(it.hasNext()) {it.next();}System.out.println(tree);}//自然排序@Testpublic void test1() {TreeMap tree =new TreeMap();tree.put(new Person("a"),90);tree.put(new Person("e"),30);tree.put(new Person("d"),50);tree.put(new Person("c"),70);System.out.println(tree);} } class Person1 {String name;public Person1(String name) {this.name = name;} @Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + ((name == null) ? 0 : name.hashCode());return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;Person other = (Person) obj;if (name == null) {if (other.name != null)return false;} else if (!name.equals(other.name))return false;return true;}@Overridepublic String toString() {return "Person [name=" + name + "]";}} class Person implements Comparable{String name;public Person(String name) {super();this.name = name;}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + ((name == null) ? 0 : name.hashCode());return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;Person other = (Person) obj;if (name == null) {if (other.name != null)return false;} else if (!name.equals(other.name))return false;return true;}@Overridepublic int compareTo(Object o) {if(o instanceof Person) {Person p = (Person)o;return this.name.compareTo(p.name);}return 0;}@Overridepublic String toString() {return "Person [name=" + name + "]";} }3.4?HashTable
與HashMap相同不能保證順序,key值相同替換,但是他是線程安全的。
Hashtable實現原理和HashMap相同,功能相同。底層都使用哈希表結構,查詢速度快,很多情況下可以互用。與HashMap不同,Hashtable 不允許使用 null 作為 key 和 value。
它的子類properties用來操作屬性文件,如下
public void TestProperties throws FileNotFoundException, IOException {public static void main(String[] args){//創建屬性文件類的對象Properties pro = new Properties();//以流的方式讀取文件到內存pro.load(new FileInputStream(new File("jdbc.properties")));String name = pro.getProperty("jdbc.username");String password = pro.getProperty("jdbc.password");System.out.println(name+ "--" + password);} }3.5?Properties
Properties 類是 Hashtable 的子類,該對象用于處理屬性文件。因為屬性文件里的 key、value 都是字符串類型,所以 Properties 里的 key 和 value 都是字符串類型。存取數據時,建議使用setProperty(String key,String value)方法和 getProperty(String key)方法 。
Properties pros = new Properties();pros.load(new FileInputStream("test.properties"));String user = pros.getProperty("user");System.out.println(user);4?Collections工具類
Collections工具類是一個操作Set,List和Map等集合的工具類,Collections提供了一系列靜態的方法對集合中的元素進行排序,查詢和修改等操作,還提供了對集合對象設置不可變,實現同步控制等方法。
| 方法 | 描述 |
| reverse(List) | 反轉List中元素的順序 |
| sort(List) | 根據元素的自然排序對指定List集合元素按升序排序 |
| sort(List,Comparator) | 根據指定的Comparator產生的順序對List集合元素進行排序 |
| swap(List,int,int) | 將指定List集合中的i處元素和j處元素進行交換 |
| shuffle(List) | 對List集合元素進行隨機排序 |
| int frequency(Collection,Object) | 返回指定集合中指定元素的出現次數 |
| Object max(Collection) | 根據元素的自然排序,返回給定集合中的最大元素 |
| Object max(Collection,Comparator) | 根據Comparator指定的順序,返回給定集合中的最大元素 |
| Object min(Collection) | 根據元素的自然排序,返回給定集合中的最小元素 |
| Object min(Collection,Comparator) | 根據Comparator指定的順序,返回給定集合中的最小元素 |
| void copy(List dest,List src) | 將src中的內容復制到dest中 |
| boolean replaceAll(List list, Object oldVal,Object newVal ) | 使用新值替換 List 對象的所有舊值 |
ListArrays.asList(T...t) 數組轉集合? ? ? ? list.toArray(集合轉數組)? ? ?Arrays.sort(array)數組排序
盡量不要使用ListArrays.asList(T...t) 數組轉集合,因為該方法返回固定長的List,不支持add和remove操作,該方法返回的List與傳入的數組是映射關系,set/get直接操作數組,List也會改變。有以下替代方案:
| Integer[] array = {1,2}; List<Integer>?list = new ArrayList<>(Arrays.asList(array)); |
| List<Integer>?list = new ArrayList<>(); Integer[] array = {1,2}; Collections.addAll(list,array); |
| int[] array = {1,2}; List<integer> list = Arrays.stream(array).bosxed().collect(Collectors.toList()); |
4?Iterator迭代器接口
Iterator對象成為迭代器,是設計模式的一種,主要作用就是用于遍歷collection集合中的元素。
迭代器模式的定義為:提供一種方法訪問一個容器(container)對象中各個元素,而又不需暴露該對象的內部細節。迭代器模式,就是為容器而生。
Collection接口繼承了java.lang.Iterable接口,這個接口有個iterator方法,所以所有實現了Collection接口的集合類都有一個iterator方法。
iterator僅僅用于遍歷集合,iterator本身不提供承載對象的能力,所以創建Iterator對象,必須由一個被迭代的集合。集合對象每次調用iterator方法都得到一個全新的迭代對象,默認游標都在集合的第一個元素之前
4.1?Iterator接口的方法
| 方法 | 描述 |
| hasNext() | 如果iterator還有元素則返回true,否則返回false(注意,這時上面的那個指針位置不變) |
| next() | 返回這個iterator的下一個元素,同時上面的指針向后移動一位。 |
| remove | 刪除 iterator 內指針的前1個元素,前提是至少執行過1次next(); |
注意:在調用next方法之前必須要調用hasNext方法檢測,否則如果下一條沒有記錄,調用next則會拋異常
總結
以上是生活随笔為你收集整理的Java集合Set,List和Map等的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java增强之并发编程
- 下一篇: Java入门篇 2021/02/22