集合-ArrayList

ArrayList

ArrayList的概述

ArrayList是Java中的一个类,实现了List接口,可以动态的增加或者减少元素的大小

ArrayList是一个数组实现的列表,它可以存储不同类型的元素,如整数、字符串、对象等。

ArrayList的容量会根据需要自动增加或减小,因此不需要手动指定大小。

ArrayList还提供了许多有用的方法,如add()、remove()、get()等,可以方便地操作列表中的元素。

  • 底层采用线形结构中的数组结构,
  • 查询数据快(基于数组索引(index)找到对应的元素)
  • 删除,添加速度慢(数组结构,数据在内存中是连续存放的,不管是删除还是添加,之后的数据都会变动)
  • 线程不安全的
  • 可以添加重复数据
  • 长度可修改,可以添加元素和删除元素
  • 随着向ArrayList中不断添加数据,其容量也会自动增加(扩容机制)

创建方式

//向上转型
List list = new ArrayList();
//创建一个容量为10的空列表
ArrayList arrayList = new ArrayList();
//创建一个容量为5的空列表
ArrayList arrayList = new ArrayList(5);

源码分析:

  • 默认的初始容量
private static final int DEFAULT_CAPACITY = 10;
  • 默认的容量空元素数据
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
  • 储存数据的数组
    • transient : 该数组不参加序列化,反序列化
    • 初始化时容量为0
    • 数组中添加1-10个元素时,它的长度扩容到10,如果超出则扩容自生的1.5倍
transient Object[] elementData; 
  • 构造方法

    • 实例化时,构建出一个容量为的列表

      public ArrayList() {
          this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
      }
      
    • 实例化时,构建一个指定容量的空列表

      public ArrayList(int initialCapacity) {
          	//容量大于0时
              if (initialCapacity > 0) {
                  //创建一个指定容量的列表
                  this.elementData = new Object[initialCapacity];
              } else if (initialCapacity == 0) {
                  //容量等于0时创建一个空列表
                  this.elementData = EMPTY_ELEMENTDATA;
              } else {
                  //容量不合法(负数)时,报异常
                  throw new IllegalArgumentException("Illegal Capacity: "+
                                                     initialCapacity);
              }
          }
      
    • 实例化时,构造一个包含指定colledtion的元素列表,

      public ArrayList(Collection<? extends E> c) {
              elementData = c.toArray();
              if ((size = elementData.length) != 0) {
                  // c.toArray(),可能不返回Object[]
                  if (elementData.getClass() != Object[].class)
                      elementData = Arrays.copyOf(elementData, size, Object[].class);
              } else {
                  // 替换为空的列表
                  this.elementData = EMPTY_ELEMENTDATA;
              }
          }
      

ArrayList集合API操作

给List集合添加元素

add():

//将指定的元素添加到此列表的尾部。
public boolean add(E e) {
        ensureCapacityInternal(size + 1);  
    	//将数据添加到数组中的最后一个元素中,同时size长度加一
        elementData[size++] = e;
        return true;
    }

//将指定的元素插入此列表中的指定位置。
public void add(int index, E element) {
    	//校验索引是否合法
        rangeCheckForAdd(index);
    	//长度加一
        ensureCapacityInternal(size + 1);  
    	//数据拷贝
        System.arraycopy(elementData, index, elementData, index + 1,
                         size - index);
    	//将数据赋值到指定索引中
        elementData[index] = element;
        size++;
    }

addAll():

//将一个(collection)容器中所有的元素,添加到此列表的尾端
boolean addAll(Collection<? extends E> c);
//将一个(collection)容器中所有的元素,添加到此列表中指定的位置
boolean addAll(int index, Collection<? extends E> c);
//添加元素	
public    static  void   test2(){		
		List   list = new  ArrayList();
		list.add("admin");
		list.add(10);
		list.add('c');
		list.add(true);
		list.add(2, "guest");
		
		List  List1 = new  ArrayList();
		smallList.add(100);
		smallList.add(1000);
		//添加一个集合
		list.addAll(List1);
		list.addAll(4,List1);
		
		System.out.println(list);
		
}

修改指定元素、获取元素(set 、 get)

set():

//修改指定位置的元素
 public E set(int index, E element) {
     	//校验索引是超出数组长度
        rangeCheck(index);
		//将索引位置的值赋值
        E oldValue = elementData(index);
     	//将索引位置的元素重新赋值
        elementData[index] = element;
        return oldValue;
    }

get():

//获取指定元素的值
public E get(int index) {
   		 //校验索引是超出数组长度
        rangeCheck(index);
		//返回当前索引的值
        return elementData(index);
    }
	public    static  void   test3(){
		List   list = new  ArrayList();
		list.add(1);
		list.add(2);
		list.add(3);
		System.out.println(list);
		//修改指定的元素
		list.set(1, "X");
		System.out.println(list);
        //通过下标获取元素
		Object obj = list.get(1);
		System.out.println(obj);
	}

List容器中的包含的值与搜索值

contains():

//查找是否包含某个元素
public boolean contains(Object o) {	
        return indexOf(o) >= 0;
    }
  • containsAll ()
//检索集合中的数据是否包含另一个集合的元素
boolean containsAll(Collection<?> c);
  • indexOf ()
//返回数据相应的索引
int indexOf(Object o);
  • lastIndexOf()
//返回数据相应的索引从最后检索
int lastIndexOf(Object o);
//List容器中的包含与索引
	public    static  void   test4(){
		List   list = new  ArrayList();
		list.add(1);
		list.add(2);
		list.add(3);
		
		//检查是否包含某个元素
		boolean is = list.contains(12);
		System.out.println(is);
		
		List  smallList = new  ArrayList();
		smallList.add('a');
		smallList.add('b');
		
		
		list.addAll(smallList);
		
		//检查是否包含某个指定的集合
		is = list.containsAll(smallList);
		System.out.println(is);
	
		System.out.println(list);
		
		//搜索指定的元素,返回下标(没有则返回-1)
		int  index = list.indexOf('x');
		System.out.println(index);
		
		//反向搜索
		index = list.lastIndexOf('a');
		
	}

容器迭代器的使用

  • 所谓的迭代器,就是获取容器中的元素的一种方式而已;

  • iterator ():

//返回按适当顺序在列表的元素上进行迭代的迭代器。     
Iterator<E> iterator();
  • listIterator():
//返回列表中元素的列表迭代器(按适当顺序),从列表的指定位置开始。
ListIterator<E> listIterator();
// 使用迭代器来获取元素
    public static void main(String[] args) {
        List list = new ArrayList();
        list.add(1);
        list.add(2);
        list.add(3);


        //list容器有着自己专属的迭代器
        ListIterator listIterator = list.listIterator();
        //System.out.println(listIterator.hasNext());//判断是否存在数据
        //System.out.println(listIterator.previous());//判断是否存在数据

       //从迭代器中获取数据获取值
        while (listIterator.hasNext()){
            System.out.println(listIterator.next());
        }

        //当前指针指向最后数据“3”,从后往前遍历数据
        while (listIterator.hasPrevious()){
            System.out.println(listIterator.previous());
       }

}

集合容器提供一个专有的迭代器,针对集合数据进行提取

List集合同时还有自己专属的一个迭代器,处理起来比较灵活。

List容器中元素的移除(remove 、removeAll)

  • remove ():
//根据索引删除元素
public E remove(int index) {
        rangeCheck(index);

        modCount++;
        E oldValue = elementData(index);
		//获取要删除的index
        int numMoved = size - index - 1;
        if (numMoved > 0)
            //数据拷贝
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
    	//长度递减,当前索引位置的元素赋null值
        elementData[--size] = null; 

        return oldValue;
    }
  • removeAll():
//从列表中移除指定 collection(容器)的值 中包含的其所有元素(可选操作)。     
boolean removeAll(Collection<?> c);
public class Demo3 {

	private static List list = new ArrayList();

	private static List smallList = new ArrayList();

	static {
		list.add("a");
		list.add("b");
		list.add("c");
		list.add("d");

		smallList.add(1);
		smallList.add(2);
		smallList.add(3);

		list.addAll(smallList);

	}

	public static void main(String[] args) {
		test1();
	}

	// 元素的移除
	public static void test1() {
		System.out.println(list);
		// 通过下标移除元素-----得到的是移除的元素本身
		/*
		 * Object obj = list.remove(1);
		 *  System.out.println(list);
		 * System.out.println(obj);
		 */

		// 通过指定的元素进行移除
		/*
		 * boolean is = list.remove("b"); System.out.println(is);
		 * System.out.println(list);
		 */
		/*boolean is = list.remove(new Integer("1"));  //复合引用类型的Integer代表的是移除指定的元素,而不是下标,下标是一个int类型的值;
		System.out.println(is);
		System.out.println(list);*/
		
		//移除指定的容器
		boolean is = list.removeAll(smallList);
		System.out.println(is);
		System.out.println(list);
		
	}

如何在List容器中删除自定义的对象元素

package com.it.www.beans;

public class Person extends Object{

    private String name;
    private Integer age;

    public Person(){

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

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

    public Integer getAge() {
        return age;
    }

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

    @Override
    public boolean equals(Object o) {
        if (o instanceof Person){//参数对象比较Person类,对象运算符,一个类是否属于另一个类,包含子类
            //将父类转换为子类(向下转型)
            Person person = (Person) o;
            if (this.name.equals(person.name) && this.age == person.age){
                return true;
            }
        }
        return false;

    }

    @Override
    public String toString() {
        return name+","+age;
    }
}

	public class MethodGeneric {
    private static List list = new ArrayList();
    private static List list1 = new ArrayList();

    public static void main(String[] args) {
        System.out.println(list);


    }
    //静太代码块的作用:随着类的加载进行加载
    static{
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);

        list1.add("a");
        list1.add("b");
        list1.add("c");
        list1.add("d");

        list.addAll(list1);//1234abcd
        list.add(new Person("张三", 18));
        list.add(new Person("李四",19));
    }

}

以下这几个方法,大家自己学习一下:

  • retainAll()
//保留指定集合的所有元素
boolean retainAll(Collection<?> c);
  • subList()
//截取集合中的元素
List<E> subList(int fromIndex, int toIndex);
  • toArray()
//将集合转为数组
Object[] toArray();
  • isEmpty()
//检查集合是否为null,为null返回ture,相反为false
boolean isEmpty();

clear:

//清除所有数据
 public void clear() {
     	//修改次数递增
        modCount++;

        //循环将所有元素赋null值
        for (int i = 0; i < size; i++)
            elementData[i] = null;
	    //长度赋0值
        size = 0;
    }

扩容机制

ArrayList的扩容机制是在添加元素时,判断当前元素个数是否已经达到了数组容量,如果达到了就会进行扩容操作

扩容操作会创建一个新的数组,将原数组中的元素复制到新数组中,同时将新元素添加到新数组中

扩容的大小通常是原数组容量的一半,即增加原来的50%

下面是 ArrayList 中的扩容方法 ensureCapacityInternal 的源码实现

//该方法保证ArrayList有足够的容量保证一定数量的元素
//当ArrayList中的数据数量超过当前的容量,就需要调整他的大小
private void ensureCapacityInternal(int minCapacity) {
    //检查该数组是否为默认的空数组,
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
        //如果是该方法将最小的容量设置为默认容量或者指定最小容量,以最大容量为主
        minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
    }
    //然后调用ensureExplicitCapacity使用最小容量
    ensureExplicitCapacity(minCapacity);
}


private void ensureExplicitCapacity(int minCapacity) {
    //记录ArrayList的修改次数
    modCount++;

    //检查最小容量是否大于elementData数组的当前容量
    if (minCapacity - elementData.length > 0) {
        //条件满足调用grow方法来增加ArrayList的容量
        grow(minCapacity);
    }
}


private void grow(int minCapacity) {
    //当前的数组长度赋值给变量
    int oldCapacity = elementData.length;
    //将当前的容量加到当前容量的一半来计算ArrayList的新容量
    int newCapacity = oldCapacity + (oldCapacity >> 1);
    //如果新的容量依旧小于最小容量,则使用最小容量,
    if (newCapacity - minCapacity < 0) {
        newCapacity = minCapacity;
    }
    //如果新的容量超过最大数组容量,
    if (newCapacity - MAX_ARRAY_SIZE > 0) {
        //调用hugeCapacity(计算可能的最大容量)
        newCapacity = hugeCapacity(minCapacity);
    }
    //最后将数组的新的长度复制给新的容器
    elementData = Arrays.copyOf(elementData, newCapacity);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

陆卿之

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

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

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

打赏作者

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

抵扣说明:

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

余额充值