集合

2021-01-31  本文已影响0人  c_gentle

一、集合框架体系

集合是Java中提供的一种容器,可以用来存储多个数据,根据不同存储方式形成的体系结构,就叫做集合框架体系。


image.png

每一种容器类底层拥有不同的底层算法。
既然数组可以存储多个数据,为什么要出现集合?
数组的长度是固定的,集合的长度是可变的。
使用Java类封装出一个个容器类,开发者只需要直接调用即可,不用再手动创建容器类。
集合中存储的数据,叫做元素,元素只能是对象(引用类型)。

二、 容器的分类

根据容器的存储特点的不同,可以分成三种情况:


image.png

三、List接口

List接口是Collection接口子接口,List接口定义了一种规范,要求该容器允许**记录元素的添加顺序,也允许元素重复。那么List接口的实现类都会遵循这一种规范。
List集合存储特点:

1、List常用API方法

添加操作
boolean add(Object e):将元素添加到列表的末尾

2、ArrayList类

ArrayList类,基于数组算法的列表,通过查看源代码会发现底层其实就是一个Object数组。
操作List接口常用方法

public class ArrayListDemo1 {
    public static void main(String[] args) {
        //创建一个默认长度的列表对象
        List list = new ArrayList();
        //打印集合中元素的个数
        System.out.println("元素数量:"+list.size());//0
        //添加操作:向列表中添加4个元素
        list.add("Will");
        list.add(100);
        list.add(true);
        list.add("Lucy");
        //查询操作:
        System.out.println("列表中所有元素:"+list);//输出:[Will, 100, true, Lucy]
        System.out.println("元素数量:"+list.size());//4
        System.out.println("第一个元素:"+list.get(0));//Will
        
        //修改操作:把索引为2的元素,替换为wolfcode
        list.set(2, "wolfcode");
        System.out.println("修改后:"+list);//输出:[Will, 100, wolfcode, Lucy]
        
        //删除操作:删除索引为1的元素
        list.remove(1);
        System.out.println("删除后:"+list);//输出:[Will, wolfcode, Lucy]
    }
}

3、LinkedList类

​ ArrayList类,基于数组算法的列表,通过查看源代码会发现底层其实就是一个Object数组。
​ LinkedList类,底层采用链表算法,实现了链表,队列,栈的数据结构。无论是链表还是队列主要操作的都是头和尾的元素,因此在LinkedList类中除了List接口的方法,还有很多操作头尾的方法。

public class LinkedListDemo {
    public static void main(String[] args) {
        LinkedList list = new LinkedList();
        //添加元素
        list.addFirst("A");
        list.addFirst("B");
        System.out.println(list);
        list.addFirst("C");
        System.out.println(list);
        list.addLast("D");
        System.out.println(list);
        //获取元素
        System.out.println("获取第一个元素:" + list.getFirst());//C
        System.out.println("获取最后一个元素:" + list.getLast());//D
        //删除元素
        list.removeFirst();
        System.out.println("删除第一个元素后:" + list);//[B, A, D]
        list.removeLast();
        System.out.println("删除最后一个元素后:" + list);//[B, A]
    }
}

4、Stack和Vector类

​ Vector类:基于数组算法实现的列表,其实就是ArrayList类的前身。和ArrayList的区别在于方法使用synchronized修饰,所以相对于ArrayList来说,线程安全,但是效率就低了点。
​ Stack类:表示栈,是Vector类的子类,具有后进先出(LIFO)的特点,拥有push(入栈),pop(出栈)方法。

四、集合元素迭代

1、集合元素遍历

对集合中的每一个元素获取出来。

List<String> list = new ArrayList<>();
list.add("西施");
list.add("王昭君");
list.add("貂蝉");
list.add("杨玉环");

使用for遍历

for (int index = 0; index < list.size(); index++) {
    String ele = list.get(index);
    System.out.println(ele);
}

使用迭代器遍历
Iterator表示迭代器对象,迭代器中拥有一个指针,默认指向第一个元素之前,

Iterator<String> it = list.iterator();
while(it.hasNext()) {
    String ele = it.next();
    System.out.println(ele);
}

操作原理如下图:


image.png

使用for-each遍历,推荐
语法:

for(元素类型 变量 : 数组/Iterable实例对象){
//TODO
}

这里Iterable实例对象表示,Iterable接口实现类对象,其实就是Collection,不包括Map。

for (String ele : list) {
    System.out.println(ele);
}

2、并发修改异常

需求:在迭代集合时删除集合元素,比如删除王昭君。

List<String> list = new ArrayList<>();
list.add("西施");
list.add("王昭君");
list.add("貂蝉");
list.add("杨玉环");

System.out.println(list);
for (String ele : list) {
    if("王昭君".equals(ele)) {
        list.remove(ele);
    }
}
System.out.println(list);

​ 此时报错java.util.ConcurrentModificationException,并发修改异常。
​ 造成该错误的原因是,不允许在迭代过程中改变集合的长度(不能删除和增加)。如果要在迭代过程中删除元素,就不能使用集合的remove方法,只能使用迭代器的remove方法,此时只能使用迭代器来操作,不能使用foreach。

List<String> list = new ArrayList<>();
list.add("西施");
list.add("王昭君");
list.add("貂蝉");
list.add("杨玉环");
System.out.println(list);
//获取迭代器对象
Iterator<String> it = list.iterator();
while(it.hasNext()) {
    String ele = it.next();
    if("王昭君".equals(ele)) {
        it.remove();
    }
}
System.out.println(list);

五、Set接口

​ Set是Collection子接口,Set接口定义了一种规范,也就是该容器不记录元素的添加顺序,也不允许元素重复,那么Set接口的实现类都遵循这一种规范。
Set集合存储特点:

1、HashSet类

HashSet底层采用哈希表实现,元素对象的hashCode值决定了在哈希表中的存储位置。
​ 当往HashSet集合中添加新的元素对象时,先回判断该对象和集合对象中的hashCode值:

public class ArrayListDemo2 {
    public static void main(String[] args) {
        Set<String> set = new HashSet<>();
        //添加操作:向列表中添加4个元素
        set.add("Will");
        set.add("wolf");
        set.add("code");
        set.add("Lucy");
        //查询操作:
        System.out.println("集合中所有元素:" + set);//[code, wolf, Will, Lucy]
        System.out.println("元素数量:" + set.size());//4
        System.out.println("是否存在某个元素:" + set.contains("code"));//true
        System.out.println("是否存在某个元素:" + set.contains("code2"));//false
        //删除操作:删除code元素
        set.remove("code");
        System.out.println("删除后:" + set);//[wolf, Will, Lucy]
        //使用for-each遍历
        for (String ele : set) {
            System.out.println(ele);
        }
        //使用迭代器遍历
        Iterator<String> it = set.iterator();
        while (it.hasNext()) {
            Object ele = it.next();
            System.out.println(ele);
        }
    }
}

六、Map接口

1、认识Map

2、Map常用方法

添加操作
boolean put(Object key,Object value):存储一个键值对到Map中

3、HashMap

HashMap底层基于哈希表算法,Map中存储的key对象的hashCode值决定了在哈希表中的存储位置,因为Map中的key是Set,所以不能保证添加的先后顺序,也不允许重复。

需求1:操作Map接口常用方法

public class HashMapDemo1{
    public static void main(String[] args) {
        Map<String, String> map = new HashMap<>();
        map.put("girl1", "西施");
        map.put("girl2", "王昭君");
        map.put("girl3", "貂蝉");
        map.put("girl4", "杨玉环");
        System.out.println("map中有多少键值对:"+map.size());
        System.out.println(map);
        System.out.println("是否包含key为girl1:"+map.containsKey("girl1"));
        System.out.println("是否包含value为貂蝉:"+map.containsValue("貂蝉"));
        //替换key为girl3的value值
        map.put("girl3", "小乔");
        System.out.println(map);
        //删除key为girl3的键值对
        map.remove("girl3");
        System.out.println(map);
    }
}

Map的迭代遍历:

//获取Map中所有的key
Set<String> keys = map.keySet();
System.out.println("Map中所有key:"+keys);
//获取Map中所有的value
Collection<String> values = map.values();
System.out.println("Map中所有value:"+values);
//获取Map中所有的key-value(键值对)
Set<Entry<String, String>> entrys = map.entrySet();
for (Entry<String, String> entry : entrys) {
    String key = entry.getKey();
    String value = entry.getValue();
    System.out.println(key+"->"+value);
}
上一篇 下一篇

猜你喜欢

热点阅读