大家好,這裡是java研究所。
java中的集合比較多,今天我們來熟悉一下常用的幾個,了解其特點,用起來會更順手一些,下面先看下類圖
1、List接口可以存放重複的元素,2個常用的實現類
1.1、ArrayList放入順序和迭代的順序是一樣的,也就是說元素是有序的數組的特點是,通過索引訪問的時候,時間複雜度是O(1)但是向某個位置插入數據,由於涉及元素的後移,所以時間複雜度是O(n)但是在末尾追加元素,沒有數據的移動操作,時間複雜度是O(1)刪除某個元素,需要先找到個元素,然後還需要將後面的元素前移,時間複雜度是O(n)刪除某個位置的元素,需要將後面的元素前移,時間複雜度是O(n)@org.junit.Test
public void arrayList() {
ArrayList<Integer> arrayList = new ArrayList<>();
for (Integer i = 10; i < 20; i++) {
arrayList.add(i);
}
//放入的順序和迭代的順序一樣
arrayList.forEach(System.out::println);
}輸出
10
11
12
13
14
15
16
17
18
19
1.2、LinkedList由於採用鍊表存放數據,所以查找某個位置的數據,涉及到鍊表的遍歷,所以時間複雜度是O(n)在某個位置插入元素,也需要先定位到那個位置,定位位置,只能通過遍歷的方式,所以時間複雜度是O(n)刪除某個元素,需要先找到個元素,然後改變一下鍊表的指針就可以了,時間複雜度是O(n)刪除某個位置的元素,需要先找到這個位置,然後改變一下鍊表的指針就可以了,時間複雜度是O(n)@org.junit.Test
public void linkedList() {
LinkedList<Integer> linkedList = new LinkedList<>();
for (Integer i = 10; i < 20; i++) {
linkedList.add(i);
}
//放入的順序和迭代的順序一樣
linkedList.forEach(System.out::println);
}
1.3、小結若應用程式對數據有較多的隨機訪問,ArrayList對象要優於LinkedList對象若應用程式有更多的插入或者刪除操作,較少的數據讀取,LinkedList對象要優於ArrayList對象不過ArrayList的插入,刪除操作也不一定比LinkedList慢,若在List靠近末尾的地方插入,那麼ArrayList只需要移動較少的數據,而LinkedList則需要一直查找到列表尾部,反而耗費較多時間,這時ArrayList就比LinkedList要快2、Set接口存入的元素會自動去重,3個常用的實現類
2.1、HashSet放入的元素是無序的,比如放入的是a、b、c,但是迭代出來的順序可能就亂掉了下面放入a/b/c/1/2/3,然後迭代輸出順序亂了,和放入的順序不一樣了
@org.junit.Test
public void hashSet() {
HashSet<String> hashSet = new HashSet<>();
hashSet.add("a");
hashSet.add("b");
hashSet.add("c");
hashSet.add("1");
hashSet.add("2");
hashSet.add("3");
hashSet.forEach(System.out::println);
}輸出
a
1
b
2
c
3
2.2、LinkedHashSet元素是有序的,即放進去的順序和迭代出來的順序是一致的看下面案例,放入順序和迭代輸出的順序一致
@org.junit.Test
public void linkedHashSet() {
LinkedHashSet<String> linkedHashSet = new LinkedHashSet<>();
linkedHashSet.add("a");
linkedHashSet.add("b");
linkedHashSet.add("c");
linkedHashSet.add("1");
linkedHashSet.add("2");
linkedHashSet.add("3");
linkedHashSet.forEach(System.out::println);
}輸出
a
b
c
1
2
3
2.3、TreeSet會對放入的元素進行排序,排序規則如下:
創建TreeMap的時候,可以指定排序器,若不指定排序,那麼放入的元素必須實現java.lang.Comparable接口,否則add元素會報異常,若通過構造器指定了排序器,並且元素也實現了java.lang.Comparable接口,那麼會按照構造函數指定的排序器進行排序。
案例1:自然順序下面放入Integer類型的元素,Integer類型默認實現了java.lang.Comparable接口,會按照升序排序。
@org.junit.Test
public void treeSetTest1() {
TreeSet<Integer> treeSet = new TreeSet<>();
treeSet.add(10);
treeSet.add(5);
treeSet.add(4);
treeSet.add(20);
treeSet.forEach(System.out::println);
}結果按升序輸出
4
5
10
20
案例2:放入自定義的元素SchoolReport:表示成績單信息,實現了Comparable接口,這個接口有個compareTo方法,這個方法中我們按照score升序排序
public static class SchoolReport implements Comparable<SchoolReport> {
//分數
private int score;
//姓名
private String name;
public SchoolReport(int score, String name) {
this.score = score;
this.name = name;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Score{" +
"score=" + score +
", name='" + name + '\'' +
'}';
}
@Override
public int compareTo(SchoolReport o) {
return Integer.compare(this.score, o.score);
}
}測試代碼如下,然後迭代輸出
@org.junit.Test
public void treeSetTest2() {
TreeSet<SchoolReport> treeSet = new TreeSet<>();
treeSet.add(new SchoolReport(10, "張三"));
treeSet.add(new SchoolReport(5, "李四"));
treeSet.add(new SchoolReport(15, "王五"));
treeSet.forEach(System.out::println);
}結果如下,按照score升序排序了
Score{score=5, name='李四'}
Score{score=10, name='張三'}
Score{score=15, name='王五'}
案例3:通過構造器指定比較器先看一下構造器如下,需要傳入java.util.Comparator類型的比較器,用來對放入的元素進行排序
public TreeSet(Comparator<? super E> comparator) {
this(new TreeMap<>(comparator));
}下面案例,比較器為按照score的降序排序
@org.junit.Test
public void treeSetTest3() {
Comparator<SchoolReport> scoreDescComparator = Comparator.comparingInt(SchoolReport::getScore).reversed();
TreeSet<SchoolReport> treeSet = new TreeSet<>(scoreDescComparator);
treeSet.add(new SchoolReport(10, "張三"));
treeSet.add(new SchoolReport(5, "李四"));
treeSet.add(new SchoolReport(15, "王五"));
treeSet.forEach(System.out::println);
}下面看結果,按照score的降序輸出了
Score{score=15, name='王五'}
Score{score=10, name='張三'}
Score{score=5, name='李四'}
2.4、小結HashSet內部使用HashMap實現的,所以添加、修改、刪除,都是上面3個集合中最快的,如果你元素的順序和排序沒有要求,那麼要用set的時候,這個就是首選若要求放入的順序和迭代出來的順序一致,那麼使用LinkedHashSet若需要對放入的元素進行排序,那麼使用TreeSet3、Map接口key->value的方式存放數據,key不能重複。
常用的3個實現
3.1、HashMap放入的元素是無序的,比如放入的key是a、b、c,但是迭代出來的順序可能就亂掉了下面代碼放入了3個元素,key分別是10/5/15,然後迭代輸出,順序亂掉了
@org.junit.Test
public void hashMap() {
HashMap<Integer, String> hashMap = new HashMap<>();
hashMap.put(10, "張三");
hashMap.put(5, "李四");
hashMap.put(15, "王五");
hashMap.forEach((k, v) -> {
System.out.println(k + ":" + v);
});
}結果
5:李四
10:張三
15:王五
3.2、LinkedHashMap元素是有序的,即放進去的順序和迭代出來的順序是一致的看下面案例,放入順序和迭代輸出的順序一致
@org.junit.Test
public void linkedHashMap() {
LinkedHashMap<Integer, String> linkedHashMap = new LinkedHashMap<>();
linkedHashMap.put(10, "張三");
linkedHashMap.put(5, "李四");
linkedHashMap.put(15, "王五");
linkedHashMap.forEach((k, v) -> {
System.out.println(k + ":" + v);
});
}輸出
10:張三
5:李四
15:王五
3.3、TreeMap會對放入的元素按照key進行排序,排序規則如下:
創建TreeMap的時候,可以指定排序器,若不指定排序,那麼key必須實現java.lang.Comparable接口,否則add元素會報異常,若通過構造器指定了排序器,並且key也實現了java.lang.Comparable接口,那麼會按照構造函數指定的排序器進行排序。
案例1:自然順序下面key為Integer類型的元素,Integer類型默認實現了java.lang.Comparable接口,會按照升序排序。
@org.junit.Test
public void treeMap1() {
TreeMap<Integer, String> treeMap = new TreeMap<>();
treeMap.put(10, "張三");
treeMap.put(5, "李四");
treeMap.put(15, "王五");
treeMap.forEach((k, v) -> {
System.out.println(k + ":" + v);
});
}結果按升序輸出
5:李四
10:張三
15:王五
案例2:放入自定義的元素SchoolReport:表示成績單信息,實現了Comparable接口,這個接口有個compareTo方法,這個方法中我們按照score升序排序
public static class SchoolReport implements Comparable<SchoolReport> {
//分數
private int score;
//姓名
private String name;
public SchoolReport(int score, String name) {
this.score = score;
this.name = name;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Score{" +
"score=" + score +
", name='" + name + '\'' +
'}';
}
@Override
public int compareTo(SchoolReport o) {
return Integer.compare(this.score, o.score);
}
}測試代碼如下,然後迭代輸出
@org.junit.Test
public void treeMap2() {
TreeMap<SchoolReport, String> treeMap = new TreeMap<>();
treeMap.put(new SchoolReport(10, "張三"), "哈哈哈");
treeMap.put(new SchoolReport(5, "李四"), "哈哈哈");
treeMap.put(new SchoolReport(15, "王五"), "哈哈哈");
treeMap.forEach((k, v) -> {
System.out.println(k + ":" + v);
});
}結果如下,按照score升序排序了
Score{score=5, name='李四'}:哈哈哈
Score{score=10, name='張三'}:哈哈哈
Score{score=15, name='王五'}:哈哈哈
案例3:通過構造器指定比較器先看一下構造器如下,需要傳入java.util.Comparator類型的比較器,用來對放入的元素進行排序
public TreeMap(Comparator<? super K> comparator) {
this.comparator = comparator;
}下面案例,比較器為按照score的降序排序
@org.junit.Test
public void treeMap3() {
Comparator<SchoolReport> scoreDescComparator = Comparator.comparingInt(SchoolReport::getScore).reversed();
TreeMap<SchoolReport, String> treeMap = new TreeMap<>(scoreDescComparator);
treeMap.put(new SchoolReport(10, "張三"), "哈哈哈");
treeMap.put(new SchoolReport(5, "李四"), "哈哈哈");
treeMap.put(new SchoolReport(15, "王五"), "哈哈哈");
treeMap.forEach((k, v) -> {
System.out.println(k + ":" + v);
});
}下面看結果,按照score的降序輸出了
Score{score=15, name='王五'}:哈哈哈
Score{score=10, name='張三'}:哈哈哈
Score{score=5, name='李四'}:哈哈哈
3.4、小結HashMap添加、修改、刪除,都是上面3個集合中最快的,如果你元素的順序和排序沒有要求,那麼要用Map的時候,HashMap就是首選若要求放入的順序和迭代出來的順序一致,那麼使用LinkedHashMap若需要對放入的元素進行排序,那麼使用TreeMap4、送書福利這邊整理了幾百本計算機相關的電子書,下面是部分截圖,常見的基本上都有,獲取方式,掃描下面二維碼,發送:電子書