Java面向对象系列[v1.0.0][List]

List集合代表一个元素有序、可重复的集合,集合中每个元素都有其对应的顺序索引,默认按元素的添加顺序设置元素的索引

List接口和ListIterator接口

List作为Collection接口的子接口,可以使用Collection接口里的全部方法,而且由于List是有序集合,List本身还提供了一些高效的的方法:

  • void add(int index, Object element): 将元素element插入到List集合的index处
  • boolean addAll(int index, Collection c): 将集合c所包含的所有元素都插入到List集合的index处
  • Object get(int index):返回集合index索引处的元素
  • int indexOf(Object o):返回对象o在List集合中第一次出现的位置索引
  • 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(不包含)处所有集合元素组成的子集合
  • void replaceAll(UnaryOperator operator): 根据operator指定的计算规则重新设置List集合的所有元素,接受Lambda坐位参数
  • void sort(Comparator c): 根据Comparator参数对List集合元素排序,接受lambda作为参数
package demo;
import java.util.*;
import static java.lang.System.*;

public class ListTest
{
    public static void main(String[] args)
    {
        var books = new ArrayList();
        // 向books集合中添加三个元素
        books.add("我醉欲眠卿且去");
        books.add("去你妈地");
        books.add("去你大爷滴");
        out.println(books);
        // 将新字符串对象插入在第二个位置
        books.add(1, new String("书山有路勤为径"));
        for (var i = 0; i < books.size(); i++)
        {
            out.println(books.get(i));
        }
        // 删除第三个元素
        books.remove(2);
        out.println(books);
        // 判断指定元素在List集合中的位置:输出1,表明位于第二位
        // 实际上这是另一个对象,在最开始添加的时候new了一个对象,现在又new了一个
        // 虽然两个对象,但List判断两个对象相等只需要通过equals()方法判断返回true
        // 因此也会将下边新new的对象当作之前添加的对象,并返回其在List中的位置
        out.println(books.indexOf(new String("书山有路勤为径"))); // ①
        //将第二个元素替换成新的字符串对象
        books.set(1, "去你妈地");
        out.println(books);
        // 将books集合的第二个元素(包括)
        // 到第三个元素(不包括)截取成子集合
        out.println(books.subList(1, 2));
    }
}
package demo;
import java.util.*;
import static java.lang.System.*;

class A
{
    public boolean equals(Object obj)
    {
        return true;
    }
}
public class ListTest2
{
    public static void main(String[] args)
    {
        var books = new ArrayList();
        books.add("我醉欲眠卿且去");
        books.add("去你妈地");
        books.add("去你大爷地");
        out.println(books);
        // 删除集合中的A对象,将导致第一个元素被删除
        // 程序试图删除一个A对象,List将会调用该A对象的equals()方法依次与集合元素进行比较
        // 如果该equals()方法与某个集合元素作为参数时返回true,List将会删掉该元素
        // A类重写了equals()方法,该方法总是返回true,所以每次从List集合中删除A对象时
        // 总是删除List集合中第一个元素
        books.remove(new A());     // ①
        out.println(books);
        // 删除集合中的A对象,再次删除集合中的第一个元素
        books.remove(new A());     // ②
        out.println(books);
    }
}
package demo;
import java.util.*;
import static java.lang.System.*;

public class ListTest3
{
    public static void main(String[] args)
    {
        var books = new ArrayList();
        // 向books集合中添加4个元素
        books.add("锄禾日当午啊");
        books.add("汗滴禾下土啊啊");
        books.add("谁知盘中餐啊啊啊");
        books.add("粒粒皆辛苦啊啊啊啊");
        // 使用目标类型为Comparator的Lambda表达式对List集合排序
        books.sort((o1, o2) -> ((String) o1).length() - ((String) o2).length());
        out.println(books);
        // 使用目标类型为UnaryOperator的Lambda表达式来替换集合中所有元素
        // 该Lambda表达式控制使用每个字符串的长度作为新的集合元素
        books.replaceAll(ele -> ((String) ele).length());
        // 输出[6, 7, 8, 9]
        out.println(books);
    }
}

List还提供了listIterator()方法,该方法返回一个ListIterator对象,ListIterator接口继承了Iterator接口,并且还提供了专门操作List的方法:

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

listIterator和普通Iterator相比增加了向前迭代的功能,还可以通过add()方法向List集合添加元素(Iterator只能向后迭代和删除元素)

package demo;
import java.util.*;
import static java.lang.System.*;

public class ListIteratorTest
{
    public static void main(String[] args)
    {
        String[] books = {
                "What are you doing?", "How are you doing today!",
                "How are you!"
        };
        var bookList = new ArrayList();
        for (var i = 0; i < books.length; i++)
        {
            bookList.add(books[i]);
        }
        var lit = bookList.listIterator();
        // 从前向后遍历
        while (lit.hasNext())
        {
            out.println(lit.next());
            lit.add("-------分隔符-------");
        }
        out.println("=======下面开始反向迭代=======");
        // 从后向前遍历
        while (lit.hasPrevious())
        {
            out.println(lit.previous());
        }
    }
}

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集合需要保存多少个元素,则可以在创建它们的时就指定initialCapacity大小

  • 如果创建空的ArrayList或Vector集合时不指定initialCapacity参数,则Object[]数组的长度默认为10

  • void ensureCapacity(int minCapacity):将ArrayList或Vector集合的Object[]数组长度增加大于或等于minCapacity值

  • void trimToSize():调整ArrayList或Vector集合的Object[]数组长度为当前元素的个数,调用该方法可减少ArrayList或Vector集合对象占用存储空间

Vector和ArrayList区别

  • Vector是个古老的集合JDK1.0的时候就有了,那时候Java还不存在集合框架,Vector提供了一些方法名很长的方法,例如addElement(Object obj),实际上这个方法与add(Object obj)没有任何区别,在JDK1.2后Java提供了集合框架,将Vector改为实现List接口,作为List的实现之一,导致Vector里有一些功能重复的方法
  • Vector后续新增的方法方法名更短,老的方法方法名较长,后来Java改写了Vector原有的方法,将方法名缩短简化bi’a编程
  • ArrayList开始就作为List的主要实现类,没有那些方法名很长的方法,Vector具有很多缺点,尽量少用
  • ArrayList是线程不安全的,多个线程访问同一个ArrayList集合时,如果有超过一个线程修改了ArrayList集合,则程序必须手动保证该集合的同步性
  • Vector是线程安全的,也因此性能比ArrayList要低
  • Vector提供了一个Stack子类,用于模拟”栈“这种数据结构,栈通常指后进先出(LIFO)的容器,后push进栈的将先被pop出栈,Stack提供了Object peek():返回”栈“第一个元素,但并不将该元素”pop“出栈,Object pop():返回栈的第一个元素并pop该元素,void push(Object item):将一个元素push进栈,最后一个进栈的元素总是位于栈顶
  • Stack继承了Vector,它也是个古老的Java集合类,线程安全性能较差,尽量少用

固定长度的List

有一个数组的工具类Arrays,该工具类提供了asList(Object… a)方法,该方法可以把一个数组或者指定个数的对象转换成一个List集合,这个List集合既不是ArrayList实现类的实例,也不是Vector实现类的实例,而是Arrays的内部类ArrayList实例
Arrays.ArrayList是一个固定长度的List集合,只能遍历访问该集合里的元素,不可增加、删除该集合里的元素

package demo;
import java.util.*;
import static java.lang.System.*;

public class FixedSizeList
{
    public static void main(String[] args)
    {
        var fixedList = Arrays.asList("AAAAAA", "BBBBBB");
        // 获取fixedList的实现类,将输出Arrays$ArrayList
        out.println(fixedList.getClass());
        // 使用方法引用遍历集合元素
        fixedList.forEach(System.out::println);
        // 对于普通集合来说如下操作完全正常,但Arrays.ArrayList就不可以
        // 试图增加、删除元素都会引发UnsupportedOperationException异常
        fixedList.add("CCCCCC");
        fixedList.remove("DDDDDD");
    }
}
发布了207 篇原创文章 · 获赞 124 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/dawei_yang000000/article/details/105164713