前面一篇的corejava讲的是集合的概述,这一篇我将详细的和大家讲解一下Collection下面的List、set、queue这三个子接口。希望大家能得到提升。

一、List接口

1.1、List接口概述

  List类型集合特点:集合中的元素有序且可重复,有下标 。

    注:有序指的是元素放到集合中的顺序和循环遍历出来的顺序一致

  List接口常见的实现类有:ArrayList、LinkedList、Vector等

    对于数据的随机访问,ArrayList效率优于LinkedList,因为LinkedList要移动指针

    对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据

    Vector是线程安全的集合,但是速度慢

1.2、迭代器

  在讲集合之前我们先来说一下迭代器,因为之后我们遍历数据的时候要用到迭代器。

  1)迭代器原理

    迭代器是对集合进行遍历,而每一个集合内部的存储结构都是不同的,所以每一个集合存和取都是不一样,那么就需要在每一个类中定义hasNext()和next()方法,这样做是可以的,

  但是会让整个集合体系过于臃肿,迭代器是将这样的方法向上抽取出接口,然后在每个类的内部,定义自己迭代方式,这样做的好处有二,第一规定了整个集合体系的遍历方式都是hasNext()和next()方法,第二,代码有底层内部实现,使用者不用管怎么实现的,会用即可 。

  我们可以去查看一下ArrayList中迭代器的源码进行分析:  

,在eclipse中ctrl + shift + t找到ArrayList类
,ctrl+o查找iterator()方法
,查看返回值类型是new Itr(),说明Itr这个类实现Iterator接口
,查找Itr这个内部类,发现重写了Iterator中的所有抽象方法

Viewstep

 3)Iterator中的方法

boolean hasNext() 如果仍有元素可以迭代,则返回 true。
E next() 返回迭代的下一个元素。
void remove() 从迭代器指向的 collection 中移除迭代器返回的最后一个元素

 3)ListIterator接口

    ListIterator是Iterator的子接口。那为什么要有这个特定的子接口呢?    

      在迭代时,不可以通过集合对象的方法操作集合中的元素。因为会发生ConcurrentModificationException异常。

    所以,在迭代器时,只能用迭代器的放过操作元素,可是Iterator方法是有限的,只能对元素进行判断,取出,删除的操作,

    如果想要其他的操作如添加,修改等,就需要使用其子接口,ListIterator。该接口只能通过List集合的listIterator方法获取。

    这是List中针对迭代的类。我们可以查看源码。这里返回的是一个ListIterator对象

    

    方法有:

* boolean hasNext()是否有下一个
* boolean hasPrevious()是否有前一个
* Object next()返回下一个元素
* Object previous();返回上一个元素

1.3、List中特有的方法


add(index,element);
addAll(index,Collection); 删
remove(index); 改
set(index,element);

get(index):
subList(from,to);
listIterator();
int indexOf(obj):获取指定元素的位置。
ListIterator listIterator();

  使用size和get(index)遍历student对象:

//通过size()和get()方法结合使用遍历
List<Student> list = new ArrayList<>();
list.add(new Student("张三",));
list.add(new Student("李四",));
list.add(new Student("王五",));
list.add(new Student("小二",)); for (int i = ; i <list.size() ; i++) {
Student s = (Student)list.get(i);
System.out.println(s.getName()+":"+s.getAge());
}

1.4、集合中并发修改异常产生的原因及解决方案

  需求:我有一个集合,请问,我想判断里面有没有"hello"这个元素,如果有,我就添加一个"world"元素,请写代码实现。    

 List<String> list = new ArrayList<>();
list.add("meinv");
list.add("gt");
list.add("ecg");
list.add("hello");
list.add("bvc");
list.add("aew"); Iterator<String> it = list.iterator();
while (it.hasNext()){
String str = (String)it.next();
if(str.equals("hello")){
list.add("world"); //这里会抛出ConcurrentModificationException并发修改异常
}
}

  解决方案:

    迭代器迭代元素,迭代器修改元素(ListIterator的特有功能add)   

    集合遍历元素,集合修改元素

ListIterator lit = list.listIterator();        //如果想在遍历的过程中添加元素,可以用ListIterator中的add方法
while(lit.hasNext()) {
String str = (String)lit.next();
if(str.equals("hello")) {
lit.add("world");
//list.add("world");
}
}

      

1.5、ArrayList

  1)ArrayList去除集合中字符串的重复值(字符串的内容相同)

    我们可以创建一个新的集合去存储没有重复值的集合

public static void main(String[] args) {
ArrayList list = new ArrayList();
list.add("a");
list.add("a");
list.add("b");
list.add("b");
list.add("b");
list.add("c");
list.add("c");
list.add("c");
list.add("c"); System.out.println(list);
ArrayList newList = getSingle(list);
System.out.println(newList);
} /*
* 去除重复
* 1,返回ArrayList
* 2,参数列表ArrayList
*/
public static ArrayList getSingle(ArrayList list) {
ArrayList newList = new ArrayList(); //创建一个新集合
Iterator it = list.iterator(); //获取迭代器
while(it.hasNext()) { //判断老集合中是否有元素
String temp = (String)it.next(); //将每一个元素临时记录住
if(!newList.contains(temp)) { //如果新集合中不包含该元素
newList.add(temp); //将该元素添加到新集合中
}
}
return newList; //将新集合返回
}

案例一

  2)去除ArrayList中重复自定义对象元素

    分析:我们通过查看上面的例子中,contains()方法底层也是通过equals来做判断的,所以这里我们需要判断自定义对象的话,我们需要在Student类中重写equals方法。

        这里我们使用contains()方法判断是否包含,底层依赖的是equals()方法

              remove()方法判断是否删除,底层依赖的也是equals()方法

 public boolean remove(Object o) {
if (o == null) {
for (int index = ; index < size; index++)
if (elementData[index] == null) {
fastRemove(index);
return true;
}
} else {
for (int index = ; index < size; index++)
if (o.equals(elementData[index])) {
fastRemove(index);
return true;
}
}
return false;
}

查看remove方法的源码

package com.zyh.domain;

public class Student {
private String name;
private int age; public Student() {
} public Student(String name,int age) {
this.name = name;
this.age = age;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} @Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
} @Override
public boolean equals(Object obj) {
Student s = (Student)obj;
return this.name.equals(s.name)&&this.age==this.age;
}
}

Student

package com.zyh.Collection.List;

import com.zyh.domain.Student;

import java.util.ArrayList;
import java.util.ListIterator; //去除ArrayList中重复的Student对象元素
public class ArrayListDemo_0010 {
public static void main(String[] args) {
ArrayList<Student> list = new ArrayList<>();
list.add(new Student("哥哥",));
list.add(new Student("姐姐",));
list.add(new Student("弟弟",));
list.add(new Student("花花",));
list.add(new Student("姐姐",));
list.add(new Student("花花",));
list.add(new Student("弟弟",));
list.add(new Student("花花",));
list.add(new Student("哥哥",)); ArrayList<Student> newList =getSignle(list); ListIterator<Student> slit = newList.listIterator();
while (slit.hasNext()){
Student s = slit.next();
System.out.println(s.getName()+":"+s.getAge());
}
} public static ArrayList<Student> getSignle(ArrayList<Student> list){
ListIterator<Student> slit = list.listIterator();
ArrayList<Student> newList = new ArrayList<>();
while (slit.hasNext()){
Student s = slit.next();
while (!newList.contains(s)){
newList.add(s);
}
}
return newList;
}
}

ArrayListDemo_0010

1.6、LinkedList

  1)LinkedList特有的方法

  * public void addFirst(E e)及addLast(E e)
* public E getFirst()及getLast()
* public E removeFirst()及public E removeLast()
* public E get(int index);

  2)用LinkedList模拟栈数据结构的集合并测试

    栈:先进后出   队列:先进先出

    需求:请用LinkedList模拟栈数据结构的集合,并测试

public class Stack<T>
{
private LinkedList<T> stack; //无参构造函数
public Stack()
{
stack=new LinkedList<T>();
}
//构造一个包含指定collection中所有元素的栈
public Stack(Collection<? extends T> c)
{
stack=new LinkedList<T>(c);
}
//入栈
public void push(T t)
{
stack.addFirst(t);
}
//出栈
public T pull()
{
return stack.remove();
}
//栈是否为空
boolean isEmpty()
{
return stack.isEmpty();
} //打印栈元素
public void display()
{
for(Object o:stack)
System.out.println(o);
}
}

Stack详细实现

            public class Stack {
private LinkedList list = new LinkedList(); //创建LinkedList对象 public void in(Object obj) {
list.addLast(obj); //封装addLast()方法
} public Object out() {
return list.removeLast(); //封装removeLast()方法
} public boolean isEmpty() {
return list.isEmpty(); //封装isEmpty()方法
}
}

Stack

1.6、Vector

  1)特有方法

    * public void addElement(E obj)
* public E elementAt(int index)
* public Enumeration elements()

  2)使用枚举遍历

            Vector v = new Vector();                //创建集合对象,List的子类
v.addElement("a");
v.addElement("b");
v.addElement("c");
v.addElement("d"); //Vector迭代
Enumeration en = v.elements(); //获取枚举
while(en.hasMoreElements()) { //判断集合中是否有元素
System.out.println(en.nextElement());//获取集合中的元素
}

二、List接口三个子类的特点与区别

2.1、List接口三个子类的特点

  1)ArrayList:
    底层数据结构是数组,查询快,增删慢。
    线程不安全,效率高。
  2)底层数据结构是数组,查询快,增删慢。
    线程安全,效率低。
     Vector相对ArrayList查询慢(线程安全的)
    Vector相对LinkedList增删慢(数组结构)
  3)LinkedList:
    底层数据结构是链表,查询慢,增删快。
    线程不安全,效率高。

2.2、List接口三个子类的区别

   1)Vector和ArrayList的区别
    Vector是线程安全的,效率低
    ArrayList是线程不安全的,效率高
  2)共同点:都是数组实现的
  3)ArrayList和LinkedList的区别
    ArrayList底层是数组结果,查询和修改快
    LinkedList底层是链表结构的,增和删比较快,查询和修改比较慢
  4)共同点:都是线程不安全的

JavaSE(十)集合之List的更多相关文章

  1. JAVASE(十四) 集合: 数组和集合、Collection、Iterator、List、Set、Map

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 1.数组和集合 1.1 内存中对数据进行存储和管理的“容器”:数组,集合 1.2 数组存储的特点和缺点 ...

  2. C#基础知识系列十(集合)

    前言 本节主要是来了解学习集合,以方便在程序编写时,什么地方该选用什么集合,让程序更健壮的运行起来.在学习了解集合之前,首先需要了解一些数据结构方面的知识.下面我们就先简单的来看一下数据结构. 数据结 ...

  3. JavaSE笔记-集合

    Java集合大致可分为:List,Set,Map,Queue List:有序,可重复 Set:无序(输出和插入顺序不一定一致),不可重复 Map:映射关系,根据key去访问value Queue:队列 ...

  4. JavaSE Map集合

    Map集合 在Map集合中保存的数据为一组数据,其中:一个数据为key,另外一个数据为value.而key和value具备对应的关系,在集合中它们属于一组(一对)数据.而每个key只能对应唯一的一个v ...

  5. JavaSE List集合

    我们掌握了Collection接口的使用后,再来看看Collection接口中的子接口和实现类,他们都具备那些特性呢? 接下来,我们一起学习Collection中的常用几个子接口: ​ java.ut ...

  6. JavaSE Set集合

    明确Set集合接口的特点. java.util.Set接口和java.util.List接口一样,同样继承自Collection接口,它与Collection接口中的方法基本一致,并没有对Collec ...

  7. JavaSE Collection集合

    集合:是java中提供的一种容器,可以用来存储多个对象.可是我们前面学习的数组也是可以保存多个对象的,为什么还要提供集合容器呢?集合和数组它们有啥区别呢? 数组的长度是固定的.一旦创建完成不能改变长度 ...

  8. Java从零开始学二十(集合简介)

    一.为什么需要集合框架 数组的长度是固定的,但是如果写程序时并不知道程序运行时会需要多少对象.或者需要更复杂的方式存储对象,---那么,可以使用JAVA集合框架,来解决这类问题 二.集合框架主要接口 ...

  9. Javase之集合体系(4)之Map集合

    集合体系之Map集合 ##Map<K,V>( 接口 ) 特点:将键映射到值对象,一个映射不能包含重复的键:每个键只能映射一个值 Map集合与Collection集合的区别 ​ Map集合存 ...

  10. Javase之集合体系(2)之List及其子类ArrayList,LinkedList与Vector及其迭代器知识

    集合体系之List及其子类ArrayList,LinkedList与Vector及其迭代器知识 List(接口) 特点:有序(存储与取出顺序相同),可重复 List子类特点: ​ ArrayList: ...

随机推荐

  1. Vmware虚拟机三种网络模式详解

    原文来自http://note.youdao.com/share/web/file.html?id=236896997b6ffbaa8e0d92eacd13abbf&type=note 我怕链 ...

  2. iframe嵌入页面不能全部展示

    在嵌入页面不能全部展示的问题中,可以通过js改变iframe的高度 html部分代码: <iframe src="#" name="i" id=" ...

  3. LoadRunner入门(二)

    三.设计场景 1.打开Controller 2.选择运行的脚本 3.场景设置 3.1修改场景模式 点击scenario-convert- 修改场景百分比模式 (1)Group Name:脚本名称 (2 ...

  4. Oracle联机日志损坏解决办法

    关于此问题,在网上找到一篇不错的文章. 大家都清楚,联机日志分为当前联机日志和非当前联机日志. ---------------------------------------------------- ...

  5. java api1.8中文版(由谷歌,百度,有道,必应翻译).md

    大家如果想看java1.8 的中文api可以点击我下面提供的链接,同时感谢把这些资源放到网上供我们学习的朋友,废话不说了下面就是链接: java 1.6 帮助文档 中文 链接:http://downl ...

  6. 【Regular Expression】RE分类及案例

    背景知识 正则表达式分为三类:基础正则表达式.扩展正则表达式.Perl正则表达式(Perl内建) 通俗来说,这三个一个比一个强大,支持的规则匹配字符更多 1.匹配IP ip addr | grep - ...

  7. SQLite在C#中的安装与操作

    SQLite 介绍 SQLite,是一款轻型的数据库,用于本地的数据储存. 先说说优点,它占用资源非常的低,在嵌入式设备中需要几百K的内存就够了:作为轻量级数据库,他的处理速度也足够快:支持的的容量级 ...

  8. Java的static关键字

    本文参考:Java的static关键字 通过static关键字可以满足两方面的需要.一种情形是,只想为某特定域分配单一存储空间,而不去考虑究竟要创建多少对象,甚至根本就不创建任何对象.另一种情形是,希 ...

  9. 调试大叔V1.0.1(2017.09.01)|http/s接口调试、数据分析程序员辅助开发神器

    2017.09.01 - 调试大叔 V1.0.1*支持http/https协议的get/post调试与反馈:*可保存请求协议的记录:*内置一批动态参数,可应用于URL.页头.参数:*可自由管理cook ...

  10. thinkjs 文件上传

    采用thinkjs框架写前后端 let formdata = new FormData($('form')[0]); $('#fileUpload').submit(function (e) { e. ...