Java:List(一)——概述

说明

在集合类中,List是最基础的一种集合——有序List

List的行为和数组几乎相同:List内部按照放入元素先后顺序存放,每个元素都可以通过索引确定自己的位置,List索引和数组相同,都是从0开始。

我们使用List而不是数组的原因是,使用数组增删元素时,会非常不方便。

在实际应用中,需要增删元素有序List,我们使用最多的是ArrayList

0、增删元素的原理

内部数组如果已满,就生成一个更大的数组,把原数组元素复制到新数组,接着用新数组代替原数组。

ArrayList添加删除元素的操作封装起来,让我们操作List类似操作数组,却不用关心内部元素如何移动

1、主要方法

List<E>接口的几个主要方法:

方法返回值

方法

说明

int size() 获取List大小(实际元素个数)
boolean add(E e) 在末尾加一个元素
boolean add(int index , E e) 在指定索引添加一个元素
E remove(int index) 删除指定索引处的元素
boolean remove(Object e) 删除第一次出现的元素o
E get(int index) 获取指定索引的元素

2、ArrayList与LinkedList

以上方法就是实现List接口的实际类之一ArrayList的主要方法,这种类型内部实际是数组

还有一种实现List接口的实际类LinkedList,这种类型内部实现是链表

两者比较:

 通常情况下,总是优先使用ArrayList

3、List的特点

  1. List内部元素可以重复;
  2. List可以添加null。

4、创建List

4.1、List.of( ... ):自己指定List中的元素,参数可以是若干元素或者若干元素构成的Array T[]

除了使用ArrayListLinkedList,我们还可以通过Listof()方法,根据给定元素快速创建List:

List <Integer> list = List.of(1,2,5);

但是List.of( )不接受null值,如果传入null,会抛出NullPointerException异常。

4.2、List.copyOf( Collection<? extends E> coll ):返回指定Collection中的元素构成的List

5、遍历List

5.1、for循环+get方法;

List <String> list = List.of("apple","pear","banana");

for(int i=0; i<list.size(); i++){
    String s = list.get(i);
    ...
}

5.2、迭代器Iterator

Iterator本身也是一个对象,它由List实例通过Iterator()创建。

使用Iterator,不需要关心List中元素的实际类型,访问效率也是最高的。

Iterator利用两个方法实现遍历:

  • boolean hasNext():判断是否有下一个元素;
  • next():返回下一个元素。
List <String> list = List.of("apple","pear","banana");
for ( Iterator <String> it = list.iterator() ; it.hasNext() ; ){
    String s = it.next();
    ...
}

5.3、for each循环(最常用);

Java的for each循环就是利用Iterator遍历的,用起来更方便:

        List<String> list = List.of("apple", "pear", "banana");
        for (String s : list) {
            System.out.println(s);
        }

 实际上,只要实现了Iterator接口集合类都可以直接用for each循环来遍历,Java编译器本身不知道如何遍历集合,它只会把for each变成Iterator调用,原因就在于Iterator接口定义了一个Iterator <E> iterator(),强迫集合类必须返回一个Iterator实例。

6、List与Array转换

①List→Array

1、list.toArray():List→Object[ ]

Object [] array = list.toArray();
for (Object s : array){
    System.out.println(s);
}

这种方法会丢失类型信息,所以不常用。

2、list.toArray( T[ ] ):List→T[ ]

Integer [] array = list.toArray(new Integer[3]);
//
Integer [] array = new Integer [3];
list.toArray( array );

for( Integer n : array ){
    System.out.println(n);
}

这里的T与构建List接口时定义的泛型E可以不同。比如,我们可以传入一个Number作为T,返回的仍然是Number类型:

List <Integer> list = List.of(1,2,3);
Number [] array = list.toArray(new Number [3]);
for (Number n : list){
    System.out.println(n);
}

 但是TE不能不匹配,比如用String[ ]数组去承接ListInteger元素,就会抛出ArrayStoreException这个异常。

如果我们传入的数组大小和实际的List大小不同,那么会有两种情况:

  • 传入小数组,会在List内部创建一个新的大小正好的数组,返回;
  • 传入大数组填充元素多余元素补null

最常用

实际使用时,为了确保传入一个大小适当的数组,通常在用list.size构建数组:

Integer [] array = list.toArray( new Integer [ list.size() ] );

3、list.toArray( IntFunction <T[ ]> generator )

还有一种更简洁的写法是通过List接口定义的T [ ] toArray( IntFunction <T[ ]> generator )方法:

Integer [] array = list.toArray(Integer[] :: new)

这种函数式写法我们在之后会讲到。

②Array→List

把Array变为List很简单,可以直接通过List.of( T... ):

Integer [] array = [1,2,3];
List<Integer> list = List.of( array );

对于JDK 11之前的版本,可以用Arrays.asList( T... )Array转为List

不过,返回的List不一定是ArrayListLinkedList,因为List只是一个接口,所有返回的List(包括List.of( ... ))都是Read-Only List,只能访问它的元素,而不能对其增删(add、remove方法,如果调用remove、add会抛出UnsupportedOperationException

 

posted @   ShineLe  阅读(426)  评论(0编辑  收藏  举报
编辑推荐:
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
阅读排行:
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
点击右上角即可分享
微信分享提示