java -- 集合框架

集合

数组有一定的缺陷

  • 数组长度固定不变
  • 可通过数组名.length获取数组的长度,去无法直接获取数组中存储元素的实际长度
  • 数组申请空间是连续的

针对数组的缺陷,java提供了集合框架(位于java.util包中)

分享一篇很好的博客

image-20230906183020866

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Iterable接口

此接口位于java.lang.Iterable中,是java标准库中的接口,用于表示可迭代的集合类,实现了Iterable接口的类可以使用java中的for-each循环来遍历其中的元素,使其具有可迭代性。

Iterable中的方法

返回值类型方法描述
voidforEach(Consumer<? super T> action)对Iterable对象的每个元素执行给定的操作,知道那个处理完所有元素或者引发异常
Iterableiterator()返回迭代type T的迭代器

实现了Iterable接口的类可以通过实现iterator()方法来返回一个迭代器对象,从而使for-each循环语法来遍历结合中的元素。

下面我们以ArrayList为例子来展示几个常见的错误

 // 错误1
public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("a");
        list.add("b");
        list.add("c");
        list.add("d");
        for (int i = 0; i < list.size(); i++) {
            //修改操作
            list.remove(i);
            //添加操作
            //添加错误也会错误
        }
        System.out.println(list);

    }
// 结果是 [b, d]
// 原因是size是动态变化的
// 错误2
//
        for (String s:list)
        {
            list.add("d");
        }
//
//错误三
        Iterator iterator = list.iterator();
        while (iterator.hasNext())
        {
            list.remove(iterator.next());
        }


在上面的错误中,错误2和错误3同理都是因为不能在迭代器中使用**原对象**进行删除.。

但是在迭代器对对象中,提供了一种方法。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

迭代器对象提供了一种默认方法remove,表示删除迭代器游标当前所指的对象。

        Iterator iterator = list.iterator();
        for (int i = 0; i < list.size(); i++) {
            iterator.next();
            //list.remove(iterator.next());         --报错
            if ("a".equals(list.get(i)))
            {
                iterator.remove();
            }
        }

这样成功的删除了元素。

Collection接口

Collection接口内的方法

image-20230906183428761

这里大部分是抽象方法,为后面的类提供规范,后面的派生类要实现这些基本的方法。

Collection 下面有三个接口

Set接口

  • 实现了set接口的集合,其中的元素是唯一的。
  • Set集合是不可变数据类型,不可以对其进行修改
  • Set集合中不能使用null元素

//个别方法示例

    public static void main(String[] args) {
        //of 和copy是Set的静态方法
        Set set = Set.of("dasd","ad","da","dadasdwa",'s');
        //Set的一些方法
        //toArray  将set集合转化成Object数组,无序
        System.out.println(Arrays.toString(set.toArray()));
        // contains 判断是否有指定字符或者字符序列 返回布尔值
        System.out.println(set.contains('s'));
        System.out.println(set.contains("da"));
        // retainAll(Collection<?> c) 仅仅保留c中存在的元素  交集
/*        Set set1 = Set.of('s');
        System.out.println(set.retainAll(set1));*/
        // 报错Set集合不可变
        
    }

常用子类HashSetTreeSet

TreeSet

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

上面的结果只有a s w 三个元素,并且是无序的

image-20230906224540404

HashSet

image-20230906224517329

List接口

有序集合(也称为序列 )。 该集合用户可以精确控制列表中每个元素的插入位置。 用户 可以通过整数索引(列表中的位置)访问元素,并搜索列表中的元素。

  • List 通常允许重复的元素、允许 null 元素
  • List是不可变的

LIst方法1

List方法2

public static void main(String[] args) {
        List<String> list = List.of("a","c","d","f","s","a");
        // List方法
        // listIterator 返回原顺序的迭代器对象,可传参,返回指定位置开始的迭代器对象
        Iterator iterator = list.listIterator(2);
        while (iterator.hasNext())
        {
            System.out.println(iterator.next());
        }
        //replaceAll在List中不能用
/*        list.replaceAll(t->t+"s");
        System.out.println(list);*/
        
        // List不可变
/*        list.add("s");
        System.out.println(list);*/



    }
Vector
 public static void main(String[] args) {
        List<String> list = List.of("a","c","d","f","s","a");
        Vector vector = new Vector();
        vector.addAll(list);
        System.out.println(vector.get(0));
     	// 转换器
        vector.replaceAll(o-> "字母是:" + o);
        System.out.println(vector);
     
        List a = vector.subList(0,3);
        a.add("a");
        System.out.println(a);
        System.out.println(vector);
     // 结果是
    // a
//[字母是:a, 字母是:c, 字母是:d, 字母是:f, 字母是:s, 字母是:a]
//[字母是:a, 字母是:c, 字母是:d, a]
//[字母是:a, 字母是:c, 字母是:d, a, 字母是:f, 字母是:s, 字母是:a]
        
    }

!!!注意subList等方法生成的子视图,会对原来的集合产生影响

Stack

和之前写的栈数据类型相似的操作

Queue接口

实现了单链表

下面有Deque(实现了双链表)接口

LinkedList
抛出异常返回特殊值
插入addoffer
删除removepoll
检查elementpeek

AbstractCollection抽象类

具有Collection的性质

Map

  • Map 接口不是 Collection 的子接口,使用键、值映射表来存储
  • Map 不能有重复的键(覆盖),每个键可以映射到最多一个值
  • 允许将映射内容视为一组键、值集合或键值映射集合
  • key 不要求有序,不可以重复。 value 也不要求有序,但可以重复
  • 当使用对象作为 key 时,要重写 equals 和 hashCode 方法
//创建不可修改的Map对象
1. Map.of
2. Map.ofEntries
3. Map.copyOf
    这三种方式创建的是不可修改的

Map的基本方法

image-20230906231911161

TreeMap

  • 继承 AbstractMap ,一个红黑树基于 NavigableMap 实现
  • 非线程安全的
  • key 不能存 `null ,但是 value 可以存 null
  • key 必须是可比较的 (实现 Comparable 接口,传递一个 Comparator 比较器)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

        Map map1 = Map.of(1,"a",2,"b",5,"s");
        map1.remove(1);

// 报错,这样定义的Map对象是不能改变的
        Map map = new TreeMap();
        map.put("鸡","蔡徐坤");
        map.put("鸡1","蔡虚坤");
        map.put("鸡5","蔡虚鲲");
        map.put("鸡3","蔡坤坤");
        map.put("鸡4","蔡坤坤");

        System.out.println(map);

// 结果是   {鸡=蔡徐坤, 鸡1=蔡虚坤, 鸡3=蔡坤坤, 鸡4=蔡坤坤, 鸡5=蔡虚鲲}

// TreeMap 定义的是有序的是根据键的自然排序放入的
// 实现了compable接口

遍历Map

        // 遍历map集合
        // 1.通过entrySet()方法
        for (Map.Entry entry: map.entrySet())
        {
            System.out.println(entry.getKey() + " = " + entry.getValue());
        }
        // 2.通过 KeySet()方法
        for (String key: map.keySet())
        {
            System.out.println(key + " = " + map.get(key));
        }

HashTable

  • 该类实现了一个哈希表,它将键映射到值 不允许 null 作为键和值
  • 默认初始容量( initialCapacity )为 11 ,默认负载因子( loadFactor )为 0.75f
  • 同步的(线程安全的)
  • 不保证顺序
  • 扩容方式是旧容量的2倍 +1
  • 为什么hashtable的扩容方式选择为2n+1 为了均匀分布,降低冲突率
  • 数组 + 链表方式存储实现Hash表存储
  • 添加值时 如果 hash 一样 equals 为 false 则将当前值添加到链表头 如果 hash 一样 equals 为 true 则使用当前值替换原来的值 ( key 相同)
    public static void main(String[] args) {
        Hashtable table = new Hashtable();
        table.put("a","蔡徐坤");
        table.put("c","蔡虚坤");
        table.put("w","蔡虚鲲");
        table.put("t","蔡坤坤");
        table.put("y","蔡坤坤");
        
        // 具有和迭代器相同的作用,但是不具备迭代器的删除功能
        Enumeration enumeration = table.keys();
        System.out.println(table);
    }

HashMap

  • 基于哈希表的实现Map接口
  • 允许null值的键和值
  • 非线程安全
  • 默认容量是16,负载因子0.75
  • 扩容是2倍旧的容量
  • 在存储数据时,key的hash计算调用的是HashMap中的hash方法
  • 添加值时,如果hash一样,添加到链表的尾部

image-20230906235603689

蔡坤坤");

    // 具有和迭代器相同的作用,但是不具备迭代器的删除功能
    Enumeration enumeration = table.keys();
    System.out.println(table);
}



## HashMap

- 基于哈希表的实现Map接口
- 允许`null`值的键和值
- 非线程安全
- 默认容量是16,负载因子0.75
- 扩容是2倍旧的容量
- 在存储数据时,key的hash计算调用的是HashMap中的hash方法
- 添加值时,如果hash一样,添加到链表的尾部

[外链图片转存中...(img-hO4ir6Oo-1694017456510)]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值