Day09 JavaSE 集合概述

Java集合概述

前言

Java集合類存放於java.util包中,是一個用來存放對象的容器

  • 集合只能用來存放對象。
  • 集合存放的是多個對象的引用,對象本身還是放在堆內存中。
  • 集合可以存放不同類型、不限數量的數據類型。

Java集合可分爲Set、List、Map三大體系。

Set:無序、不可重複的集合

List:有序,可重複的集合

Map:具有映射關係的集合

1 Set

1.1 HashSet

HashSet按照Hash算法來存儲集合中的元素,因此具有很好的存取和查找性能。

HashSet特點:

  • 不能保證元素的排列順序
  • 不可重複 --> hashCode不相同
  • HashSet不是線程安全的
  • 集合元素可以使用null

排列順序的解釋:當向HashSet集合存入一個元素時,會調用該對象的hashCode()方法來得到該對象的hashCode值,根據hashCode值決定該對象在集合中存儲位置。

HashSet類 --實現–> set接口 --繼承–> Collection接口

基本操作:

創建HashSet: Set set = new HashSet();

  • 增、刪、判斷、清空;

  • add()、remove()、contains()、clear();

    package com.set;
    
    import java.util.HashSet;
    import java.util.Iterator;
    import java.util.Set;
    
    public class HashSetDemo01 {
        public static void main(String[] args) {
            Set set = new HashSet();// <=>Set<Object> set = new HashSet<Object>();
            set.add(1);//添加元素
            set.add("a");
            System.out.println(set);
    
            set.remove(1); //移除元素
            System.out.println(set);
    
            System.out.println(set.contains(1));//判斷是否存在
    
            set.clear(); //清空集合
            System.out.println(set);
        }
    }
    //運行結果
    //[1, a]
    //[a]
    //false
    //[]
    
  • 遍歷(迭代器遍歷 / for each迭代集合)

    package com.set;
    
    import java.util.HashSet;
    import java.util.Iterator;
    import java.util.Set;
    
    public class HashSetDemo01 {
        public static void main(String[] args) {
            Set set = new HashSet();// <=>Set<Object> set = new HashSet<Object>();
            set.add("a");
            set.add("b");
            set.add("c");
            set.add("d");
            set.add("d"); //set集合並未發生改變,說明set存的值是不重複的
            set.add(null); //set可以存null --> 存後發現null位於首位,故hashSet無順序
            System.out.println(set);
            
          	//使用迭代器遍歷集合
            Iterator it = set.iterator();
            while (it.hasNext()){
                System.out.println(it.next());
            }
            
          	//for each迭代集合(推薦!)
            for (Object obj : set){ //將set每一個值取出賦值給obj
                System.out.println(obj);
            }
            System.out.println(set.size()); //獲取集合個數
        }
    }
    /*運行結果
    [null, a, b, c, d]
    null
    a
    b
    c
    d
    null
    a
    b
    c
    d
    5
    */
    
  • 泛型的引入

  • Set set1 = new HashSet();

    package com.set;
    
    import java.util.HashSet;
    import java.util.Set;
    
    public class HashSetDemo01 {
        public static void main(String[] args) {
            //如果想讓集合只存同樣類型的對象,需要使用泛型
            Set<String> set1 = new HashSet<String>();
    
            set1.add("abc");
            //set1.add(true); //非String對象不能存入
            System.out.println(set1);
        }
    }
    //運行結果:
    //[abc]
    

1.2 TreeSet

TreeSet是SortedSet接口的實現類,TreeSet可以確保集合元素處於排序狀態。

TreeSet支持兩種排序方法:自然排序(默認)和定製排序。

1.2.1 自然排序

TreeSet會調用集合元素的compareTo(Object obj)方法來比較元素之間的大小關係,然後將集合元素按升序排列

  • 如果this > obj,返回1
  • 如果this < obj,返回-1
  • 如果this = obj,返回0
  • 必須放入同樣類的對象(可使用泛型來限制),否則會出現類型轉換異常

自然排序案例:

基本操作與HashSet中一致,遍歷操作也相同,故直接給出:

package com.set;

import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;

public class TreeSetDemo01 {
    public static void main(String[] args) {
        Set<Integer> set = new TreeSet<Integer>();
        //TreeSet 自然排序
        set.add(5);
        set.add(2);
        set.add(4);
        set.add(3);
        System.out.println(set);
        set.remove(5);
        System.out.println(set.contains(3));
//        set.clear();
        //遍歷同上
        //迭代器遍歷
        Iterator<Integer> it = set.iterator();
        while(it.hasNext()){
            System.out.println(it.next());
        }
        //for-each遍歷
        for (Integer i : set){
            System.out.println(i);
        }
    }
}
/*運行結果:
[2, 3, 4, 5]
true
2
3
4
2
3
4
 */

1.2.2 定製排序

TreeSet中存放自己定義的類對象,現需按照自己想要的方式進行排序,需使用定製排序。

實現方法:

  • 創建自己的類並實現Comparator<Person>接口,例如Person類,內含name,age屬性。
  • 在Person類中創建無參構造器+有參構造器。
  • Person類中重寫compare方法,傳入兩對象,按照age比較並返回1、-1、0。

TreeSet創建使用:Set<Person> set = new TreeSet<Person>(new Person());

定製排序案例:

package com.set;

import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;

public class TreeSetDemo02 {
    public static void main(String[] args) {
        Person p1 = new Person("張三", 23);
        Person p2 = new Person("里斯", 25);
        Person p3 = new Person("王武", 20);
        Person p4 = new Person("Lucy", 19);

        Set<Person> set = new TreeSet<Person>(new Person());
        set.add(p1);
        set.add(p2);
        set.add(p3);
        set.add(p4);

        for (Person p : set){
            System.out.println(p.name + " "+ p.age);
        }

    }
}
class Person implements Comparator<Person> { //將person對象存入TreeSet中,並按照年齡排序
    int age;
    String name;
    //無參構造器
    public Person(){

    }
    //有參構造器
    public Person(String name, int age){
        this.name = name;
        this.age = age;
    }
    @Override
    public int compare(Person o1, Person o2) { //年齡正序排列
        if (o1.age > o2.age) {
            return 1;
        } else if (o1.age < o2.age) {
            return -1;
        } else {
            return 0;
        }
    }
}
//運行結果:
//Lucy 19
//王武 20
//張三 23
//里斯 25

2 List

List代表一個元素有序、且可重複的集合,集合中的每個元素都有其對應的順序索引。

List對象創建:List<String> list = new ArrayList<String>();

ArrayList和Vector是List接口的兩個典型實現,區別:

  • Vector是一個古老的集合,通常建議ArrayList。
  • ArrayList是線程不安全的,Vector是線程安全的。

常用操作:

函數名稱 函數功能
add() 1)添加元素
2指定位置添加元素
addAll() 指定位置添加另一集合中所有元素
remove() 刪除元素(可根據索引也可根據元素名稱)
set() 更改指定位置元素
get() 根據索引取出指定位置元素
indexOf() 獲取指定元素在集合中第一次出現的索引下標
lastIndexOf() 獲取指定元素在集合中最後一次出現的索引下標
sublist() 截取list集合,返回新的list集合(左閉右開)
size() 返回列表元素個數

案例展示:

package com.list;

import java.util.ArrayList;
import java.util.List;

public class ListDemo01 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<String>();
        list.add("a"); //索引爲0
        list.add("c"); //索引爲1
        list.add("c"); //索引爲2
        list.add("d"); //索引爲3
        list.add("d"); //允許使用重複元素
        System.out.println(list);

        list.add(1,"b"); //在指定位置插入數據,其後數據均往後移動
        System.out.println(list);

        List<String> l = new ArrayList<String>();
        l.add("123");
        l.add("efg");
        list.addAll(0,l); //在指定索引下標位置插入集合
        System.out.println(list);

        list.remove(4); //根據指定索引下標移除數據
        System.out.println(list);

        list.set(1,"456"); //根據指定索引下標修改元素
        System.out.println(list);

        System.out.println(list.get(2)); //取出指定位置元素
        System.out.println(list);


        System.out.println(list.indexOf("d")); //獲取指定元素在集合中第一次出現的索引下標
        System.out.println(list.lastIndexOf("d")); //獲取指定元素在集合中最後一次出現的索引下標

        List<String> sublist = list.subList(2,5); //取出索引下標爲[2,5)的元素,注意左閉右開
        System.out.println(sublist);
        System.out.println(sublist.size());
    }
}
/*運行結果:
[a, c, c, d, d]
[a, b, c, c, d, d]
[123, efg, a, b, c, c, d, d]
[123, efg, a, b, c, d, d]
[123, 456, a, b, c, d, d]
a
[123, 456, a, b, c, d, d]
5
6
[a, b, c]
3
 */

3 Map

Map用來保存具有映射關係的數據,因此Map集合裏保存兩組值,一組值保存Key,另外一組保存Value。

(這裏的Map有點類似於python中的字典)

Key不允許重複,且Key與Value存在一對一關係。

3.1 HashMap

常用操作:

函數名稱 函數功能
put() 添加數據
get() 根據key取值
remove() 根據key移除鍵值對
size() 返回鍵值對個數
containsKey() 判斷map集合中是否包含指定的key
containsValue() 判斷map集合中是否包含指定的value
clear() 清空map集合
map.keySet() 獲取map集合中key的集合
map.values() 獲取map集合中所有values值
(返回HashMap$Values類型數據)

基本操作案例:

package com.map;

import java.util.*;

public class MapDemo01 {
    public static void main(String[] args) {
        Map<String, Integer> map = new HashMap<String, Integer>();
        map.put("a",1); //添加數據
        map.put("c",2);
        map.put("e",2);
        map.put("f",2);
        System.out.println(map);

        System.out.println(map.get("c")); //根據key取值

        map.remove("c"); //根據key移除鍵值對
        System.out.println(map);
        System.out.println(map.size()); //map集合長度

        System.out.println(map.containsKey("c")); //判斷map集合中是否包含指定的key
        System.out.println(map.containsValue(1)); //判斷map集合中是否包含指定的Value

        map.values(); //獲取map集合的所有Value值
        System.out.println(map.values().getClass().getName()); //查看返回類型
      
        map.clear();//清空
    }
}
/*運行結果:
{a=1, c=2, e=2, f=2}
2
{a=1, e=2, f=2}
3
false
true
java.util.HashMap$Values
 */

遍歷操作案例:

兩種方式:1、map.keySet() 2、map.entrySet()(推薦使用!)

package com.map;

import java.util.*;

public class MapDemo01 {
    public static void main(String[] args) {
        Map<String, Integer> map = new HashMap<String, Integer>();
        map.put("a",1); //添加數據
        map.put("e",2);
        map.put("f",2);
        System.out.println(map); 
      
        //遍歷map集合,通過map.keySet();
        Set<String> keys = map.keySet(); //獲取map集合的key的集合
        for (String key : keys) {
            System.out.println("key: " + key + ", value: " + map.get(key));
        }

        //通過map.entrySet();(性能更優,推薦使用)
        Set<Map.Entry<String,Integer>> entrys = map.entrySet(); //Map.Entry表示映射關係,map.entrySet()返回包含該關係的Set視圖
        for (Map.Entry<String, Integer> en : entrys){
            System.out.println("key: " + en.getKey()+", value: "+ en.getValue());
        }
    }
}
/*運行結果:
key: a, value: 1
key: e, value: 2
key: f, value: 2
key: a, value: 1
key: e, value: 2
key: f, value: 2
 */

3.2 TreeMap

TreeMap也支持兩種排序方法:自然排序與定製排序(與TreeSet類似)

此處僅展示自然排序的使用,定製排序可仿照TreeSet編寫。

  • 案例展示:
package com.map;

import java.util.Map;
import java.util.TreeMap;

public class MapDemo02 {
    public static void main(String[] args) {
        Map<Integer, String> map = new TreeMap<Integer, String>();
        map.put(4,"a");
        map.put(3,"b");
        map.put(5,"b");
        map.put(2,"e");
        System.out.println(map);

        //自然排序使用的是英文字典順序排序,且數字在字母之前
        Map<String, String> map1 = new TreeMap<String, String>();
        map1.put("a","b");
        map1.put("c","d");
        map1.put("b","e");
        map1.put("d","f");
        map1.put("ab","ab");
        map1.put("1","11");
        map1.put("12","12");
        map1.put("2","2");
        System.out.println(map1);
    }
}
/*運行結果:
{2=e, 3=b, 4=a, 5=b}
{1=11, 12=12, 2=2, a=b, ab=ab, b=e, c=d, d=f}
*/

注:TreeMap自然排序<String排序>使用的是英文字典順序,且數字在字母之前!

寫在最後

因爲苦澀,纔去品嚐,因爲感動,纔去深愛。

To Demut and Dottie!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章