集合引入和ArrayList

本文详细介绍了Java集合框架中的ArrayList,包括其特点、优缺点、使用场景和与数组的区别。通过示例展示了如何创建、添加、删除、修改ArrayList中的元素,并探讨了ArrayList的扩容机制。此外,还讨论了泛型在ArrayList中的应用,以提高代码的安全性和便捷性。
摘要由CSDN通过智能技术生成

引入集合

集合和数组的比较
集合的使用场合:

举例:新闻列表、就业喜报、就业明星、邮件列表、购物车;当我们需要将一些相同结构的个体整合在一起时,就可以考虑使用集合了 。
在这里插入图片描述
为什么使用集合而不是数组?
集合和数组的相似点:都可以存储多个对象,对外都作为一个整体存在。
数组的缺点:

  • 长度必须在初始化时指定,且固定不变。
  • 数组采用连续存储空间,删除和添加效率低下。
  • 数组无法直接保存映射关系。
  • 数组缺乏封装,操作繁琐。
集合框架

Java集合框架提供了一套性能优良、使用方便的接口和类,它们位于java.util包中。存放在集合中的数据,被称为元素。
在这里插入图片描述在这里插入图片描述集合架构

  • Collection接口存储一组不唯一、无序的对象。
  • List接口存储一组不唯一,有序(索引顺序)的对象。
  • Set接口存储一组唯一、无序的对象。
  • Map接口存储一组键值对象,提供key到value的映射:
    key:唯一、无序。
    value:不唯一、无序。

List的主要实现类

  • List
    特点:有序、不唯一(可重复)。
  • ArrayList
    1.在内存中分配连续的空间,实现了长度可变的数组。
    2.优点:遍历元素和随机访问元素的效率较高。
    3.缺点:添加和删除需要大量移动元素,按照内容查询效率低。
  • LinkedList
    1.采用双向链表的存储方式。
    2.缺点:遍历元素和随机访问元素的效率较低。
    3.优点:插入、删除元素效率比较高(但是前提也是必须先低效率查询才可。如果插入删除发生在头尾可以减少查询次数)。
    在这里插入图片描述ArrayList
    示例1:使用ArrayList存储多个学生的分数:
package com.bjsxt.list;

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

public class TestArrayList1 {
    public static void main(String[] args) {
        //1.创建一个ArrayList对象,用来存储多个分数
        ArrayList<Integer> list = new ArrayList();

        //2.向ArrayList中添加分数
        list.add(99);
        list.add(92);
        list.add(56);
        list.add(89);
        list.add(90);


        //3.输出集合中有多少对象
        System.out.println(list.size());

        System.out.println(list);//[99, 92, 56, 89, 90]
        System.out.println(list.toString());//[99, 92, 56, 89, 90]

//        System.out.println(list.toArray());
//        System.out.println(list.stream().toArray());

        //4.在集合指定位置添加分数
        list.add(2,88);

        //5.删除指定位置的对象
        list.remove(1);

        System.out.println(list);

        //普通for循环
        System.out.println("---------------遍历1-----------------");
        for (int i = 0; i < list.size(); i++) {
            int elem = (int) list.get(i);
            System.out.println(elem);
        }
        //使用增强for循环
        System.out.println("---------------遍历2-----------------");
        for (Object elem:list
             ) {
            Integer i=(Integer) elem;
            System.out.println(i);
        }
        //使用iterator迭代器
        System.out.println("---------------遍历3-----------------");
        Iterator iterator=list.iterator();
        while (iterator.hasNext()) {
            int elem= (int) iterator.next();
            System.out.println(elem);
        }
    }
}

示例2:使用泛型保证集合操作的安全和简便

package com.bjsxt.list;

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

/*
在集合中使用泛型

目前代码的缺点:
1.不安全     list.add("zhang");
2.繁琐,需要强制类型转换       int elem = (int) list.get(i);

解决:泛型
1.安全
2.不需要强制类型转换
3.JDK1.5提供
 */
public class TestArrayList2 {
    public static void main(String[] args) {
        //1.创建一个ArrayList对象,用来存储多个分数
        ArrayList<Integer> list = new ArrayList<Integer>();

        //2.向ArrayList中添加分数
        list.add(99);
        list.add(92);
        list.add(56);
        list.add(89);
        list.add(90);

//        list.add("zhang");



        //3.输出集合中有多少对象
        System.out.println(list.size());

        System.out.println(list);//[99, 92, 56, 89, 90]
        System.out.println(list.toString());//[99, 92, 56, 89, 90]

//        System.out.println(list.toArray());
//        System.out.println(list.stream().toArray());

        //4.在集合指定位置添加分数
        list.add(2,88);

        //5.删除指定位置的对象
        list.remove(1);

        System.out.println(list);

        //普通for循环
        System.out.println("---------------遍历1-----------------");
        for (int i = 0; i < list.size(); i++) {
            int elem = list.get(i);
            System.out.println(elem);
        }
        //使用增强for循环
        System.out.println("---------------遍历2-----------------");
        for (int elem:list
        ) {
            Integer i=(Integer) elem;
            System.out.println(i);
        }
        //使用iterator迭代器
        System.out.println("---------------遍历3-----------------");
        Iterator iterator=list.iterator();
        while (iterator.hasNext()) {
            int elem= (int) iterator.next();
            System.out.println(elem);
        }
    }
}

示例3:ArrayList的更多方法

package com.bjsxt.list;

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

/*
ArrayList的其他方法:
添加
list.add();
list.addAll(list2);  将list2中的所有元素添加到list的结尾
list.addAll(1,list2);  将list2中的所有元素添加到list的指定位置。

删除
list.remove(new Integer(99));   按内容删除
list.remove(1);     按索引删除
list.removeAll(list2);  删除list中与list2的公共元素
list.retainAll(list2);  保留list和list2的公共元素
list.clear();   清空

修改
list.set(1, 50);

查询
list.contains(92)
 */
public class TestArrayList3 {
    public static void main(String[] args) {
        //1.创建一个ArrayList对象,用来存储多个分数
        ArrayList<Integer> list = new ArrayList<Integer>();
        ArrayList<Integer> list1 = new ArrayList<Integer>();

        list1.add(33);
        list1.add(77);
        list.addAll(list1);

        //2.向ArrayList中添加分数
        list.add(99);
        list.add(92);
        list.add(56);
        list.add(89);
        list.add(90);

//        list.add("zhang");

        //3.删除
        list.remove(new Integer(99));//按内容删除
        list.remove(1);//按索引删除
//        list.clear();   //清空

        //4.修改
        list.set(1, 50);


        //3.输出集合中有多少对象
        System.out.println(list.size());

        System.out.println(list);//[99, 92, 56, 89, 90]
        System.out.println(list.toString());//[99, 92, 56, 89, 90]

//        System.out.println(list.toArray());
//        System.out.println(list.stream().toArray());

        System.out.println(list.contains(92));
        System.out.println(list.isEmpty());
    }
}

理解ArrayList的源码

  • ArrayList底层是一个长度可以动态增长的Object数组(StringBuilder底层是一个长度可以动态增长的char数组);
public class ArrayList<E> extends AbstractList<E> implements 
List<E>, RandomAccess, Cloneable, Serializable{
       private static final int DEFAULT_CAPACITY = 10;
       private static final Object[] EMPTY_ELEMENTDATA = {};
        private static final Object[]  
DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
       transient Object[] elementData;
       private int size;
}
  • 接口是可以一个方法也不提供的,比如 RandomAccess, Cloneable, java.io.Serializable。

  • JDK1.7中,使用无参数构造方法创建ArrayList对象时,默认底层数组长度是10。JDK1.8中,使用无参数构造方法创建ArrayList对象时,默认底层数组长度是0;第一次添加元素,容量不足就要进行扩容了。

public ArrayList() {
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
private static int calculateCapacity(Object[] elementData, int minCapacity) {
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
        return Math.max(DEFAULT_CAPACITY, minCapacity);
    }
    return minCapacity;
}
  • 容量不足时进行扩容,默认扩容50%。如果扩容50%还不足容纳新增元素,就扩容为能容纳新增元素的最小数量。
private void grow(int minCapacity) {
    int oldCapacity = elementData.length;
    //右移一位相当于除2
    int newCapacity = oldCapacity + (oldCapacity >> 1);
    if (newCapacity - minCapacity < 0)
        newCapacity = minCapacity;
    if (newCapacity - MAX_ARRAY_SIZE > 0)
        newCapacity = hugeCapacity(minCapacity); 
    elementData = Arrays.copyOf(elementData, newCapacity);
}
  • ArrayList中提供了一个内部类Itr,实现了Iterator接口,实现对集合元素的遍历。
public Iterator<E> iterator() {
    return new Itr();
}
private class Itr implements Iterator<E> {
}	
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值