JAVA集合框架笔记

1.集合分类

Java集合框架提供了一套性能优良,使用方便的接口和类,他们位于java.util包中。
在这里插入图片描述
集合分两类,Collection集合和Listi集合
区别:Collection 接口存储一组不唯一,无序的对象
Map 接口存储一组键值对象,提供key到value的映射
List 接口存储一组不唯一,有序的对象。
Set 接口存储一组唯一,无序的对象

我们学习集合,通常学习子类的集合用法,因为子类都继承了父类的所有方法并且自己有更丰富的方法和特性。

2.Collection集合

2.1 List集合

2.1.1 ArrayList集合

快速入门

    public static void main(String[] args) {
        List list = new ArrayList();
        list.add("第一个");
        list.add("第二个");
        list.add("第三个");

        System.out.println(list);
    }
2.1.1.1、ArrayList概述

通过源码我们发现 ArrayList继承了抽象类,抽象类实现了Collection接口。

可调整大小的数组的实现List接口。 实现所有可选列表操作,并允许所有元素,包括null 。 除了实现List 接口之外,该类还提供了一些方法来操纵内部使用的存储列表的数组的大小。 (这个类是大致相当于Vector,不同之处在于它是不同步的)。

基于数组实现的list
说明:底层的数据结构就是数组,数组元素类型为Object类型,即可以存放所有类型数据。我们对ArrayList类的实例的所有的操作底层都是基于数组的。
ArrayList和Vector的区别是:ArrayList是线程不安全的,当多条线程访问同一个ArrayList集合时,程序需要手动保证该集合的同步性,而Vector则是线程安全的。

补充,为什么有接口了还要有抽象类呢

我们知道接口实现,需要实现全部的方法,而抽象类可以实现部分的方法,其他方法声明是抽象方法即可,类还是抽象类
这样抽象类就相当于中间的过度,比如ArrayList继承了AbstractList抽象类,实现它的所有抽象方法,而AbstractList实现了list接口,这样代码更有层次性。AbstractList实现了部分通用的接口方法,其他类继承AbstractList即可。

2.1.1.2、ArrayList的add方法
       List list = new ArrayList();
        list.add("第一个");
        list.add("第二个");
        list.add("第三个");

        list.add(new Person());

        System.out.println(list);

add方法是给列表添加元素,可以是任意类型。
扩容机制(ArrayList的初始容量为10,之后每次扩容均为已有容量的1.5倍

我们知道Arraylist底层是数组实现的,数组一旦确定就确定了长度,list集合怎么完成动态扩容的呢。
其实内部有个扩容机制,当集合长度小于原来定义的数组长度的时候就会进行数组扩容,新建一个数组是原来1.5倍的新数组,把原来的数组复制进去
正常情况下会扩容1.5倍,特殊情况下(新扩展数组大小已经达到了最大值)则只取最大值。

总结 扩容后的数组长度 = 当前数组长度 + 当前数组长度 / 2。

2.1.1.3、ArrayList的remoce方法

指定集合索引进行删除。

list.remove(0);

可以根据数据里面的内容进行删除。

 list.remove("第二个");

清空所有。

 list.clear();
2.1.1.4、ArrayList的其他方法,get,set等

set,入门没有就新增,有了就替换

   list.set(1,"替换第二个");

根据索引获取指定的元素

  System.out.println( list.get(1));

获取集合长度

 System.out.println( list.size());

遍历

 for (Object o : list) {
            System.out.println(o);
        }

总结
arrayList可以存放null。 list.add(null);
arrayList本质上就是一个elementData数组。
arrayList区别于数组的地方在于能够自动扩展大小,其中关键的方法就是gorw()方法。
arrayList由于本质是数组,所以它在数据的查询方面会很快,而在插入删除这些方面,性能下降很多,有移动很多数据才能达到应有的效果

2.1.2 LinkedList集合

        List list = new LinkedList();
        list.add("第一个");
        list.add("第二个");
        list.add(null);

        list.add(new Person());

        for (Object o : list) {
            System.out.println(o);
        }

基本上方法和使用上和Arraylist相同。get,set,add遍历等。

2.1.1.1、LinkedList概述

LinkedList是一种可以在任何位置进行高效地插入和移除操作的有序序列,它是基于双向链表实现的。
LinkedList 是一个继承于AbstractSequentialList的双向链表。它也可以被当作堆栈、队列或双端队列进行操作。
LinkedList 实现 List 接口,能对它进行队列操作。
LinkedList 实现 Deque 接口,即能将LinkedList当作双端队列使用。
LinkedList 实现了Cloneable接口,即覆盖了函数clone(),能克隆。
LinkedList 实现java.io.Serializable接口,这意味着LinkedList支持序列化,能通过序列化去传输。
LinkedList 是非同步的。

LinkedList是通过链表实现的如果在频繁的插入,或者删除数据时,就用linkedList性能会更好。
linkedList是一个非线程安全的(异步)

2.1.1.1、LinkedList总结
  1. linkedList本质上是一个双向链表,通过一个Node内部类实现的这种链表结构。
  2. 能存储null值
  3. 跟arrayList相比较,就真正的知道了,LinkedList在删除和增加等操作上性能好,而ArrayList在查询的性能上好
  4. 从源码中看,它不存在容量不足的情况
  5. linkedList不光能够向前迭代,还能像后迭代,并且在迭代的过程中,可以修改值、添加值、还能移除值。
  6. linkedList不光能当链表,还能当队列使用,这个就是因为实现了Deque接口。

2.1.3 LinkedList和ArrayList比较

arrayList底层是用数组实现的顺序表,是随机存取类型,可自动扩增,并且在初始化时,数组的长度是0,只有在增加元素时,长度才会增加。默认是10,不能无限扩增,有上限,在查询操作的时候性能更好
LinkedList底层是用链表来实现的,是一个双向链表,注意这里不是双向循环链表,顺序存取类型。
在源码中,似乎没有元素个数的限制。应该能无限增加下去,直到内存满了在进行删除,增加操作时性能更好。
两个都是线程不安全的,在iterator时,会发生fail-fast:快速失效。

2.Map集合

2.1.1 HashMap集合

2.1.1 .1 HashMap概述

HashMap是基于哈希表的Map接口实现的,它存储的是内容是键值对<key,value>映射。
在1.8之前HashMap的数据结构就是用的链表散列。
1.8之后就是 数组+链表+红黑树

HashMap的属性
初始容量:哈希表中桶的数量
加载因子:哈希表在其容量自动增加之前可以达到多满,的一种尺度
当哈希表中条目数超出了当前容量加载因子(其实就是HashMap的实际容量)时,则对该哈希表进行*
rehash操作,将哈希表扩充至两倍的桶数
Java中默认初始容量为16,加载因子为0.75。
一般第一次扩容时会扩容到64,之后好像是2倍。总之,容量都是2的幂

2.1.1 .2 HashMap的常用方法

put方法

        Map map = new HashMap();
        map.put(1,"liut");
        map.put("liut","帅");

        System.out.println(map);

get方法

        System.out.println(map.get("liut"));
2.1.1 .3 HashMap的迭代器
        Map map = new HashMap();
        map.put(1,"liut");
        map.put("liut","帅");
        for (Object o : map.keySet()) {
            System.out.println(o);
            System.out.println(map.get(o));
        }

我们用增强for循环的方式,可以遍历出所有的key,再通过key来获取对应的value。

Iterator对象也可以实现,迭代器,但是我喜欢用增强for循环。

        Map map = new HashMap();
        map.put(1,"liut");
        map.put("liut","帅");

        Set keys = map.keySet();
        Iterator it=keys.iterator();
        while(it.hasNext()){
            System.out.println(map.get(it.next()));
        }

3.泛型

泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。

        Map map = new HashMap();
        map.put(1,"liut");
        map.put("liut","帅");

这样不指定类型我们可以用泛型指定格式,以上虽然编译运行不报错,但是可能在后续的格式转换的时候发生错误。

        Map<String,String> map = new HashMap<>();
        map.put("1","liut");
        map.put("liut","帅");

这样我们就指定格式。

4. Collections工具类

4.1 reverse 反转列表

反转列表中元素的顺序

        List<String> list = new ArrayList<>();
        list.add("张三");
        list.add("李四");
        list.add("王五");
        list.add("赵六");

        System.out.println(list);
        Collections.reverse(list);
        System.out.println(list);

4.2 shuffle 随机排序

对List集合元素进行随机排序。

     Collections.shuffle(list);

4.3 sort 排序

根据元素的自然顺序 对指定列表按升序进行排序

 Collections.sort(list);

4.4 swap 交换元素

在指定List的指定位置i,j处交换元素

 Collections.swap (list,1,2);

4.5 rotate 移到

当distance为正数时,将List集合的后distance个元素“整体”移到前面;当distance为 负数时,将list集合的前distance个元素“整体”移到后边。该方法不会改变集合的长度。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值