List集合
三:List集合
List集合是单列集合的一种,它所存储的元素是可以重复的。List是直接实现Collection接口类的一种。完整的lIst接口类定义如下。
public interface List<E>extends Collection<E>
E是指代了泛型,泛型说明了类属性。
与 set 不同,列表通常允许重复的元素。更确切地讲,列表通常允许满足 e1.equals(e2) 的元素对 e1 和 e2,并且如果列表本身允许 null 元素的话,通常它们允许多个 null 元素。
List 接口在 iterator、add、remove、equals 和 hashCode 方法的协定上加了一些其他约定,超过了 Collection 接口中指定的约定。为方便起见,这里也包括了其他继承方法的声明。
List 接口提供了 4 种对列表元素进行定位(索引)访问方法。列表(像 Java 数组一样)是基于 0 的。注意,这些操作可能在和某些实现(例如 LinkedList 类)的索引值成比例的时间内执行。因此,如果调用者不知道实现,那么在列表元素上迭代通常优于用索引遍历列表。
List 接口提供了特殊的迭代器,称为 ListIterator,除了允许 Iterator 接口提供的正常操作外,该迭代器还允许元素插入和替换,以及双向访问。还提供了一个方法来获取从列表中指定位置开始的列表迭代器。
List 接口提供了两种在列表的任意位置高效插入和移除多个元素的方法。
既然是接口,那必然需要实现类了。我们通常需要了解两种,那就是ArrayList,LinkedList。
1:实现类ArrayList
<1>方法说明
注意ArrayList只是实现了List,但是并没有继承List接口
public class ArrayList<E>extends AbstractList<E>implements List<E>, RandomAccess, Cloneable, Serializable
可见ArrayList的继承自AbstractList,然后我们查看AbstractList的类定义
查询JDK API说明我们可以看到AbstractList的完整定义
public abstract class AbstractList<E>extends AbstractCollection<E>implements List<E>
溯源
public abstract class AbstractCollection<E>extends Object implements Collection<E>
这些了解就可以,没有什么疑问,Object是根。
ArrayList数据结构为数组,通过数组的特点,我们可以了解到,数组的查询是比较快的,但是增删是比较慢的。
我们来看ArrayList的几个常用的方法。
测试了大部分方法
//1:将指定的元素添加到此列表的尾部。
List l = new ArrayList<>();
//ArrayList L = new ArrayList<>();
l.add("Hello");//一次只能插入一个元素
System.out.println(l);
// 2: add(int index, E element)
l.add(0,"jgdabc");
System.out.println(l);
ArrayList l1 = new ArrayList<>();
l1.add("jgdabc01");
l1.add(20);
System.out.println(l1);
//3:add()方法,整个集合添加
l.add(l1);
l.addAll(1,l1);
System.out.println(l);
//4:addAll(Collection<? extends E> c)
l.addAll(l1);
System.out.println(l);
//5:addAll(int index, Collection<? extends E> c)
//从指定的位置开始,将指定 collection 中的所有元素插入到此列表中。
l.add(1,l1);
System.out.println(l);
//6:clear()
//移除此列表中的所有元素。
l.clear();
System.out.println(l);
//7:contains(Object o)
//如果此列表中包含指定的元素,则返回 true。
boolean flag = l1.contains("jgdabc");
System.out.println(flag);
//8:get(int index)
//返回此列表中指定位置上的元素。如果集合为空,会报异常。
l.add("jgdabc");
String s = (String) l.get(0);
System.out.println(s);
//9:indexOf(Object o)
//返回此列表中首次出现的指定元素的索引,或如果此列表不包含元素,则返回 -1。
int x = l.indexOf("jgdabc");
System.out.println(x);
//10:isEmpty()
//如果此列表中没有元素,则返回 true
boolean flag_1 = l.isEmpty();
System.out.println(flag_1);
//11:lastIndexOf(Object o)
//返回此列表中最后一次出现的指定元素的索引,或如果此列表不包含索引,则返回 -1。
int flag_2 = l.lastIndexOf("jgdabc");
System.out.println(flag_2);
//12:remove(int index)
l.remove(0);
System.out.println(l);
//13:removeRange(int fromIndex, int toIndex)
//移除列表中索引在 fromIndex(包括)和 toIndex(不包括)之间的所有元素。
// removeRange()方法受保护,只提供子类使用
l.add("jgdabc");
l.add("jgdabc01");
ArrayList ll = new ArrayList<>();
ArrayList ll2 = ll;
//14:set(int index, E element)
//用指定的元素替代此列表中指定位置上的元素。
l.set(0, "zhan");
System.out.println(l);
// 15:toArray()
//按适当顺序(从第一个到最后一个元素)返回包含此列表中所有元素的数组
l.toArray();
System.out.println(l);
// 17:trimToSize()
//将此 ArrayList 实例的容量调整为列表的当前大小。
((ArrayList<Object>) l).trimToSize();
System.out.println(l.size());
其中需要注意的就是两个方法,一个removeRange(),这个方法虽然在ArrayList中被提供,但是受到保护,只能被子类使用。也就是写一个继承类就好。
还有一个方法,可能并不常用。其实涉及到优化。那就是trimToSize()方法
ArrayList 的内部使用数组存储元素,当数组将被存满,就会创建一个新数组,其容量是当前数组的 1.5 倍。
同时,所有元素都将移至新数组,假设内部数组已满,而我们现在又添加了 1 个元素,ArrayList 容量就会以相同的比例扩展(即前一个数组的1.5倍)。
在这种情况下,内部数组中将有一些未分配的空间。
这时,trimToSize() 方法可以删除未分配的空间并更改 ArrayList 的容量,使其等于 ArrayList 中的元素个数。
- 点赞
- 收藏
- 关注作者
评论(0)