Collection接口

概述

数组和集合都是Java中提供的容器

集合: 英文译为 Collection,用来存放对象的容器,集合中可以存放不同类型的对象,并且集合的长度可变。

在编程时,常常需要集中存放多个数据,可以使用数组来保存多个对象,但数组长度不可变化,一旦在初始化数组时指定了数组长度,这个数组长度就是不可变的,如果需要保存数量变化的数据,数组就有点无能为力了;

为了保存数量不确定的数据,以及保存具有映射关系的数据,Java提供了集合类。集合类主要负责保存、盛装其他数据,因此集合类也被称为容器类。

小结: 集合和数组的对比:

  1. 数组中的元素可以基本类型的值,也可以是对象; 而集合中只能保存对象
  2. 数组一旦指定了长度,长度就不能再改变; 而集合的长度是可以随时改变的
  3. 往数组中插入元素非常麻烦,需要将插入位置后面的元素往后移动; 或者删除数组中间位置的某一个元素, 需要将删除位置后的元素往前移动; 而如果往集合中插入元素或者删除集合中的某一个元素,直接使用现成的方法操作即可

集合的继承结构

由于需求不同,Java就提供了不同的集合类。这多个集合类的数据结构不同,但是它们都是要提供存储和遍历功能的,我们把它们的共性不断的向上提取,最终就形成了集合的继承体系结构图。

Collection接口

  • List接口
  • ArrayList类
  • LinkedList类
  • Set接口
  • HashSet类
  • TreeSet类

解释说明:

  • Collection集合是所有单值集合的顶层接口, 其中定义了常用的用于操作集合以及集合中元素的方法

    例如: 添加元素、删除元素、获取元素、获取集合长度、判断功能、将集合转成数组、迭代器遍历元素等功能

  • List是Collection的子接口,特点是其中的元素是有序的(即:元素存入集合时的顺序和取出的顺序一致)

    可以通过下标访问List中的元素,另,List集合中的元素是可以重复的(包括null)

  • Set也是Collection的子接口,特点是其中的元素是无序(即:元素存入集合时的顺序和取出的顺序不一定一致)

    无法通过下标访问Set中的元素,另外,Set集合中的元素是不可以重复的

学习集合的建议:

  • 学习接口中提供的共性方法

  • 通过实现类创建对象, 调用这些共性方法

常用方法

!!boolean add(E e)

  • 往集合中添加指定元素e

boolean addAll(Collection c)

  • 将小集合添加到大集合中

!!boolean isEmpty()

  • 如果集合中没有任何元素(空集合), 返回true

boolean contains(Object o)

  • 如果此集合中包含指定元素o, 则返回true

boolean containsAll(Collection c)

  • 如果此集合中包含指定 集合c 中的所有元素,则返回 true。
  • 例如c1中有 “a”,“b”,“c”,“d”, 而c2中有"a",“b”, 则c1包含c2, 返回true
    若,c1中有 “a”,“b”,“c”,“d”, 而c2中有"x",“a”,“b”, 则c1不包含c2, 返回false

!!int size()

  • 返回集合的大小(元素个数)

!!boolean remove(Object o)

  • 从集合中删除指定的元素o, 删除成功则返回true
  • 如果删除的元素不存在导致删除失败, 则返回false
  • 如果元素o在集合中出现多次,仅删除第一个

boolean removeAll(Collection c)

  • 删除此集合中那些也包含在指定集合c中的所有元素, 若有共同元素, 则删除并返回true
    例如 c1中有 “a”,“b”,“c”,“d”, 而c2中有"x",“a”,“b”,

c1.removeAll(c2),只删除c1中两个共同的元素 “a”,“b”, 对c2没有影响

  • 如果两个集合中没有共同元素, 则不删除, 返回false

boolean retainAll(Collection c)

  • 仅保留此集合中那些也包含在指定集合c中的元素
  • 例如 c1中有 “a”,“b”,“c”,“d”, 而c2中有"x",“a”,“b”,
    c1.retainAll(c2),只保留c1中两个共同的元素 “a”,“b”, 对c2没有影响

void clear()

  • 删除此集合中的所有元素

Object[] toArray()

  • 将此集合转成对象数组

boolean equals(Object o)

  • 比较此 collection 与指定对象是否相等。

!!Iterator iterator()

  • 返回此集合中所有元素组成的迭代器。

实例1:CollectionDemo1

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
package collection;

import java.util.ArrayList;
import java.util.Collection;

/**
* JAVA集合框架
* 集合和数组一样,可以保存一组元素,但是集合将元素的操作封装成了方法,操作简便,并且集合还提供了多种不同的实现供我们使用
* java.util.Collection是所有集合的顶级接口,里面定义了所有的集合都必须具备的功能和方法
* 集合有两类常用的子类:
* java.util.List:可重复的集合,且有序,通常我们称之为"线性表"
* java.util.Set:不可重复的集合
* 上述两个都是接口,而元素是否重复取决于元素的自身的equals方法,即:Set集合不会存在两个元素equals比较为true的情况.
*/
public class CollectionDemo1 {
   public static void main(String[] args) {
       //类型声明为Collection的目的是什么? c变量只能调用Collection中声明的方法
       //集合中只能存放引用类型
       Collection c = new ArrayList();
       /*
        * add:加
        * boolean add(E e) 这个E是泛型,先理解为是Object
        * 向当前集合添加一个元素,如果该元素成功添加返回true,否则返回false
        */
       c.add("one");
       c.add("two");
       c.add("three");
       c.add("four");
       c.add("five");
       //[one, two, three, four, five]
       System.out.println(c);
       c.add("six");
       //[one, two, three, four, five, six]
       System.out.println(c);
       c.add(1);//自动装箱 c.add(Integer.valueOf(1))
       c.add(true);
       //[one, two, three, four, five, six, 1, true]
       System.out.println(c);
       /*
        * int size()
        * 返回当前集合的元素个数
        * 区别于数组的length,length是属性,size()是方法,length表示数组能存多少,但是存不够长度也不能改变,但是size不是,表示集合中的元素个数
        */
       int size = c.size();
       System.out.println("集合的元素的个数:"+size);
       boolean empty = c.isEmpty();
       //如果size=0,就返回true
       System.out.println("集合是否为空集:"+empty);
       c.clear();
       System.out.println(c);
       System.out.println("集合的元素个数:"+c.size());
       System.out.println("集合是否为空集:"+c.isEmpty());
  }
}

实例2:CollectionDemo2

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
package collection;

import pojo.Point;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;

/**
* 使用当前类作为集合元素测试集合相关操作
*/
public class CollectionDemo2 {
   public static void main(String[] args) {
       //Collection c = new HashSet();
       Collection c = new ArrayList();
       c.add(new Point(1, 2));
       c.add(new Point(1, 2));//Set集合不能存储重复元素
       c.add(new Point(1, 2));
       c.add(new Point(3, 4));
       c.add(new Point(5, 6));
       c.add(new Point(7, 8));
       c.add(new Point(9, 0));
       /*
        * 集合重写了toString方法,格式为:
        * [元素1.toString(),元素2.toString(),...]
        */
       System.out.println(c);
       Point p = new Point(1, 2);
       /*
        * boolean contains(Object o)
        * 判断当前集合中是否包含给定的元素
        * 元素是否包含取决于该元素是否与集合现有元素存在equals比较为true的情况
        */
       boolean contains = c.contains(p);
       System.out.println("集合中是否包含(1,2)点:"+contains);
       /*
       * remove方法删除元素时,也是与集合中元素进行equals方法比较结果为true时,删除元素
       * 但是对于List集合而言,由于可以存储重复元素,所以这种删除只会删除遇到的第一个元素
       * */
       c.remove(p);
       System.out.println(c);
  }
}

Point

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
package pojo;

import java.util.Objects;

public class Point {
   private int x;
   private int y;
   //alt+insert
   public Point(int x, int y) {
       this.x = x;
       this.y = y;
  }

   public int getY() {
       return y;
  }

   public void setY(int y) {
       this.y = y;
  }

   public int getX() {
       return x;
  }

   public void setX(int x) {
       this.x = x;
  }

   @Override
   public String toString() {
       return "(" + x + "," + y +")";
  }

   @Override
   public boolean equals(Object o) {
       if (this == o) return true;
       if (o == null || getClass() != o.getClass()) return false;
       Point point = (Point) o;
       return x == point.x && y == point.y;
  }

   @Override
   public int hashCode() {
       return Objects.hash(x, y);
  }
}

实例4:CollectionDemo4

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
61
62
package collection;

import java.util.ArrayList;
import java.util.Collection;

/**
* @author 老安
* @data 2022/7/18 19:40
* 集合间的操作
*/
public class CollectionDemo4 {
   public static void main(String[] args) {
       Collection c1 = new ArrayList();
       c1.add("java");
       c1.add("c++");
       c1.add(".net");
       //c1集合:[java, c++, .net]
       System.out.println("c1集合:" + c1);
       Collection c2 = new ArrayList();
       c2.add("android");
       c2.add("ios");
       c2.add("java");
       //c2集合:[android, ios, java]
       System.out.println("c2集合:" + c2);
       /*
       * 将c2集合添加到c1集合中
       * */
       c1.addAll(c2);
       //c1集合:[java, c++, .net, android, ios, java]
       System.out.println("c1集合:" + c1);
       //c2集合:[android, ios, java]
       System.out.println("c2集合:" + c2);
       Collection c3 = new ArrayList();
       c3.add("c++");
       c3.add("ios");
       //c3.add("php"); 如果添加php,就会返回false
       //[c++, ios]
       System.out.println("c3集合:" + c3);
       /*
       * 判断c1集合中是否包含c3集合中的所有元素
       * */
       boolean containsAll = c1.containsAll(c3);
       System.out.println("c1集合是否包含c3集合:"+containsAll);
       /*
       * 将c1集合的元素和c3集合的相同元素进行保留
       * 取两个集合的交集
       * */
       c1.retainAll(c3);
       //[c++, ios]
       System.out.println("c1集合:" + c1);
       //[c++, ios]
       System.out.println("c3集合:" + c3);
       /*
       * 删除交集,将c1集合与c3集合公有的元素进行删除(c3不受影响)
       * */
       c1.removeAll(c3);
       //[]
       System.out.println("c1集合:" + c1);
       //[c++, ios]
       System.out.println("c3集合:" + c3);
  }
}

集合的遍历

IteratorDemo

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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
package collection;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

/**
* @author 老安
* @data 2022/7/18 20:00
* 集合的遍历
* Collection层面上不支持随机访问操作(根据指定的位置获取对应的元素),但是集合的子类是支持的,我们后面学习
* 而Collection层面上想要取出集合的元素只能通过遍历集合,从而拿出集合中的每一个元素
* 集合提供了统一遍历的方式:迭代器遍历模式
* 对应方法:
* Iterator iterator()
* 该方法会返回一个用于遍历当前集合的迭代器对象
*/
public class IteratorDemo {
   public static void main(String[] args) {
       Collection c = new ArrayList();
       c.add("a");
       c.add("#");
       c.add("b");
       c.add("#");
       c.add("c");
       c.add("#");
       c.add("d");
       c.add("#");
       c.add("e");
       System.out.println(c);
       /*
       * 迭代器使用方式:
       * */
       //1:获取要遍历的集合的迭代器对象
       Iterator it = c.iterator();
       //2:问(问集合是否有下一个元素可以遍历)
       /*
       * boolean hasNext()
       * 判断集合是否有下一个元素可以遍历
       * 迭代器的起始位置是集合的第一个元素之前,因此第一次调用hasNext()就是判断集合是否有第一个元素
       * */
       while (it.hasNext()){
           //3:取(取出下一个元素)
           /*
           * E next()
           * 取出集合中的下一个元素,获取元素后,迭代器的位置会向后移动一个元素的位置
           * */
           String e = (String) it.next();
           if ("#".equals(e)){
               //4:删(删除集合中的指定元素)
               /*
               * 迭代器在遍历的过程中,不能通过集合的方法来增删元素,
               * 但是可以通过迭代器的方法来删元素
               * 迭代器提供了remove()方法,该方法会将本次next()取出的元素从集合中删除
               * */
               //c.remove(e);
               it.remove();
          }
      }
       System.out.println(c);
  }
}

## 增强型for循环

**NewForDemo**
```JAVA
package collection;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

/**
* @author 老安
* @data 2022/7/18 20:24
* JDK5推出时,推出了一个新的特性:增强型for循环
* 通常也称之为叫做新循环和foreach循环
* 新循环不会取代传统for循环的操作,它的出现仅仅是为了使用相同的语法去遍历集合和数组
* 语法:
* for(元素类型 e : 集合或者数组){
* <p>
* }
*/
public class NewForDemo {
   public static void main(String[] args) {
       String[] array = {"a", "b", "c", "d", "e"};
       //传统for循环
       //array.fori
       for (int i = 0; i < array.length; i++) {
           String s = array[i];
           System.out.println(s);
      }
       //新循环 array.for
       for (String s : array) {
           System.out.println(s);
      }
       /*
       * 集合之所以能够装载所有类型的元素,是因为集合装载的类型是Object类型
       * 集合和数组一样,一般情况下,都装载同一类型元素
       * 集合的泛型可以约束集合中装载的元素类型是什么
       * */
       Collection<String> c = new ArrayList<>();
       c.add("A");//编译器会检查传入的参数是否是泛型的指定的类型
       c.add("B");
       c.add("C");
       c.add("D");
       c.add("E");
       //c.for
       //新循环就是迭代器遍历
       for (String s : c) {
           System.out.println(s);
      }
  }
}

List集合

概述

List是一个有序的Collection(List是Collection的子接口),使用此接口能够精确的控制每个元素插入的位置,能够通过索引(类似于数组的下标)来访问List中的元素,第一个元素的索引为 0,而且允许有相同的元素。

List 接口存储一组可重复、有序(插入顺序)的对象。

特点

  1. 元素有下标,可以通过下标访问元素
  2. 元素是有序的(存入集合的顺序和取出的顺序一定相同)
  3. 元素可以重复(包括null)

List方法测试

ListDemo

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
package collection;

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

/**
* @author 老安
* @data 2022/7/18 21:22
* java.util.List接口
* List继承自Collection,是最常用的一类集合.特点:可以存放重复的元素且有序
* List里提供了一套可以通过下标操作元素的方法
* 常用实现类:
* java.util.ArrayList:内部使用数组实现,查询性能更好
* java.util.LinkedList:内部使用链表实现,增删性能更好
* 对性能没有特别苛刻的要求下,通常使用ArrayList即可
*/
public class ListDemo {
   public static void main(String[] args) {
       List<String> list = new ArrayList<>();
       list.add("a");
       list.add("b");
       list.add("c");
       list.add("d");
       list.add("e");
       System.out.println(list);
       //获取集合中的第三个元素
       /*
        * E get(int index)
        * 获取指定下标对应的元素
        * */
       String str = list.get(2);
       System.out.println(str);
       //通过下标来遍历集合
       for (int i = 0; i < list.size(); i++) {
           String s = list.get(i);
           System.out.println(s);
      }
       //新循环遍历一定是从头到尾都遍历一次
       for (String s : list) {
           System.out.println(s);
      }
       /*
       * E set(int index,E e)
       * 将给定的元素设置到集合的指定的位置,返回值为该位置原来的元素
       * 替换元素的操作
       * */
       //给集合list的下标1的位置设置新的元素f,将被替换的b返回
       String old = list.set(1, "f");
       System.out.println(old);
       System.out.println(list);
  }
}

ListDemo2

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
package collection;

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

/**
* @author 老安
* @data 2022/7/18 21:22
* List重载了一对add和remove方法
*/
public class ListDemo1 {
   public static void main(String[] args) {
       List<String> list = new ArrayList<>();
       list.add("a");
       list.add("b");
       list.add("c");
       list.add("d");
       list.add("e");
       System.out.println(list);
       //给集合list下标3的位置插入新的元素"f"
       /*
       * void add(int index,E e)
       * 将给定的元素插入到指定的位置
       * */
       list.add(3,"f");
       System.out.println(list);
       //删除list集合中下标为2的元素,并将删除的元素返回
       /*
       * E remove(int index)
       * 删除并返回指定位置的元素
       * */
       String old = list.remove(2);
       System.out.println(old);
       System.out.println(list);
  }
}

ListDemo3

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
package collection;

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

/**
* @author 老安
* @data 2022/7/18 21:22
* List提供的方法:
* List subList(int start,int end)
* 获取当前集合中指定范围内的子集
*/
public class ListDemo2 {
   public static void main(String[] args) {
       //泛型指定时,必须要写引用类型
       List<Integer> list = new ArrayList<>();
       //10.fori
       for (int i = 0; i < 10; i++) {
           list.add(i);
      }
       //[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
       System.out.println(list);
       //获取子集[3,7] 含头不含尾
       List<Integer> subList = list.subList(3, 8);
       //[3, 4, 5, 6, 7]
       System.out.println(list);
       System.out.println(subList);
       //将子集每个元素都扩大10倍
       //[30,40,50,60,70]
       //遍历集合中的每一个元素
       //i就是下标
       for (int i = 0; i < subList.size(); i++) {
           //获取当前元素,并扩大10被,然后赋值给当前遍历的下标位置
           subList.set(i,subList.get(i)*10);
      }
       System.out.println(subList);
       //对子集的操作就是对原集合对应的元素的操作
       System.out.println(list);
       //可以利用subList方法操作集合的部分元素
       //清空集合中1-8这部分的元素
       list.subList(1,9).clear();
       System.out.println(list);
  }
}

集合和数组的转换

集合转换数组:CollectionToArrayDemo

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
package collection;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;

/**
* @author 老安
* @data 2022/7/20 20:51
* 将一个集合转换为数组
*/
public class CollectionToArrayDemo {
   public static void main(String[] args) {
       Collection<String> c = new ArrayList<>();
       c.add("A");
       c.add("B");
       c.add("C");
       c.add("D");
       c.add("E");
       System.out.println("集合:"+c);
       /*
       * toArray由于默认是Object类型,所以使用非常少,
       * 一般都使用他的重载方法toArray(Object[] arr)
       * 要生成什么类型的数组,arr就声明什么类型,并且数组的长度,
       * 一般都指定成集合的元素数量
       * */
       String[] array = c.toArray(new String[c.size()]);
       System.out.println("数组:"+ Arrays.toString(array));
  }
}

数组转换集合: ArrayToListDemo

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
package collection;

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

/**
* @author 老安
* @data 2022/7/20 20:59
* 数组转换为集合
*/
public class ArrayToListDemo {
   public static void main(String[] args) {
       String[] arr = {"A","B","C","D","E"};
       System.out.println("数组:"+Arrays.toString(arr));
       //数组转换为集合的方法
       List<String> list = Arrays.asList(arr);
       System.out.println("集合:"+list);
       //对list集合的操作,同时也会更改arr数组
       list.set(1, "F");
       System.out.println("数组:"+Arrays.toString(arr));
       System.out.println("集合:"+list);
       arr[0] = "G";
       System.out.println("数组:"+Arrays.toString(arr));
       System.out.println("集合:"+list);
       /*
       * 由于集合和数组关联了,而且数组是定长的,所以给集合中新增元素,
       * 同时也会给数组新加元素,但是数组不能新加,就会报错
       * */
       //list.add("H");
       //List<String> list2 = new ArrayList<>();
       //list2.addAll(list);
       //创建集合,并且将list集合的元素装载到list2中
       List<String> list2 = new ArrayList<>(list);
       list2.add("H");
       System.out.println("数组:"+Arrays.toString(arr));
       System.out.println("集合:"+list);
       System.out.println("集合:"+list2);
  }
}

集合的排序

SortListDemo

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
package collection;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;

/**
* @author 老安
* @data 2022/7/20 21:12
*/
public class SortListDemo {
   public static void main(String[] args) {
       List<Integer> list = new ArrayList<>();
       Random random = new Random();
       for (int i = 0; i < 10; i++) {
           //生成一个随机整数
           int a = random.nextInt(100);
           list.add(a);
      }
       System.out.println("乱序集合:"+list);
       Collections.sort(list);//会自然排序,从小到大
       System.out.println("从小到大集合:"+list);
       Collections.reverse(list);//反转集合的元素
       System.out.println("从大到小集合:"+list);
  }
}

Map接口

概述

Map用于保存具有映射关系的数据,因此Map集合里保存着两组值,一组值用于保存Map里的键(key)另外一组值用于保存Map里的值(value),键和值是一一对应的关系,称为映射。根据键就能找到对应的值,类似于生活中一张身份证对应一个人一样。

Map的key和value可以是任何引用类型的数据,其中key不允许重复,同一个Map对象的任何两个key通过equals方法比较总是返回false。

特点

  1. Map集合中每个元素都有两个值, 分别是key(键) 和 value(值)
  2. Map集合中的key(键)不允许重复, 在第二次添加已有的key时, value会被会覆盖
  3. Map集合中的元素是无序的(即元素存入集合的顺序和取出时的顺序很可能不一致)
  4. Map集合中的key和value具有映射关系, 可以通过key(键)来获取对应的value(值)

key和value之间存在单向一对一关系,即通过指定的key,总能找到唯一的、确定的value。从Map中取出数据时,只要给出指定的key,就可以取出对应的value。

如果把Map里的所有key放在一起来看,它们就组成了一个Set集合(所有的key没有顺序,key与key之间不能重复),实际上Map确实包含了一个keySet()方法,用于返回Map里所有key组成的Set集合。

如果把Map里的所有value放在一起来看,它们又非常类似于一个List:元素与元素之间可以重复,每个元素可以根据索引来查找,只是Map中的索引(也就是key)不是从0开始的整数值,而是任意类型的对象;

如果需要从List集合中取出元素,则需要提供该元素的数字索引;如果需要从Map中取出元素,则需要提供该元素的key。因此,Map有时也被称为字典,或关联数组。

继承结构

Map接口

  • HashMap类
  • TreeMap类
  • Hashtable类

解释说明:

  • Map集合是采用键-值对(key-value)的存储方式, 键(key)、值(value)可以是引用类型的数据, key不允许重复, vaue可以重复, key和value是一对一的关系, 通过指定的key总能找到唯一的、确定的value值

  • HashMap 和 Hashtable 都是Map接口的实现类,它们之间的关系完全类似于ArrayList和Vector的关系

  1. HashMap是线程不安全的, 所以HashMap的性能要比HashTable高一些
  2. HashMap可以使用null作为key或value, Hashtable不允许使用null作为key和value;
  3. Hashtable是一个古老的Map实现类,JDK 1.0出现,出现时,Java还没有提供Map接口,命名没有遵守Java的命名规范,与Vector类似的是,尽量少用Hashtable实现类,即使需要创建线程安全的Map实现类,也无须使用Hashtable实现类,可以通过别的方式来解决线程安全问题。
  • TreeMap是Map的子接口SortedMap的的实现类, 是可以支持对内部元素进行排序的类, 也正因为如此, TreeMap的执行效率通常要比HashMap和HashTable慢。

MapDemo

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
package map;

import java.util.HashMap;
import java.util.Map;

/**
* java.util.Map接口 查找表
* Map体现的结构是一个多行两列的表格,其中左列称之为"key",右列称之为"value"
* Map总是以key-value(键值对)的形式保存一组数据,并且可以根据key获取对应的value.
* Map有一个要求,key不能重复(通过equals比较)
* 常用实现类:
* java.util.HashMap 我们称之为"散列表".当今查询速度最快的数据结构
*/
public class MapDemo {
   public static void main(String[] args) {
       Map<String,Integer> map = new HashMap<>();
       //V put(K k,V v)
       //向当前Map中保存一组键值对
       map.put("语文", 80);
       map.put("英语", 90);
       map.put("物理", 60);
       map.put("化学", 100);
       //{物理=60, 化学=100, 语文=80, 英语=90}
       System.out.println(map);
       Integer score = map.put("数学", 70);
       System.out.println(map);
       System.out.println(score);//由于key不存在,所以就返回null
       score = map.put("数学", 100);
       System.out.println(map);
       System.out.println(score);//由于key存在,就返回覆盖的value的内容
       //V get(Object key) 通过key值获取对应的value值
       score = map.get("语文");
       System.out.println(score);
       //返回Map中的元素个数
       int size = map.size();
       System.out.println(size);
       //判断是否包含key
       boolean ck = map.containsKey("英语");
       System.out.println(ck);
       //判断是否包含value
       boolean cv = map.containsValue(97);
       System.out.println(cv);
  }
}

变量分析

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
package test;

import pojo.Point;

import java.util.ArrayList;
import java.util.Collection;

/**
* 局部变量在栈中
* 对象都在堆中
* 属性都在对象中(在堆里)
*
* 基本类型保存的只就是值本身 在栈中
* 引用类型保存的值是对象在堆里的地址
*/
public class Demo {
   public static void main(String[] args) {
       String s = "hello";
       int a = 1;
       Point p = new Point(1, 2);
       Collection c = new ArrayList();
       c.add(p);
       test(s, a, p, c);
       System.out.println("s:" + s);//?
       System.out.println("a:" + a);//?
       System.out.println("p:" + p);//?
       System.out.println("c:" + c);//?
  }
   public static void test(String s, int a, Point p, Collection c) {
       a++;
       s = s + "world";
       p.setX(3);
       p = new Point(4, 5);
       c.clear();
       c.add(p);
       c = new ArrayList();
       p.setX(7);
       c.add(p);
  }
}