【Java的集合框架之list 27】

一、list集合和set集合

Collection下面有两个派系:
|-- list:有序(存入和取出的顺序一致),元素都有索引(角标)。元素可以重复
|-- set:无序,元素不能重复

二、list集合:可以完成对元素的增删改查

list:除了有父类Collection的方法,还有一些特有的常见方法
有一个共性特点就是都可以操作角标
1、添加
void add (index,element)   -->按照索引添加元素
void add (index,collection) -->按照索引添加集合
2、删除
object remove(index)  -->按照索引删除元素

3、修改
Object set(index,element)  -->按照索引修改元素

4、获取
Object get(index);  -->按照索引获取元素
int indexOf(object) -->获取对象的索引
int lastIndexOf(object) -->获取对象的最后一个索引
List subList(from,to)  -->获取从from到to索引的集合,from是闭区间,to是开区间

package com.JavaStudy01;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * @Author wufq
 * @Date 2020/7/30 14:13
 */
public class ListDemo01 {
    public static void main(String[] args){
        List list = new ArrayList();
        show(list);
    }

    public static void show(List list) {
        //增加元素
        list.add("ABC1");
        list.add("ABC2");
        list.add("ABC3");

        //添加元素
        list.add(1,"abc8");
        System.out.println(list);//[ABC1, abc8, ABC2, ABC2]

        //删除指定元素
        System.out.println("removeObject:"+list.remove("abc8"));//removeObject:true
        System.out.println("removeIndex:"+list.remove(2));//removeIndex:ABC2
        System.out.println(list);//[ABC1, ABC2]

        //修改元素
        list.set(1,"abc9");
        System.out.println(list);//[ABC1, abc9]

        //获取
        System.out.println(list.get(2));//ABC3

        System.out.println(list.indexOf("ABC3"));//2

        System.out.println(list.lastIndexOf("ABC2"));//1

        System.out.println(list.subList(1,2));//[ABC2]

        //获取所有元素
        //常规取出所有元素的方式
        Iterator it=list.iterator();
        while (it.hasNext()){
            System.out.print(it.next()+" ");//ABC1 abc8 ABC2 ABC3
        }
        System.out.print("
");
        //list特有的取出元素的方式:get
        for(int i=0;i<list.size();i++){
            System.out.print(list.get(i)+" ");//ABC1 abc8 ABC2 ABC3
        }

    }
}

三、list的 listIterator接口

 public interface ListIterator<E> extend Iterator<E>   ListIterator继承了Iterator

List接口提供了特殊的迭代器,称为ListIterator,除了允许Iterator提供的正常的操作外,该迭代器还允许元素插入和替换,以及双向访问。还提供了一个方法来获取从列表中指定位置开始的列表迭代器

注意:只有list具备该迭代功能

listIterator接口的方法:

1、除了具备父类接口iterrator的hashnext()、next()、remove()方法,还具备自身的其他方法

2、boolean hasPrevious():逆向遍历列表,返回true

3、previous():向前查找 。例如:[1,2,3]  用此方法查找的是3,2,1

4、set():替换元素

package com.JavaStudy01;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;


/**
 * @Author wufq
 * @Date 2020/7/30 15:43
 */
public class ListDemo02 {
    public static void main(String[] args){
        List list = new ArrayList();
        listshow(list);
    }

    public static void listshow(List list) {

        list.add("abc1");
        list.add("abc2");
        list.add("abc3");

        /*
        需求:遍历list集合,如果遍历到abc2时,增加一个新元素abc9
         */
        //调用iterator接口
        Iterator it=list.iterator();
        while (it.hasNext()){
            //查找下一个元素
            Object obj =it.next();
            if(obj.equals("abc2")){
                list.add("abc9");
            }
        }
        System.out.println(list); //异常:ConcurrentModificationException当方法检测到对象的并发修改时,但是又不允许修改,抛出异常
        /*
        抛出这个异常的原因是:Iterator对象在查找元素,而list又在修改,这时候Iterator其实是不知道list已经被修改了,所以就抛出了这个错误
        改进的方法:是采用Iterator的子接口ListIterator,这个接口是可以进行修改的

         */

        //改进的方法
        ListIterator lt=list.listIterator();
        //正向遍历hasNext()
        while (lt.hasNext()){
            Object obj=lt.next();
            if(obj.equals("abc2")){
                lt.add("abc9");
            }
        }
        //反向遍历
        while (lt.hasPrevious()){
           
        }
        System.out.println("next:"+lt.next());//遍历后,查找下一个元素-->没有找到抛出java.util.NoSuchElementException
        System.out.println("previous:"+lt.previous());//向前查找 -->abc3
        System.out.print(list); //[abc1, abc2, abc9, abc3]


        System.out.println(lt.nextIndex());

    }
}

四、list常用子类的特点

 list常用的子类
|-- Vector:内部是数组数据结构,是同步的。增删查询都很慢。
|-- ArrayList:内部是数组数据结构,是不同步的。替代了Vector。查询速度快
|-- LinkedList:内部是链表数据结构,是不同步的。增删元素的速度很快

下图是数组和链表如何存储数据的原理,以及各数组和链表的优缺点

 备注:数组是长度固定的,list是可变长度的,如何实现呢?

创建一个新数组,将原来的数组复制到新数组内,就实现了list长度的可变

 数组、链表查询快慢的原因,如下图:

1、LinkedList集合

LinkedList除了继承了list里面常用的一些方法(除listIterator()方法),还有一些自有的方法,如:

|-- addfirst    在列表前头插入元素
|-- addlast  在列表后头插入元素
|-- getfirst   获取第一个元素但是不删除
|-- getlast  获取最后一个元素但是不删除
|-- removefirst 获取第一个元素但是会删除
|-- removelast 获取最后一个元素但是会删除

package com.JavaStudy01;

import java.util.Iterator;
import java.util.LinkedList;

/**
 * @Author wufq
 * @Date 2020/7/31 09:43
 */
public class LinkedListDemo01 {
    public static void main(String[] args){
        LinkedList link = new LinkedList();

        //在第一个元素前面插入元素、最后一个元素后面插入元素
        link.addFirst("abc1");
        link.addFirst("abc2");
        link.addFirst("abc3");

        link.addLast("abd4");

        System.out.println(link);//[abc3, abc2, abc1, abd4]

        //迭代器获取里面所有的元素
        Iterator li=link.iterator();
        while (li.hasNext()){
            System.out.println(li.next());
        }

        //获取第一个元素或者最后一个元素
        System.out.println(link.getFirst()); //abc3   -->获取元素但是不会删除列表内的元素
        System.out.println(link.getFirst());//abc3
        System.out.println(link.getLast());//abc3
        System.out.println(link);//[abc3, abc2, abc1, abd4]

        //移除第一个元素或者最后一个元素
        System.out.println(link.removeFirst());//abc3  -->获取元素但是会删除列表内的元素
        System.out.println(link.removeFirst());//abc2
        System.out.println(link.removeLast());//abd4
        System.out.println(link);//[abc1]

        //循环删除列表内的元素
        while (!link.isEmpty()){
            System.out.println("removeFirst="+link.removeFirst());
        }
        System.out.println("link="+link);//link=[]
    }
}

---需求:使用LinkedList模拟一个堆栈和队列数据结构---

|-- 堆栈的数据结构:先进后出

|-- 队列的数据结构:先进先出

----队列类----

package com.JavaStudy01.LinkedListTest;

import java.util.LinkedList;

/**
 * @Author wufq
 * @Date 2020/7/31 10:38
 */
public class DuiLie {
    private LinkedList link;

    public DuiLie(){
        link = new LinkedList();
    }

    //增加
    public void myAdd(Object obj){
        link.addLast(obj);
    }

    //获取
    public Object getLink(){
        return link.removeFirst();
    }

    //判断
    public boolean isNull(){
        return link.isEmpty();
    }
}

----堆栈类----

package com.JavaStudy01.LinkedListTest;

import java.util.LinkedList;

/**
 * @Author wufq
 * @Date 2020/7/31 10:38
 */
public class DuiZhan {
    private LinkedList link;

    DuiZhan(){
        link = new LinkedList();
    }

    //增加
    public void myDZadd(Object obj){
        link.addFirst(obj);
    }

    //获取
    public Object getDZ(){
        return link.removeFirst();
    }

    //判断
    public boolean dzisNull(){
        return link.isEmpty();
    }
}

----main方法调用-----

package com.JavaStudy01.LinkedListTest;

/**
 * @Author wufq
 * @Date 2020/7/31 10:13
 */
public class LinkedListDemo02 {
    public static void main(String[] args){
        DuiLie dl = new DuiLie();
        dl.myAdd("abc1");
        dl.myAdd("abc2");
        dl.myAdd("abc3");

        while (!dl.isNull()){
            System.out.println(dl.getLink());
        }

        /*
        队列执行结果:abc1  abc2  abc3   -->先进先出
         */

        DuiZhan dz = new DuiZhan();
        dz.myDZadd("abc4");
        dz.myDZadd("abc5");
        dz.myDZadd("abc6");

        while (!dz.dzisNull()){
            System.out.println(dz.getDZ());
        }
        /*
        堆栈执行结果:abc6  abc5  abc4   -->先进后出
         */

    }
}

2、ArrayList集合

需求:ArrayList里面存放自定义对象

-----Person类-------

package com.JavaStudy01.Bean;

/**
 * @Author wufq
 * @Date 2020/7/31 11:24
 */
public class Person {
    private String name;
    private int age;

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

}

----ArrayList类----

package com.JavaStudy01.ArrayList;

import com.JavaStudy01.Bean.Person;

import java.util.ArrayList;
import java.util.Iterator;

/**
 * @Author wufq
 * @Date 2020/7/31 11:23
 * ArrayList里面存放自定义对象
 */
public class ArrayListTest01 {
    public static void main(String[] args){
        ArrayList al = new ArrayList();
        al.add(new Person("张三",23));
        al.add(new Person("李四",24));
        al.add(new Person("王五",25));

        Iterator it=al.iterator();
        while (it.hasNext()){
            Person p= (Person) it.next();//next是一个Object对象,多态强制转换成person对象,用于获取ArrayList里面的元素
            System.out.println(p.getName()+"::"+p.getAge());
        }
    }
}

ArrayList集合放自定义对象内存原理图

 其他知识点:集合里面只能放对象,new ArrayList().add(1);   --->其实是进行了自动装箱new ArrayList().add(new integer(1))

原文地址:https://www.cnblogs.com/frankruby/p/13407892.html