0060 List接口

/*
    List接口和常用方法

    List接口是Collection接口的子接口
    1.List集合类中元素有序(即添加顺序和取出顺序一致)且可重复
    2.List集合中的每个元素都有其对应的顺序索引(整型int),即支持索引取出元素(索引从0开始)
    4.List接口实现类主要有Vector,LinkedList,Arraylist

    List接口常用方法
    List集合里添加了一些根据索引来操作集合元素的方法
    1.void add(int index,Object ele)                        //在index位置插入ele元素
    2.boolean addAll(int index,Collection ele)              //从index位置开始将ele中所有元素添加进来
    3.Object get(int index)                                 //获取指定index位置的元素
    4.int indexOf(Object obj)                               //返回obj在集合中首次出现的位置
    5.int lastIndexOf(Object obj)                           //返回obj在集合中最后一次出现的位置
    6.Object remove(int index)                              //移除指定index位置的元素,并返回
    7.Object set(int index,Object ele)                      //设置指定index位置元素为ele,即替换
    8.List subList(int fromIndex,int toIndex)               //返回从fromIndex到toIndex位置的子集合
 */
import java.util.ArrayList;
import java.util.List;
public class List_ {
    @SuppressWarnings({"all"})
    public static void main(String[] args) {
        //List集合类中元素有序(即添加顺序和取出顺序一致)且可重复
        List list = new ArrayList();
        list.add("smith");
        list.add("mary");
        list.add("mary");
        System.out.println(list);//[smith, mary, mary]
        //List集合中的每个元素都有其对应的顺序索引,即支持索引取出元素(索引从0开始)
        System.out.println(list.get(1));//mary

        //常用方法
        //add
        list.add(1, "huang");
        System.out.println(list);//[smith, huang, mary, mary]

        //addAll
        List list2 = new ArrayList();
        list2.add("jack"); list2.add("tom");
        list.addAll(1, list2);
        System.out.println(list);//[smith, jack, tom, huang, mary, mary]

        //get
        System.out.println(list.get(0));//smith

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

        //lastIndexOf
        System.out.println(list.lastIndexOf("mary"));//5

        //remove
        list.remove(0);
        System.out.println(list);//[jack, tom, huang, mary, mary]

        //set
        list.set(1, "黄");
        System.out.println(list);//[jack, 黄, huang, mary, mary]

        //subList
        List returnlist = list.subList(0, 2);
        System.out.println(returnlist);//[jack, 黄]

    }
}
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
/*
    List的三种遍历方式(List接口实现类Vector,LinkedList,Arraylist都适用)
    1.使用iterator
        Iterator iterator = xxx.iterator();
        while(iter.hasNext()){
            Object x = iterator.next();
        }

    2.使用增强for循环
         for(元素类型 元素名:集合名或数组名){
                访问元素
        }

    3.使用普通for
        for(int i=0;i<list.size();i++){
            list.get(i);
        }


 */
public class List02 {
    @SuppressWarnings({"all"})
    public static void main(String[] args) {

        List list = new LinkedList();
        list.add("jack");
        list.add("tom");
        list.add("mary");
        list.add("smith");

        //遍历
        System.out.println("===========使用迭代器==============");
        Iterator iterator = list.iterator();
        while (iterator.hasNext()) {
            Object obj =  iterator.next();
            System.out.println(obj);
        }

        System.out.println("===========使用增强for==============");
        for (Object obj :list) {
            System.out.println(obj);
        }

        System.out.println("===========使用普通for==============");
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }
    }
}
import java.util.ArrayList;

/*
    1.ArrayList可以加入null,且可放多个
    2.ArrayList是由数组来实现数据存储的
    3.ArrayList基本等同于Vector,除了ArrayList是线程不安全(源码没有synchronized)
      在多线程情况下,不建议使用ArrayList

    ArrayList底层结构
    1.ArrayList维护了一个Object类的数组elementData
        transient Object[] elementData  //transient表示该属性不会被序列化
    2.当创建ArrayList对象时,如果使用的是无参构造器,则初始elementDate容量为0
      第1次添加则扩容elementData为10,如再次扩容,则扩容elementData的1.5倍
        0-->10-->15-->22-->...
    3.如果使用的为指定大小的构造器,初始容量为指定大小,如需扩容,则扩容elementData的1.5倍
 */
@SuppressWarnings({"all"})
public class List03 {
    public static void main(String[] args) {
        // 使用无参构造器创建 ArrayList 对象
        ArrayList list = new ArrayList();
        //ArrayList list = new ArrayList(8);
        // 使用 for 给 list 集合添加 1-10 数据
        for (int i = 1; i <= 10; i++) {
            list.add(i);
        }
        //使用 for 给 list 集合添加 11-15 数据
        for (int i = 11; i <= 15; i++) {
            list.add(i);
        }
        list.add(100);
        list.add(200);
        list.add(null);
    }
}

/*
    使用无参构造器部分源码
     public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }
    //创建了一个空的elementData数组

     public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
        //执行list.add,先确定是否要扩容,然后在执行赋值

      private static int calculateCapacity(Object[] elementData, int minCapacity) {
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            return Math.max(DEFAULT_CAPACITY, minCapacity);
        }
        //确定minCapacity,第一次扩容为10

       private void ensureExplicitCapacity(int minCapacity) {
        modCount++;//记录集合被修改的次数
        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);//如果elementData大小不够 就调用grow

        //使用扩容机制来确定要扩容到多大
       private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);//第一次newCapacity=10,第二次以后按照1.5倍扩容
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);//扩容使用Arrays.copyOf()
    }

 */

/*
    使用有参构造器部分源码

    public ArrayList(int initialCapacity) {
        if (initialCapacity > 0) {
            this.elementData = new Object[initialCapacity]; //创建了一个指定大小elementData数组
        } else if (initialCapacity == 0) {
            this.elementData = EMPTY_ELEMENTDATA;
        } else {
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        }
    }
 */
import java.util.Vector;

/*
    Vector底层结构
    1.Vector底层也是一个对象数组,protected Object[] elementData;
    2.Vector是线程同步的,即线程安全,操作方法都带有关键字synchronized
    3.在开发中,需要线程同步安全时,考虑使用Vector

    Vector和ArrayList的比较
                    底层结构            版本          线程安全         扩容倍数
    ArrayList       可变数组            jdk1.2      不安全,效率高     无参默认为10,后按1.5倍
                                                                    有参1.5倍

    Vector          可变数组            jdk1.0      安全,效率不高     无参默认为10,后按2倍
                                                                    有参2倍
 */
public class List04 {
    public static void main(String[] args) {
        //Vector vector= new Vector();
        Vector vector = new Vector(8);
        for (int i = 0; i < 10; i++) {
            vector.add(i);
        }
        vector.add(66);
        System.out.println(vector);
    }
}



/*      部分源码
        //无参默认为10
        public Vector() {
        this(10);

        //有参方法
          public Vector(int initialCapacity) {
        this(initialCapacity, 0);
         }

        //添加数据到Vector
         public synchronized boolean add(E e) {
        modCount++;
        ensureCapacityHelper(elementCount + 1);
        elementData[elementCount++] = e;
        return true;
    }
        //判断是否需要扩容
          private void ensureCapacityHelper(int minCapacity) {
        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }

        //扩容算法
        private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
                                         capacityIncrement : oldCapacity);  //扩容2倍 10+10
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        elementData = Arrays.copyOf(elementData, newCapacity);
    }
 */
/*
    LinkedList
    1.底层实现了双向链表和双端队列特点
    2.可以添加任意元素(元素可以重复),包括null
    3.线程不安全,没有实现同步

    LinkedList底层
    1.底层维护了一个双向链表
    2.维护了两个属性first和last,分别指向首结点和尾结点
    3.每个结点(Node对象)又维护了prev,next,item三个属性
      prev指向前一个,next指向后一个,最终实现双向链表
    4.LinkedList的元素的添加和删除,不是通过数组完成的,效率较高
 */
//  模拟简单的双向链表
public class List05 {
    public static void main(String[] args) {
        Node node1 = new Node("jack");
        Node node2 = new Node("tom");
        Node node3 = new Node("smith");

        //连接三个结点,形成双向链表
        //jack-->tom-->smith
        node1.next = node2;
        node2.next = node3;
        //smith-->tom-->jack
        node3.pre = node2;
        node2.pre = node1;

        Node first = node1;//让first指向node1,即头结点
        Node last = node3;//让last指向node3,即尾结点

        //从头遍历
        while(true){
            if(first == null){
                break;
            }
            System.out.println(first);
            first = first.next;
        }

        System.out.println("===============");
        //从尾遍历
        while(true){
            if(last == null){
                break;
            }
            System.out.println(last);
            last = last.pre;
        }

        //链表添加数据
        Node node = new Node("huang");//创建结点
        //插入到node3前
        node.next = node3;
        node.pre = node2;
        node3.pre = node;
        node2.next = node;

        //重置first,重新指向node1
         first = node1;
        System.out.println("===============");
        //从头遍历
        while(true){
            if(first == null){
                break;
            }
            System.out.println(first);
            first = first.next;
        }

        //重置last,重新指向node3
        last = node3;
        System.out.println("===============");
        //从尾遍历
        while(true){
            if(last == null){
                break;
            }
            System.out.println(last);
            last = last.pre;
        }
    }
}
//  定义一个Node类,表示双向链表的一个结点
class Node{
    public Object item;//存放数据
    public Node next;//指向下一结点
    public Node pre;//指向前一结点
    public Node(Object name){
        this.item = name;
    }
    public String toString(){
        return "name=" + item;
    }
}
import java.util.Iterator;
import java.util.LinkedList;

/*
    LinkedList的增删改查和遍历方式

    ArrayList和LinkedList的比较
                    底层结构            增删效率            改查效率
    ArrayList       可变数组            数组扩容,较低         较高

    LinkedList      双向链表            链表追加,较高         较低

    一般在程序中,大多数是查询,因此大部分情况下使用ArrayList
 */
@SuppressWarnings({"all"})
public class List06 {
    public static void main(String[] args) {
        LinkedList linkedList = new LinkedList();
        //添加结点
        linkedList.add(1);
        linkedList.add(2);
        linkedList.add(3);
        System.out.println("linkedList=" + linkedList);

        //删除结点
        linkedList.remove(); //默认删除的是第一个结点
        //linkedList.remove(2);
        System.out.println("linkedList=" + linkedList);

        //修改某个结点对象
        linkedList.set(1, 999);
        System.out.println("linkedList=" + linkedList);

        //得到某个结点对象
        Object o = linkedList.get(1);
        System.out.println(o);//999

        //LinkedList 实现 List 接口
        System.out.println("====使用迭代器====");
        Iterator iterator = linkedList.iterator();
        while (iterator.hasNext()) {
            Object next = iterator.next();
            System.out.println("next=" + next);
        }

        System.out.println("====使用增强for====");
        for (Object o1 : linkedList) {
            System.out.println("o1=" + o1);
        }

        System.out.println("====使用普通for====");
        for (int i = 0; i < linkedList.size(); i++) {
            System.out.println(linkedList.get(i));
        }
    }
}

/*
    部分源码(增)
    LinkedList linkedList = new LinkedList();
    public LinkedList() {}
    //这时linkedList 的属性 first = null last = null

    public boolean add(E e) {
         linkLast(e);
         return true;
    }
    //执行添加

    void linkLast(E e) {
         final Node<E> l = last;
         final Node<E> newNode = new Node<>(l, e, null);
         last = newNode;
         if (l == null)
                first = newNode;
         else
                l.next = newNode;
         size++;
         modCount++;
      }
      //将新的结点,加入到双向链表的最后
 */

/*
    部分源码(删)
    removeFirst public E remove() {
        return removeFirst();
    }
    //执行removeFirst

    public E removeFirst() {
        final Node<E> f = first;
        if (f == null)
            throw new NoSuchElementException();
        return unlinkFirst(f);
     }
     //执行unlinkFirst

     private E unlinkFirst(Node<E> f) {
          // assert f == first && f != null;
          final E element = f.item;
          final Node<E> next = f.next;
          f.item = null;
          f.next = null; // help GC
          first = next;
          if (next == null)
                last = null;
          else
                next.prev = null;
          size--;
          modCount++;
          return element;
        }
     //执行unlinkFirst, 将 f 指向的双向链表的第一个结点删除
 */

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

nzmzmc

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值