夯实基础——Java基础学习(List 集合)

目录

  • List集合
    • 改进的List接口和ListIterator接口
    • ArrayList和Vector实现类
    • 固定长度的List

List集合

List集合代表着这个有序的、可重复的集合,集合当中每个元素都有其对应的顺序索引。List集合允许使用重复元素,可以通过索引来访问指定位置的集合元素。List集合默认按照元素的添加顺序设置索引。

改进的List接口和ListIterator接口

List作为Collection的子接口,可以使用Collection里面的所有方法。而且由于List是一个有序集合所以添加了一些根据索引操作的方法。

  • void add(int index , Object element):将元素element添加到index索引处
  • boolean addAll(int index , Collection c):将集合c所包含的所有元素都插到List集合的index处。
  • Object get(int index): 返回集合index中的元素
  • int lastIndexOf(Object o):返回对象o在List集合中第一次出现的位置索引。
  • Object remove (int index ): 删除在index索引处的元素。
  • Object set(int index,Object element): 将index索引处的对象替换为element
  • List subList(int fromIndex,int toIndex):返回从fromIndex处到toIndex处的子列表。

所有的List实现类都可以调用这些方法来操作集合元素。与Set集合相比较,List添加了根据索引来插入、替换和删除集合元素的方法。除此之外,Java8
还为List接口添加了如下两个默认方法。

  • void replaceAll(UnaryOperator operator): 根据operation指定的就是你规则重新设置List集合的所有元素。
  • void sort(Comparator c):根据Comparator参数对List集合的元素排序。

import java.util.ArrayList;
import java.util.TreeSet;

public class App {
    public static void main(String[] args) throws Exception {
        ArrayList javas = new ArrayList();
        javas.add("开始学习");
        javas.add("怀疑人生");
        javas.add("萌生退意");
        System.out.println(javas);
        javas.add(1,new String("直接放弃"));
        for (int i= 0;i<javas.size();i++){
            System.out.println(javas.get(i));
        }
        javas.remove(2);
        System.out.println(javas);
        System.out.println(javas.indexOf("直接放弃"));
        javas.set(1, "怀疑人生");
        System.out.println(javas);
        System.out.println(javas.subList(1, 2));
    }

}

上述程序输出结果如下:

[开始学习, 怀疑人生, 萌生退意]
开始学习
直接放弃
怀疑人生
萌生退意
[开始学习, 直接放弃, 萌生退意]
1
[开始学习, 怀疑人生, 萌生退意]
[怀疑人生]

从上面的程序可以看出list的一些基本用法,同时可以看出list判断两个对象的标准:只要通过equlas方法就返回true就认为它们是相等。

与set只提供一个iterator()方法不同,List还额外提供了一个listIteration()方法,该方法返回一个ListIterator对象,ListIterator接口继承了Iteration接口,提供了专门操作List的方法。ListIterator接口在Iterator接口基础之上增加了如下的方法。

  • boolean hasPrevious():返回该迭代器关联的集合是否还有上一个元素。
  • Object previous():返回该迭代器的上一个元素。
  • void add(Object o):在指定位置插入一个元素。

拿ListIterator与普通的Iterator进行对比,不难发现ListIterator增加了向前迭代的功能(Iterator只能向后迭代),而且ListIterator和可以通过add()方法向List集合中添加元素。

ArrayList和Vector实现类

ArrayList和Vector作为List类的两个典型实现,完全支持前面介绍的List接口的全部功能。

ArrayList和Vector类都是基于数组实现的List类,所以ArrayList和Vector类封装了一个动态的、允许再分配的Object[]数组。ArrayList或者Vector对象使用initialCapacity参数来设置该数组的长度,当向ArrayList或者Vector中添加元素超过该数组的长度的时候,他的initialCapacity会自动增加。

对于通常的编程场景,程序员无需关心ArrayList和Vector的initialCapacity。但如果向ArrayList或者Vector集合中添加大量元素的时候,可使用ensureCapacity(int minCapacity)方法一次性地增加initialCapacity。这可以减少重分配的次数,从而提高性能。

如果开始知道ArrayList或者Vector集合需要保存多少个元素,则可以在创建它们时就指定initial大小,如果创建空的ArrayList或者Vector集合时不指定initialCapacity参数,则Object[]数组的长度默认为10.

除此之外,ArrayList和Vector还提供了如下两个方法来重新分配Object[]数组。

  • void ensureCapacity(int minCapacity):将ArrayList或者Vector集合的Object[]数组长度增加大于或者等于minCapacity值。
  • void trimToSize():调整ArrayList或Vector集合的Object[]数组长度。调用该方法可减少ArrayList或者Vector集合对象占用的存储空间。、

ArrayList或Vector的显著区别是:ArrayList是线程不安全的,而Vector是线程安全的。所以Vector的性能要比ArrayList要低,但是实际上,即使是在线程当中,也不建议使用Vector。可以通过Collections工具类,他可以将一个ArrayList变成线程安全。

Vector提供了一个Stack子类,其基本上模仿了栈这种数据结构。但是Stack与Vector一样都是一个非常古老的子类,它们都是线程安全,性能较差的。因此应该尽量少用Stack类,如果必须使用Stack类的功能,可以考虑使用ArrayDeque代替。

固定长度的List

在学习数组的时候,介绍了一个工具类:Arrays,该工具类里了asList(Object… a)方法,该方法可以把一个数组或指定个数的对象转换为一个List集合,这个List集合既不是ArrayList实现类的实例,也不是Vector实现类的实例,也不是Vector实现类的实例,而是Arrays的内部类ArrayList的实例。

Arrays.ArrayList是一个固定长度的List集合,程序只能遍历访问该集合里的元素,不可增加、删除该集合里的元素。如下程序所示。

import java.util.Arrays;
import java.util.List;

public class App {
    public static void main(String[] args) throws Exception {
        List fixedList = Arrays.asList("开始学习","学习结束");
        System.out.println(fixedList.getClass());
        fixedList.forEach(System.out::println);
        // fixedList.add("放弃学习");
        // fixedList.remove("开始学习");
    }
}

输出结果如下:

class java.util.Arrays$ArrayList
开始学习
学习结束

任何试图增加或者删除的操作都会引起异常。注释掉代码在运行的时候回引发异常。

你可能感兴趣的:(java,数据结构,编程语言)