Java基础(九) -- 集合

  • 集合分为两组
    • Collection 【单列集合】 包含 ListSet
    • Map 【双列集合】存放的 K-V 数据

Collection

  • List 和 Set

    list 【ArrayList、Vector、LinkedList】

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    import java.util.ArrayList;
    import java.util.List;

    public class Collection_ {

    @SuppressWarnings({"all"})
    public static void main(String[] args) {
    List list = new ArrayList();
    // 添加
    list.add(10);
    list.add("hello");
    list.add("hello");
    list.add(true);
    System.out.println(list);
    // 删除 支持索引和指定元素值删除
    list.remove(1);
    System.out.println(list);
    list.remove("hello");
    System.out.println(list);
    // 查询
    System.out.println(list.contains(10));
    // 长度
    System.out.println(list.size());
    // 判断是否为空
    System.out.println(list.isEmpty());
    // 清空
    list.clear();
    // 批量添加
    ArrayList arrayList = new ArrayList();
    arrayList.add("三国演义");
    arrayList.add("水浒传");
    list.addAll(arrayList);
    System.out.println(list);
    // 使用迭代器遍历
    Iterator i = list.iterator();
    while (i.hasNext()){
    Object next = i.next();
    System.out.println(next);
    }
    // for增强用法
    for (Object obj:list) {
    System.out.println(obj);
    }
    }
    }
  • Vector、ArrayList对比


| | 底层结构 | 版本 | 线程安全、效率 | 扩容倍数 |
|—————————————————————————–

| ArrayList | 可变数组 |jdk1.2 | 不安全,效率高 | 无参时初始为10,然后1.5倍扩容|
|—————————————————————————–

| Vector | 可变数组 | jdk1.0| 安全,效率低 | 默认10,2倍扩容 |
|—————————————————————————–

  • LinkedList
  • 查询和修改的效率不高,但是增加和删除的效率很高

set

  • 不重复存储 Hash值且equals结果 相同的对象
  • 可以通过重写 hashCodeequals 的方式实现set中属性相同的对象是否能同时存在多个,默认是可以存在多个的,因为不同的对象默认的哈希值不同 快捷方式可以使用 alt+insertequals and hashCode

HashSet 【数组+单向链表+红黑树】

  • 存储是无序的

  • 取出的顺序是固定的

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    import java.util.HashSet;
    import java.util.Iterator;
    import java.util.Set;

    @SuppressWarnings({"all"})
    public class Set_ {
    public static void main(String[] args) {

    Set hashSet = new HashSet();
    hashSet.add("join");
    hashSet.add("lucy");
    hashSet.add("tom");
    hashSet.add("lucy");
    hashSet.add(null);
    System.out.println(hashSet);

    // 使用迭代器或者增强for循环遍历数据
    Iterator ite = hashSet.iterator();
    while(ite.hasNext()){
    Object next = ite.next();
    System.out.println(next);
    }
    for (Object obj:hashSet) {
    System.out.println(obj);
    }

    }
    }
  • 该示例实现相同属性的对象在set中只能存在一个

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    import java.util.HashSet;
    import java.util.Objects;

    @SuppressWarnings({"all"})
    public class Set_ {
    public static void main(String[] args) {

    HashSet hashSet = new HashSet();
    hashSet.add(new Dog("大黄",10));
    hashSet.add(new Dog("大黄",10));
    hashSet.add(new Dog("小黄",5));
    hashSet.add(new Dog("大花",15));

    System.out.println(hashSet);
    }
    }

    class Dog{
    private String name;
    private int age;

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

    @Override
    public String toString() {
    return this.name + this.age;
    }

    @Override
    public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    Dog dog = (Dog) o;
    return age == dog.age && Objects.equals(name, dog.name);
    }

    @Override
    public int hashCode() {
    return Objects.hash(name, age);
    }
    }
  • 自定义对象中包含另一个自定义对象时,需要保证两个自定义对象的hashCode 判断都相等

    以下示例要求保证相同姓名和出生日期的狗只能在set中保留一条记录

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    import java.util.HashSet;
    import java.util.Objects;

    @SuppressWarnings({"all"})
    public class Set_ {
    public static void main(String[] args) {

    HashSet hashSet = new HashSet();
    hashSet.add(new Dog("大黄",new MyDate("2023","10","30")));
    hashSet.add(new Dog("大黄",new MyDate("2023","10","30")));
    System.out.println(hashSet);
    }
    }

    class Dog{
    private String name;
    private MyDate birth;
    public Dog(String name, MyDate birth) {
    this.name = name;
    this.birth = birth;
    }

    @Override
    public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    Dog dog = (Dog) o;
    return Objects.equals(name, dog.name) && Objects.equals(birth, dog.birth);
    }

    @Override
    public int hashCode() {
    return Objects.hash(name, birth);
    }
    }

    class MyDate{
    private String year;
    private String month;
    private String day;

    public MyDate(String year, String month, String day) {
    this.year = year;
    this.month = month;
    this.day = day;
    }

    @Override
    public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    MyDate myDate = (MyDate) o;
    return Objects.equals(year, myDate.year) && Objects.equals(month, myDate.month) && Objects.equals(day, myDate.day);
    }

    @Override
    public int hashCode() {
    return Objects.hash(year, month, day);
    }
    }
  • HashSet 一个有意思的程序

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    import java.util.HashSet;
    import java.util.Objects;

    @SuppressWarnings({"all"})
    public class HomeWork3 {
    public static void main(String[] args) {
    HashSet hashSet = new HashSet();
    Person p1 = new Person(1001, "tom");
    Person p2 = new Person(1002, "jack");
    hashSet.add(p1);
    hashSet.add(p2);
    System.out.println(hashSet);
    p1.setName("cjp");
    // 此时name变成了 cjp,所以计算hash值时,hash值就改变了
    hashSet.remove(p1);
    // 同理能使用一个新的hash值插入
    hashSet.add(p1);
    // hash值虽然已存在但是 equals 结果不相等,所以可以插入新值
    hashSet.add(new Person(1001,"tom"));
    for (Object obj:hashSet) {
    System.out.println(obj);
    }
    }
    }

    class Person{
    private int id;
    private String name;

    public Person(int id, String name) {
    this.id = id;
    this.name = name;
    }

    public void setName(String name) {
    this.name = name;
    }

    @Override
    public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    Person person = (Person) o;
    return id == person.id && Objects.equals(name, person.name);
    }

    @Override
    public int hashCode() {
    return Objects.hash(id, name);
    }

    @Override
    public String toString() {
    return "Person{" +
    "id=" + id +
    ", name='" + name + '\'' +
    '}';
    }
    }

LinkedHashSet 【存入和取出的顺序是一致的】【数组+双向链表+红黑树】

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import java.util.Iterator;
import java.util.LinkedHashSet;

@SuppressWarnings({"all"})
public class LinkedHashSet_ {
public static void main(String[] args) {
LinkedHashSet linkedHashSet = new LinkedHashSet();
linkedHashSet.add("aaa");
linkedHashSet.add("bbb");
linkedHashSet.add("ccc");
linkedHashSet.add("ccc");
linkedHashSet.add(456);
linkedHashSet.add(456);
linkedHashSet.add("ddd");
System.out.println(linkedHashSet);
// 遍历数据
Iterator ite = linkedHashSet.iterator();
while (ite.hasNext()){
Object next = ite.next();
System.out.println(next);
}


}
}

TreeSet

  • 添加的数据的对象类型必须实现了comparable接口或者new TreeSet时传入Comparator的匿名类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import java.util.Comparator;
import java.util.TreeSet;

@SuppressWarnings({"all"})
public class TreeSet_ {
public static void main(String[] args) {

TreeSet treeSet = new TreeSet(new Comparator() {
@Override
public int compare(Object o1, Object o2) {
return ((String)o2).compareTo((String)o1);
}
});

treeSet.add("tom");
treeSet.add("jack");
treeSet.add("cjp");
treeSet.add("d");
System.out.println(treeSet);

}
}

Map

HashMap

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

@SuppressWarnings({"all"})
public class Map_ {
public static void main(String[] args) {
HashMap hashMap = new HashMap();
// 添加元素
hashMap.put("username","gphper");
hashMap.put("age",10);
// 获取元素
System.out.println(hashMap.get("username"));
// 删除
hashMap.remove("username");
// 获取数量
System.out.println(hashMap.size());
// 是否为空
System.out.println(hashMap.isEmpty());
// 是否包含
System.out.println(hashMap.containsKey("username"));
// 清空map
hashMap.clear();

// 遍历 key-value
Set set = hashMap.entrySet();
for (Object obj : set){
Map.Entry entry = (Map.Entry) obj;
System.out.println(entry.getKey()+"-"+entry.getValue());
}

// 遍历key
Set set1 = hashMap.keySet();
for(Object obj:set1){
System.out.println(obj);
}

// 遍历value
Collection values = hashMap.values();
for(Object obj:values){
System.out.println(obj);
}
}
}

HashTable

  • 键和值都不能为空
  • 线程安全

扩容机制

初始为 11

临界值 容量 * 0.75

扩容时 新容量 = 原先的容量 * 2 + 1

Properties

  • 读取配置文件使用

Collections 工具类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

@SuppressWarnings({"all"})
public class CollecUtil {
public static void main(String[] args) {
ArrayList arrayList = new ArrayList();
arrayList.add("aa");
arrayList.add("bb");
arrayList.add("cc");
arrayList.add("cc");
arrayList.add("dd");
System.out.println(arrayList);
// 打乱顺序
Collections.shuffle(arrayList);
System.out.println(arrayList);
// 自然排序
Collections.sort(arrayList);
System.out.println(arrayList);
// 指定规则排序
Collections.sort(arrayList, new Comparator() {
@Override
public int compare(Object o1, Object o2) {
return ((String)o2).compareTo((String)o1);
}
});
System.out.println(arrayList);
// swap 交换
Collections.swap(arrayList,2,3);
System.out.println(arrayList);

// 出现的次数
System.out.println(Collections.frequency(arrayList,"cc"));
// 复制 需要先给目标list赋值
ArrayList arrayList1 = new ArrayList();
for (int i = 0;i< arrayList.size();i++){
arrayList1.add("");
}

Collections.copy(arrayList1,arrayList);
System.out.println(arrayList1);
// 替换所有
Collections.replaceAll(arrayList,"cc","cjp");
System.out.println(arrayList);
}
}