gcf-1917

 

单列集合List

 

一、集合框架体系

集合: 用来存储多个数据一种容器.与数组不同的是...

 集合数组
长度 可变 固定
存储的数据类型是否固定 数据类型不固定 数据类型固定
存储的类型 只能是存储引用类型 基本类型数组,引用类数组
功能 有属性和方法 没有方法,没有属性(length除外)

 

集合体系

image-20230222094006626

今天主要学习Collection,List,ArrayList,LinkedList...

二、Collection

Collection是单列集合层次结构中的根接口 一些 集合允许有重复的元素,而另一些则不允许。一些 集合是有序的,而另一些则是无序的 Collection下面的一些子实现类有些有重复元素,有些没有,有些可以有序,有些无序

 

方法: 每个都很常见,很重要

   private static void testMethod1() {
       // Collection是接口,演示时需要创建子类对象ArrayList
       Collection collection = new ArrayList();
       System.out.println(collection );

       // boolean add(Object obj); 添加1个元素
       collection.add("集合");
       collection.add(new Date());
       collection.add(111); // 111 自动装箱成Integer,Integer赋值给Object
       // ps: 可以存储各种类型的数据,且长度不固定


       System.out.println(collection );

       // boolean addAll(Collection c); 将参数集合中的所有元素,全部添加到当前集合
       Collection c1 = new ArrayList();
       c1.add("a");
       c1.add("b");
       c1.add("c");

       Collection c2 = new ArrayList();
       c2.add(1);
       c2.add(2);
       c2.add(3);

       // c2.add(c1); // 这是将集合当做1个元素放进去
       // System.out.println(c2 );

       // int size(); 返回集合中元素的个数
       // int size = c2.size( );
       // System.out.println(size );


       c2.addAll(c1); // 将集合中的元素取出,1个1个放进去
       System.out.println(c2 );
       System.out.println(c2.size() );


       Collection c3 = new ArrayList();
       c3.add("a");
       c3.add("b");
       c3.add("c");
       System.out.println(c3 );

       // boolean remove(Object obj);
       System.out.println(c3.remove(1));
       System.out.println(c3.remove("a"));
       System.out.println(c3 );


       // boolean removeAll(Collection c);
       Collection c4 = new ArrayList();
       c4.add("a");
       c4.add("b");
       c4.add("c");
       System.out.println(c4 );

       Collection c5 = new ArrayList();
       c5.add("e");
       c5.add("d");

       // 删除的两个集合中有交集的部分元素
       System.out.println(c4.removeAll(c5));
       System.out.println(c4 );
  }
   public static void main(String[] args) {
      Collection c1 = new ArrayList();
      c1.add("a");
      c1.add("b");
      c1.add("c");
      c1.add("d");

      Collection c2 = new ArrayList();
      c2.add("b");
      c2.add("e");

      // retainAll(Collection c); 保留指定元素,删除其他元素
      // 两个集合交集部分全部保留,其他删除
      c1.retainAll(c2);
      System.out.println(c1 );


      Collection c3 = new ArrayList();
      c3.add("a");
      c3.add("b");
      c3.add("c");

      System.out.println(c3.contains("c"));

      System.out.println(c3.size( ));
      // 判断是否为空
      System.out.println(c3.isEmpty( ));

      // clear() 清空集合
      c3.clear();
      System.out.println(c3.size( ));
      // 判断是否为空
      System.out.println(c3.isEmpty( ));
  }

三、泛型

泛型就是一种比较宽泛的类型定义,是一种抽象的类型. 今天使用泛型的主要目的: 为了消除强制类型转换

 

泛型使用: 在类或方法参数定义时使用泛型字母来取代之前固定数据类型

add(Object obj) --> add(E e) Collection --> Collection<E>


常见的泛型字母 E (element) T (target) K(key) V(value) ? (未知)

 

    public static void main(String[] args) {
       // Collection<String> c1 = new ArrayList<String>();
       // 设置泛型
       // 一旦设置泛型,就约束了集合只能存储该类型数据
       Collection<String> c1 = new ArrayList<>();
       // 这么做的目的是:为了消除强制类型转换!!

       c1.add("a");
       // 不能加入其他类型的元素
       // c1.add(1);
       // c1.add(new Object());
       c1.add("b");
  }

四、迭代[重要]

迭代 (遍历), 将集合元素迭代,目的是取出元素.

Collection根接口,提供了一个迭代器规范,iterator(),调用该方法会返回一个集合元素上的迭代器,通过这个迭代器就可以获得集合元素

    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");

       // 获得迭代器(这个迭代器里面就会拥有所有的元素)
       Iterator<String> iterator = c.iterator();
       // 判断有没有下一个
       while(iterator.hasNext()) {
           String e = iterator.next(); // 取出下一个元素
           System.out.println(e );
      }

       // 现在不使用泛型,再来一遍,感受泛型的好处
  }

image-20230222112842117

迭代器使用注意事项:

1、迭代器迭代完成之后,迭代器的位置在最后⼀位。 所以迭代器只能迭代⼀次

2、迭代器在迭代的时候,不要调⽤多次next⽅法,可能会出错NoSuchElementException

3、在迭代器迭代的时候,不能向集合中添加或者删除元素 ,否则报错ConcurrentModificationException (除非使用迭代器自己的方法进行删除/添加)



 

增强for循环(foreach)

增强for循环可以代替iterator,两者的本质都是一样的,都是用于遍历集合和数组

特点:增强就是迭代器iterator的简化版

// 语法
for(数据类型 变量名: 要遍历的集合/数组){
   // ...
}
//左侧的数据类型 变量名要根据集合/数组来定,变量是每次循环都代表1个集合元素或者数组元素.不是下标!!!
    public static void main(String[] args) {
       Collection<String> c = new ArrayList<>();
       c.add("a1");
       c.add("b1");
       c.add("c1");
       c.add("d1");
       c.add("e1");

       // 迭代
       for(String s : c) {
           System.out.println(s );
      }

       // 使用foreach遍历数组
       int[] arr = {1,2,3,4,5};
       for(int i: arr){
           System.out.println(i );
      }
  }

五、List

List是Collection的子接口 List是有序集合: 有序是指集合迭代顺序和插入顺序一致 List集合允许重复元素!! List集合提供了可以针对索引(下标)操作元素的方法

 

List接口中的方法大部分与父接口Collection中一致, 但是除此之外的方法,确实提了可以通过下标操作元素(CRUD)的方法

  • void add(int index,E e)

  • E remove(int index)

  • E get(int index)

  • E set(int index,E e)

 

List是接口,没有办法演示其中的方法

List接口有两个常用的实现类:ArrayList和LinkedList

六、ArrayList[重点]

ArrayList实现了List接口,即ArrayList也是有序集合,也允许重复元素,且那些关于下标操作集合的方法ArrayList都有!

ArrayList底层是数组,大小可变是指它会扩容(不是真正大小可变)

 

6.1 演示方法

构造方法

  • ArrayList() 创建空集合,默认创建了一个长度为10的数组

  • ArrayList(Collection c) 创建一个集合,集合内直接就有指定的参数

  • ArrayList(int initialCapacity) 创建一个指定初始化容量的数组

 ArrayList<Integer> list = new ArrayList<>( );

 

方法

  • 其他的方法上午在Collection中已经学过

  • void add(int index,E e) 返回一个E元素

  • E remove(int index)

  • E get(int index)

  • E set(int index,E e)

   public static void main(String[] args) {
       ArrayList<Integer> list = new ArrayList<>( );
       // System.out.println(list.size() );
       // System.out.println(list.isEmpty() );

       // 有序: 遍历和插入顺序一致
       list.add(4);
       list.add(2);
       // 且允许重复
       list.add(4);
       list.add(1);
       list.add(3);
       // 42413
       // E remove(int index); // 根据下标删除,并返回被删除的元素(阅后即焚)
       //Integer e1 = list.remove(2);
       //System.out.println("要删除的元素: " + e1 );
       //System.out.println(list );

       // 通过下标取出元素
       Integer e2 = list.get(2);
       System.out.println("获得下标2的元素"+e2 );
       System.out.println(list );

       // 根据下标插入元素
       list.add(3,5);

       // 根据下标修改元素,返回旧元素
       list.set(3,50);
       System.out.println(list );
       // 遍历
       // for(Integer i: list){
       //     System.out.println(i );
       // }
  }

6.2 底层原理

ArrayList底层是使用数组,默认长度是10,但是存储元素多于10时会扩容.

如何扩容的?

  • 当加入元素时,先判断加入后会不会超出默认长度

  • 如果没有超出默认长度

    • add(Object o) 元素直接放最后

    • add(int index,Object o) 先将该位置以后的元素依次往后移动一个,然后再将该元素放入该位置

  • 当加入元素时,判断加入后长度会不会超出容量,如果超出就要扩容

  • 扩容是创建一个新的数组,容量是原来的1.5倍

  • 将原来数组的元素依次拷贝到新数组

  • 然后再放入新元素

image-20230222160227208

6.3 特点[记住]

ArrayList特点: 1) 有序 2) 重复 3) 查询更新效率高 4) 删除插入效率低

应用场景: 适合那些查询频率高的地方. 且基本大部分场景都是经常查不经常删除和插入的,所以呢ArrayList就非常常用!!! 如果以后没有特殊说明,直接就使用ArrayList!!

 

七、LinkedList

LinkedList是List的实现类,那么LinkedList也是允许重复,有序 且LinkedList集合也有关于下标操作集合的方法,但是还提供了一些关于操作开头和结尾的方法

底层是使用链表实现.

7.1 演示方法

    public static void main(String[] args) {
LinkedList<Integer> ll = new LinkedList<>( );
ll.add(4);
ll.add(2);
ll.add(4);
ll.add(3);
ll.add(1);

// 关于下标操作
ll.add(3,5);
System.out.println(ll );

ll.set(3,50);
System.out.println(ll );

Integer i = ll.get(3);
System.out.println(i );

ll.remove( 3 );
System.out.println(ll );

System.out.println("-------------" );
// 特殊的,有关于操作头和尾的方法
// 获得第一个
System.out.println(ll.getFirst( ));

// 获得最后一个
System.out.println(ll.getLast() );

// 向头插入
ll.addFirst(0);
System.out.println(ll );

// 向尾插入
ll.addLast(6);
System.out.println(ll );

// 删除第一个,删除最后一个
}

7.2 原理

底层是链表实现

image-20230222171301547

7.3 特点

  1. 有序

  2. 允许重复

  3. 查找,更新时效率比较低

  4. 插入,删除时效率比较高

八、扩展

面试

      // 会出现并发编程问题的
// Iterator<Integer> iterator = list.iterator( );
// while(iterator.hasNext()) {
// Integer next = iterator.next( );
//
// // 使用集合自己方法进行删除/添加会出现并发修改异常
// list.remove(1);
//
// }


System.out.println(list );
// 不会出现并发编程异常
ListIterator<Integer> listIterator = list.listIterator( );
while (listIterator.hasNext()) {
Integer next = listIterator.next( );

// 使用迭代器的方法进行对集合内容修改/添加
//listIterator.remove();
listIterator.add(100);

}
System.out.println(list );

九、总结

Collection 里面的方法都很常见,其中的方法必须记住
泛型会用就行
迭代 Iterator或者foreach都要会
ArrayList全部都是重点(集合创建,方法的使用,原理,特点)
LinkedList主要记住特点,防止面试问
 

posted on 2025-03-03 21:45  Fei_关我什么柿  阅读(7)  评论(0)    收藏  举报

导航