一些关于java集合的知识点

集合与数组的区别

  1. 长度区别
    • 数组固定
    • 集合可变
  2. 内容区别
    • 数组可以是基本类型,也可以是引用类型
    • 集合只能是引用类型
  3. 元素区别
    • 数组只能存储同一种类型
    • 集合可以存储不同类型(一般存储一种类型——泛型)

Collection集合的方法

  1. Boolean add(E e):在集合末尾添加元素
  2. Boolean remove(Object o):若本类集中有值与相等的元素,则删除该元素,并返回true
  3. void clear():清除本类集中所有的元素,调用完该方法后本类集将为空
  4. Boolean contains (Object o ):判断集合中是否包含某元素
  5. Boolean isEmpty():判断集合是否为空
  6. int size():返回集合中的元素个数
  7. Boolean addAll(Collection c):将一个类集c中的所有元素添加到另一个类集
  8. Object[ ] toArray():返回一个包含了本类集合中所有元素的数组,数组类型为,Object[ ]
  9. Iterator iterator():迭代器,集合的专用遍历方式

常用集合的分类

  1. Collection接口的接口,对象的集合(单列集合)
  2. List接口:元素按进入先后有序保存,可重复
    • LinkedList接口实现类,链表,插入删除,没有同步,线程不安全
    • ArrayList接口实现类,数组,随机访问,没有同步,线程不安全
    • Vertor接口实现类数组,同步,线程安全
  3. set接口:仅接受一次,不可重复,并做内部排序
    • HashSet使用hash表(数组)存储元素
    • LinkedHashSet链表维护元素的插入次序
    • TreeSet底层实现为二叉树,元素好排序

List和Set集合详解

list和set的区别

  1. 有序性
    • List保证按插入顺序排序
    • Set存储和取出顺序不一致
  2. 唯一性
    • List可以重复
    • Set元素唯一
  3. 获取元素
    • List可以通过
    • Set不能根据索引获取元素

list

特有功能:

  • void add(int index,Object obj):在指定位置添加元素
  • Object remove(int index):根据指定索引删除元素,并把删除的元素返回
  • Object Set(int index,Object obj):把指定索引位置的元素修改指定的值,返回修改前的值
  • int indexOf(Object o):返回指定元素在集合中第一次出现的索引
  • Object get(int index):获取指定位置的元素
  • ListIterator listItertor():列表迭代器
  • List subList(int fromIndex,int toIndex):截取集合。
  1. ArrayList:底层数据结构是数组,查询快,增删慢,线程不安全,效率高,可以存储重复元素

  2. LinkedList 底层数据结构是链表,查询慢,增删快,线程不安全,效率高,可以存储重复元素

    • 添加:addFirst() addLast()
    • 删除:removeFirst()removeLast()poll()pollFirst() pop()//弹出最后一个
    • 获取:getFirst() getLast
  3. Vector:底层数据结构是数组,查询快,增删慢,线程安全,效率低,可以存储重复元素

    • public void addElement(E obj)相当于add()
    • public E elementAt(int index)相当于get()
    • public Enumeration elements( ) 相当于iterator()
  4. 如何避免并发修改异常?// ConcurrentModificationException

    • 在使用迭代器或者增强for遍历集合的过程中,不要使用集合的方法去添加或者删除元素即可。

泛型

  1. 泛型接口的两种使用方式:

    • 实现类给出具体的类型
    • 实现类延续泛型,创建实现类对象时再确定类型
  2. 泛型不具备继承性,但数据具备继承性

    import java.util.ArrayList;
    
    public class GenericsDemo02 {
        public static void main(String[] args) {
            ArrayList<Ye> list1 = new ArrayList<>();
            ArrayList<Fu> list2 = new ArrayList<>();
            ArrayList<Zi> list3 = new ArrayList<>();
    
            // 调用method方法
    //        method(list1);
    //        method(list2);//报错
    //        method(list3);//报错
    
            list1.add(new Ye());
            list1.add(new Fu());
            list1.add(new Zi());
        }
    
        public static void method(ArrayList<Ye> list) {
    
        }
    }
    
    class Ye {
    }
    
    class Fu extends Ye {
    }
    
    class Zi extends Fu {
    }
    

    此时可以使用泛型的通配符:

    • ?也可以表示不确定类型可以进行类型的限定
    • ?extends E:表示可以传递E或者E所有的子类类型
    • ?super E:表示可以传递E或者E所有的父类类型
    public static void method(ArrayList<? extend Ye> list)
        //关于Ye的子类都可以使用泛型方法
    

    应用场景:

    1. 如果在定义类、方法、接口的时候,如果类型不确定,就可以定义泛型类、泛型方法、泛型接口。
    2. 如果类型不确定,但是能知道以后只能传递某个继承体系中的,就可以使用泛型的通配符

    泛型的通配符:

    • 关键点:可以限定泛型的范围

泛型总结

  1. 什么是泛型
    • JDK5引入的特性,可以再编译阶段约束操作的数据类型,并进行检查
  2. 泛型的好处
    • 统一数据类型
    • 把运行时期的问题提前到了编译期间,避免了强制类型转换可能出现的异常,因为再编译阶段类型就能确定下来。
  3. 泛型的细节?
    • 泛型中不能写基本数据类型
    • 指定泛型的具体类型后,传递数据时,可以传入该类型和他的子类类型
    • 如果不写泛型,类型默认时Object
  4. 哪里定义泛型?
    • 泛型类:再类名后面定义泛型,创建该类对象的时候,确定类型
    • 泛型方法:再修饰符后面定义方法,调用该方法的时候,确定类型
    • 泛型接口:在接口名后面定义泛型,实现类确定类型,实现类延续泛型

set

  1. Set系列集合的特点

    • 无序、不重复、五索引
    • Set集合的方法上基本与Collection的API一致
  2. Set集合的实现类特点

    • HashSet:无序、不重复、无索引
    • LinkedHashSet:有序、不重复、无索引
    • TreeSet:可排序、不重复、无索引
  3. (1)HashSet底层数据结构采用哈希表实现,元素无序且唯一,线程不安全,效率高,可以存储null元素,元素的唯一性是靠所存储元素类型是否重写hashCode()和equals()方法来保证的,如果没有重写这两个方法,则无法保证元素的唯一性。

/*
具体实现唯一性的比较过程:存储元素首先会使用hash()算法函数生成一个int类型hashCode散列值,然后已经的所存储的元素的hashCode值比较,如果hashCode不相等,则所存储的两个对象一定不相等,此时存储当前的新的hashCode值处的元素对象;如果hashCode相等,存储元素的对象还是不一定相等,此时会调用equals()方法判断两个对象的内容是否相等,如果内容相等,那么就是同一个对象,无需存储;如果比较的内容不相等,那么就是不同的对象,就该存储了,此时就要采用哈希的解决地址冲突算法,在当前hashCode值处类似一个新的链表, 在同一个hashCode值的后面存储存储不同的对象,这样就保证了元素的唯一性。
*/
  • 覆盖hashCode()方法的原则:

    1、一定要让那些我们认为相同的对象返回相同的hashCode值
    2、尽量让那些我们认为不同的对象返回不同的hashCode值,否则,就会增加冲突的概率。
    3、尽量的让hashCode值散列开(两值用异或运算可使结果的范围更广)

  1. LinkedHashSet底层数据结构采用链表和哈希表共同实现,链表保证了元素的顺序与存储顺序一致,哈希表保证了元素的唯一性。线程不安全,效率高。

小结

/*
Set具有与Collection完全一样的接口,因此没有任何额外的功能,不像前面有两个不同的List。实际上Set就是Collection,只 是行为不同。(这是继承与多态思想的典型应用:表现不同的行为。)Set不保存重复的元素。
*/

List和Set总结

  1. List,Set都是继承自Collection接口,Map则不是

  2. List特点:元素有放入顺序,元素可重复 ,Set特点:元素无放入顺序,元素不可重复,重复元素会覆盖掉

  3. Set和List的对比:

    • Set:检索元素效率低下,删除和插入效率高,插入和删除不会引起元素位置改变。
    • List:和数组类似,List可以动态增长,查找元素效率高,插入删除元素效率低,因为会引起其他元素位置改变。
  4. ArrayList与LinkedList的区别和适用场景

    • Arraylist:

      优点:ArrayList是实现了基于动态数组的数据结构,因为地址连续,一旦数据存储好了,查询操作效率会比较高(在内存里是连着放的)。
      缺点:因为地址连续, ArrayList要移动数据,所以插入和删除操作效率比较低。

    • LinkedList

      优点:LinkedList基于链表的数据结构,地址是任意的,所以在开辟内存空间的时候不需要等一个连续的地址,对于新增和删除操作add和remove,LinedList比较占优势。LinkedList 适用于要头尾操作或插入指定位置的场景
      缺点:因为LinkedList要移动指针,所以查询操作性能比较低。

map

  1. map遍历的三种方式

    • 先获取所有的键,把这些键放到一个单列的集合当中,在用循环取出值:map.keySet()方法

    • 直接用map.entrySet()取出键值对,然后遍历取出键和值,entry.getKey(),entry.getValue();

    • lambda表达式

      map.forEach(new BiConsumer<String, String>() {
          @Override
          public void accept(String key, String value) {
              System.out.println(key+"="+value);
          }
      });
      
  2. HashMap的特点

    • HashMap是Map里面的一个实现类
    • 没有额外需要学习的特有方法,直接是使用Map里面的方法就可以了
    • 特点都是由键决定的:无序、不重复、无索引
    • HashMap跟HashSet底层原理是一摸一样的,都是哈希表结构
    • 依赖hashCode方法和equlas方法保证键的唯一
    • 如果键存储的是自定义对象,需要重写hashCode和equals方法如果值存储自定义对象,不需要重写hashCode和equals方法
  3. LinkedHashMap的存和取的顺序是一致的。

  4. TreeMap集合的特点是怎么样的?

    • 不重复、无索引、可排序
    • 底层基于红黑树实现排序,增删改查性能较好
  5. TreeMap集合排序的两种方式

    • 实现Comparable接口,指定比较规则
    • 创建集合时传递Comparator比较器对象,指定比较规则
    1. treemap添加元素的时候,键是不需要重写hashcode和equals方法的

    2. 在hashmap的底层,默认是利用哈希值的大小关系来创建红黑树的,不需要实现compareable接口或者传递比较器对象

    3. 一般不形成长链表的情况下,hashmap的效率比treemap要高

    4. 在map集合中,putIfAbsent方法是如果键重复了,也不会覆盖的方法。 代码中的逻辑都有两面性,如果我们只知道了其中的A面。而且代码中还发现了有变量可以控制的两面性的发生。那么该逻辑一定会有B面。

    5. 如何选择三种双列集合?

      默认:HashMap(效率最高)

      如果要保证存取有序:LinkedHashMap

      如果要进行排序:Treemap

可变参数

  1. 可变参数本质上就是一个数组

  2. 作用:在形参中接受多个数据

  3. 格式:数据类型... 参数名称

    举例:int... a

  4. 注意事项:

    • 形参列表中可变参数只能有一个
    • 可变参数必须放在形参列表的最后面

Collections

  1. addAll 批量添加元素

  2. shuffle 打乱元素

    ArrayList<String> list = new ArrayList<>();
    Collections.addAll(list,"abc","bcd","qwer","df","asdf","1234");
    Collections.shuffle(list);
    
    
posted @   yu_lu  阅读(7)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程
· .NET 10 首个预览版发布,跨平台开发与性能全面提升
· 《HelloGitHub》第 107 期
· 全程使用 AI 从 0 到 1 写了个小工具
· 从文本到图像:SSE 如何助力 AI 内容实时呈现?(Typescript篇)
点击右上角即可分享
微信分享提示