List是Collection接口的子接口,表示的是一种有序的、可重复元素的集合。

List接口的主要实现类ArrayList和Vector,底层都是维护了一套动态的,可扩展长度的Object[]数组,通过initialCapacity参数来动态地调整长度。因此,相比较父接口Collection所提供的公共增删改方法,List接口及实现类也定义了通过索引来增删查改元素,或者基于元素查找索引的方法。更一般地,ArrayList中的元素可以为null。

List及List新增的ListIterator接口

List接口的定义方法如下

 public class TestList {

     @SuppressWarnings("unlikely-arg-type")
public static void main(String[] args) { List<String> books = new ArrayList<>();
//List集合添加元素的顺序是有序的
books.add(new String("资本论"));
books.add(new String("***宣言"));
books.add(new String("家庭私有制和国家的起源"));
System.out.println(books);
//add和addAll分别在指定索引处添加元素或另一个集合
books.add(1, "德意志意识形态");
books.forEach(str -> System.out.println(str));
//使用Lambda表达式对List进行排序
books.sort((o1, o2) -> (o1.length() - o2.length()));
System.out.println(books);
//删除指定索引的元素
books.remove(2);
System.out.println(books);
//通过指定索引返回元素(==根据HashCode来判断,此处返回false)
System.out.println(books.get(0) ==new String("资本论"));
//通过indexOf来返回指定元素所在的索引位置
//indexOf通过元素的equals方法来判断, 只要是true就返回对应的索引
System.out.println(books.indexOf(new String("德意志意识形态")));
//通过索引改变元素
books.set(1, new String("神圣家族"));
//返回子集合[1,3), 不改变原集合
System.out.println(books.subList(1, 3)); //使用Lambda表达式使用每个字符的长度替代原集合的元素
books.replaceAll(ele -> ele.length() + "");
//因为A对象equals方法恒返回true,所以集合会在第一次比较中直接删除第一个元素
books.remove(new A());
System.out.println(books);
//同样的,继续删除第一个元素
books.remove(new A());
System.out.println(books.size()); } } class A{
//定义A类对象的equals方法恒返回true
public boolean equals(Object obj) {
return true;
}
}

与Set集合不同,List集合新增了一个继承Iterator接口的子接口ListIterator接口,可以实现反向迭代和增加元素的功能。

 /*
* 与Collection集合的Iterator接口不同, List额外提供一个ListIterator接口(继承了Iterator接口), 增加了如下三个方法:
* 1. hasPrevious():是否还有上一个元素
* 2. previous():返回上一个元素
* 3. add():增加一个元素
*/
public class ListIteratorTest { public static void main(String[] args) { String[] books = {
"资本论","德意志意识形态","***宣言"
};
List<String> booksList = new ArrayList<>();
for(int i=0; i<books.length;i++) {
booksList.add(books[i]);
}
ListIterator<String> lit = booksList.listIterator();
System.out.println("====下面开始正向迭代====");
while(lit.hasNext()) {
System.out.println(lit.next());
lit.add("----分隔符----");
}
System.out.println("====下面开始反向迭代====");
while(lit.hasPrevious()) {
System.out.println(lit.previous());
} } }

ArrayList和Vector

如前所述,ArrayList和Vector底层维护了一个动态可变的对象数组。如果创建对象时不指定容量值,会有一个默认的数组长度10。更一般地,可以通过在创建对象时指定容量值:

1. void ensureCapacity(int minCapacity):将List集合数组长度增加到minCapacity。如可提前知道元素个数,可以赋值长度,以减少频繁扩容所带来的性能开销。

2. void trimToSize():调整数组长度至当前元素的个数,以节省空间。

ArrayList与Vector相比较,需要注意以下几点:

1. ArrayList是线程不安全的,因此性能较高;Vector是线程安全的,但性能较差;后面的博文会介绍如果通过Collection提供的工具类,使ArrayList线程安全。

2. Vector及其子类Stack,是非常古旧的Java集合,并不建议使用。Stack子类所实现的栈功能,也可以通过ArrayDeque来实现。

固定长度的List

数组的工具类Arrays自带一个asList(Object... o)方法,可以将数组或指定数量的对象转换为List,不过需要注意一点:

该类是Arrays类的内部类ArrayList的实例,是固定长度的,相当于数组,只能用于遍历,不能增加和删除里面的元素。

 public class TestArrayList {

     public static void main(String[] args) {

         List<String> list = Arrays.asList("AA", "BB", "CC");
//显示类的类型为java.util.Arrays$ArrayList
System.out.println(list.getClass()); list.forEach(System.out::println);
//以下会抛出运行时异常java.lang.UnsupportedOperationException
list.add("DD"); } }

线性表的性能选择

一般来说,基于数组的ArrayList在随机访问中性能较好;基于链表的LinkedList在插入、删除中性能较好。但在一般使用中,ArrayList总体性能占优,因此使用非常广泛。

1. 如果需要遍历List元素,ArrayList建议使用随机访问方法;对于LinkedList,建议使用Iterator迭代器

2. 如果需要经常插入、删除大量数据的List集合,可以考虑使用LinkedList

Java容器深入浅出之List、ListIterator和ArrayList的更多相关文章

  1. Java容器深入浅出之Collection与Iterator接口

    Java中用于保存对象的容器,除了数组,就是Collection和Map接口下的容器实现类了,包括用于迭代容器中对象的Iterator接口,构成了Java数据结构主体的集合体系.其中包括: 1. Co ...

  2. Java容器深入浅出之数组

    写在前面 关于Java的学习,特别是对于非计算机专业的同学来说,我总是主张从实践中来,到实践中去的学习方法.Java本身是一门应用性特别强的高级编程语言,因此如果能在基于实际开发的经验基础上,对Jav ...

  3. Java容器深入浅出之Map、HashMap、Hashtable及其它实现类

    在Java中,Set的底层事实上是基于Map实现的,Map内部封装了一个Entry内部接口,由实现类来封装key-value对,当value值均为null时,key的集合就形成了Set.因此,Map集 ...

  4. Java容器深入浅出之HashSet、TreeSet和EnumSet

    Java集合中的Set接口,定义的是一类无顺序的.不可重复的对象集合.如果尝试添加相同的元素,add()方法会返回false,同时添加失败.Set接口包括3个主要的实现类:HashSet.TreeSe ...

  5. Java容器深入浅出之String、StringBuffer、StringBuilder

    对字符串的花式处理一直是现代应用系统的主要操作之一,也是对Java基础知识考察的重要方面.事实上,Java字符串类的底层是通过数组来实现的.具体来说,String类是固定长度的数组,StringBuf ...

  6. Java容器深入浅出之PriorityQueue、ArrayDeque和LinkedList

    Queue用于模拟一种FIFO(first in first out)的队列结构.一般来说,典型的队列结构不允许随机访问队列中的元素.队列包含的方法为: 1. 入队 void add(Object o ...

  7. Java 容器源码分析之 ArrayList

    概览 ArrayList是最常使用的集合类之一了.在JDK文档中对ArrayList的描述是:ArrayList是对list接口的一种基于可变数组的实现.ArrayList类的声明如下: 12 pub ...

  8. Java容器学习之ArrayList

    一.概述 ArrayList是java中十分常用的集合类,继承于AbstractList,并实现了List.RandomAccess.Cloneable和Serializable接口.ArrayLis ...

  9. Java 容器:Collection 初探之 List

    1 ///: JavaBasic//com.cnblogs.pattywgm.day1//CollectionTest.java 2 3 package com.cnblogs.pattywgm.da ...

随机推荐

  1. 20155311 实验三 敏捷开发与XP实践 实验报告

    20155311 实验三 敏捷开发与XP实践 实验报告 实验内容 XP基础 xp核心工具 相关工具 实验要求 没有Linux基础的同学建议先学习<Linux基础入门(新版)><Vim ...

  2. 20155330 2016-2017-2 《Java程序设计》第二周学习总结

    20155330 2016-2017-2 <Java程序设计>第二周学习总结 教材学习内容总结 学习目标 了解Java编程风格 认识Java的类型与变量 掌握Java流程控制的方法(分支. ...

  3. 2.Rest Server提供数据库的Json字符串

    Delphi最大的特点是数据库操作便捷.为了能够给App提供数据,这里采用Rest Server后台,然后在用Json文件发送到APP前台. 1.后台的dataset转换为json. 这里百度后就可以 ...

  4. pgpool-II的master-slave模式的分析

    磨砺技术珠矶,践行数据之道,追求卓越价值 回到上一级页面: PostgreSQL集群方案相关索引页     回到顶级页面:PostgreSQL索引页 现象描述: 客户来邮件,问:为何Pgpool-II ...

  5. python 内置模块(os)

    1.OS os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径os.chdir("dirname")  改变当前脚本工作目录:相当于shell下cdos. ...

  6. DevOps是一种文化,不是角色!

    一.DevOps是一种文化,不是角色! 软件无处不在.在如今的世界里,每个主流公司/组织都和软件开发息息相关,并且公司需要向软件一样运作.更快且更敏捷,同时保证安全性和可靠性,这样的要求前所未有的强烈 ...

  7. Sublime Text3.0的安装

    Sublime Text是一款轻量级的易于使用的前端编写软件,个人比较推荐. 找到Sublime的官网,下载对应的版本后,点击安装.安装完成后需要下载相应的插件才能进行更加 有效率的开发工作.编写前端 ...

  8. Python函数标注

    Python函数标注 是关于用户自定义函数中使用的类型的完全可选元数据信息. 函数标注 以Python字典的形式存放在函数的 __annotations__ 属性中,并且不会影响函数的任何其他部分. ...

  9. 1.0 Hadoop的介绍、搭建、环境

    HADOOP背景介绍 1.1 Hadoop产生背景 HADOOP最早起源于Nutch.Nutch的设计目标是构建一个大型的全网搜索引擎,包括网页抓取.索引.查询等功能,但随着抓取网页数量的增加,遇到了 ...

  10. 【python 3.6】python读取json数据存入MySQL(二)

    在网上找到一个包含全国各省市经纬度的json文件,也可以通过上次的办法,解析json关键字,构造SQL语句,插入数据库. JSON文件格式如下: [ { "name": " ...