java--ArrayList

ArrayList

1.ArrayList简介

在集合框架中,ArrayList是一个普通的类,实现了List接口,具体框架图如下:
在这里插入图片描述
【说明】

  1. ArrayList是以泛型方式实现的,使用时必须要先实例化
  2. ArrayList实现了RandomAccess接口,表明ArrayList支持随机访问
  3. ArrayList实现了Cloneable接口,表明ArrayList是可以clone的
  4. ArrayList实现了Serializable接口,表明ArrayList是支持序列化的
  5. 和Vector不同,ArrayList不是线程安全的,在单线程下可以使用,在多线程中可以选择Vector或者CopyOnWriteArrayList
  6. ArrayList底层是一段连续的空间,并且可以动态扩容,是一个动态类型的顺序

2.ArrayList构造

1.无参构造

public static void main(String[] args)
    {
        List<String> list=new ArrayList<>();//调用了不带参数的构造方法
        list.add("hello");
        //总结:当调用不带参数的构造方法的时候,底层的数组长度为0,但是当我第一次add的时候
        //才会为我分配内存,此时第一次分配的内存为10
        //扩容的方法(grwo),每次1.5倍扩容

    }

2.利用其他Collection构建ArrayList

 	 public static void main(String[] args)
    {
        ArrayList<String> arrayList1=new ArrayList<>();
        arrayList1.add("abc");
        arrayList1.add("def");
        List<String> list1=new ArrayList<>(arrayList1);

        ArrayList<Integer> arrayList2=new ArrayList<>();
        List<String> list2=new ArrayList<>(arrayList2);

    }

在这里插入图片描述
list2会出错
原因是
ArrayList底层的构造方法是这样的

在这里插入图片描述
上面这段代码结合图片来看,list1传入的arrlist1的类型是String,跟List的类型一样,符合
arrlist2的类型是Integer,不符合,所以报错
这里的String,Integer相当于E
在这里插入图片描述

class Person
{

}
class Student extends Person
{

}
 public static void main(String[] args)
    {
        ArrayList<Student> arrayList1=new ArrayList<>();
        List<Person> list=new ArrayList<>(arrayList1);

    }

arrayList1的类型是Student,传入list1里面,list1的类型是Person,而arrayList1的Student类型是Person的子类,所以不会报错

3.ArrayList常见操作

ArrayList虽然提供的方法比较多,但是常用方法如下所示,需要用到其他方法时,同学们自行查看ArrayList的帮助文档。
在这里插入图片描述
这里拿几个举例
1.addAll

    public static void main(String[] args) {
        ArrayList<String> arrayList=new ArrayList<>();
        arrayList.add("abc");
        arrayList.add("def");
        arrayList.add("wwww");
        List<String> list=new ArrayList<>();//向上转型
        //List是ArrayList的父类,所以list可以调用add和addALL
        list.add("hello");
        list.addAll(arrayList);
        System.out.println(list.toString());
    }

在这里插入图片描述
2.remove

		String ret=list.remove(0);
        System.out.println(list.toString());

在这里插入图片描述

 		boolean ret2=list.remove("abc");//删除成功就是true,否则false
        System.out.println(list.toString());

在这里插入图片描述
3.clear
数组长度变为0了
在这里插入图片描述

在这里插入图片描述
4.subList

	public static void main(String[] args)
    {
        ArrayList<String> arrayList=new ArrayList<>();
        arrayList.add("abc");
        arrayList.add("def");
        arrayList.add("wwww");
        arrayList.add("qaaaaaaa");
        arrayList.add("ddddddddddd");
        List<String> ret = arrayList.subList(1,3);//左闭右开
        System.out.println(ret.toString());

    }

在这里插入图片描述
如果我们把ret的0下标修改,会不会影响arrayList的呢?

		ret.set(0,"xiaobai");
        System.out.println(ret.toString());
        System.out.println(arrayList.toString());

在这里插入图片描述
答案是会,修改ret的0下标相当于修改arrayList的1下标
也就是说,截取的是原来的地址,拿到的是原来的地址,所以修改也会影响原变量

4.ArrayList的遍历

1.直接输出

    public static void main(String[] args)
    {
        ArrayList<String> arrayList=new ArrayList<>();
        //ArrayList的父类的父类重写了toString方法
        arrayList.add("abc");
        arrayList.add("def");
        arrayList.add("wwww");
        arrayList.add("qaaaaaaa");
        arrayList.add("ddddddddddd");
        System.out.println(arrayList.toString());
        System.out.println("--------------------------------------");
        System.out.println(arrayList);

    }

在这里插入图片描述
2.根据下标遍历

		for (int i = 0; i < arrayList.size(); i++)
        {
            System.out.print(arrayList.get(i)+" ");
        }
        System.out.println();

3.foreach

//冒号的右边是你要传入的集合,冒号的左边是集合当中所定义的类型的变量
//拿到一个类型放到x里面然后打印
		for(String x:arrayList)
        {
            System.out.print(x+" ");
        }

4.迭代器
it指的是集合第一个元素的前一个位置

		Iterator<String> it=arrayList.listIterator();
        while(it.hasNext())//如果下一个有,走到下一个
        {
            System.out.print(it.next()+" ");//打印
        }
        System.out.println();

5.ArrayList的扩容机制

获取旧的空间大小,按照旧的空间的1.5倍来扩容的
如果用户所需扩容大小超过1.5倍,按照用户所需大小扩容

6.ArrayList相关题

1.CVTE面试题在这里插入图片描述

   public static void func(String str1,String str2)
    {
        List<Character> list=new ArrayList<>();
        for(int i=0;i<str1.length();i++)
        {
            char ch=str1.charAt(i);
            if(!str2.contains(ch+""))
            {
                list.add(ch);
            }
        }
        for(int i=0;i<list.size();i++)
        {
            System.out.print(list.get(i));
        }
        System.out.println();
    }
    public static void main(String[] args) {
        func("welcome to bit","come");
    }

2.扑克牌

创建两个类
在这里插入图片描述
card类代码

public class Card
{
    private String suit;//花色
    private int rank;//数字

    public Card(String suit, int rank)
    {
        this.suit = suit;
        this.rank = rank;
    }

    public String getSuit()
    {
        return suit;
    }

    public void setSuit(String suit)
    {
        this.suit = suit;
    }

    public int getRank()
    {
        return rank;
    }

    public void setRank(int rank)
    {
        this.rank = rank;
    }

    @Override
    public String toString()
    {
        return suit+rank;
    }
}

Test类代码

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class Test
{
    private static final String[] SUITS={"♥","♠","♣","♦"};
    public static List<Card> buyCard()//买牌
    {
        List<Card> cards=new ArrayList<>();
        for(int i=0;i<SUITS.length;i++)
        {
            for(int j=1;j<=13;j++)
            {
                Card card=new Card(SUITS[i],j);
                cards.add(card);
            }
        }
        return cards;
    }
    //如果我们要玩斗地主扎金花等游戏,牌的顺序这么齐肯定是不行的
    //所以我们要进行洗牌
    public static void shuffle(List<Card> cards)//洗牌
    {
        Random random=new Random();
        for(int i= cards.size()-1;i>0;i--)
        {
            int j= random.nextInt(i);
            Card tmp=cards.get(i);
            cards.set(i,cards.get(j));
            cards.set(j,tmp);

        }
    }
    public static void main(String[] args)
    {
        List<Card> cards=buyCard();
        System.out.println("牌到手了:");
        System.out.println(cards);
        System.out.println("---------------------------");
        System.out.println("洗牌:");
        shuffle(cards);
        System.out.println(cards);


        //有三个人,轮流揭牌五张
        List<Card> hand1=new ArrayList<>();
        List<Card> hand2=new ArrayList<>();
        List<Card> hand3=new ArrayList<>();

        List<List<Card>> hand=new ArrayList<>();
        //hand的每个元素都是List,而List的每个元素都是Card,相当于一个二维数组

        hand.add(hand1);
        hand.add(hand2);
        hand.add(hand3);

        //每个人拿一张牌
        for(int i=0;i<5;i++)
        {
            for(int j=0;j<3;j++)
            {
                Card card=cards.remove(0);//揭牌
                hand.get(j).add(card);//把card这张牌放到j这个人的手上
            }
        }
        System.out.println("第一个人的牌:");
        System.out.println(hand1);
        System.out.println("---------------------------");

        System.out.println("第二个人的牌:");
        System.out.println(hand2);
        System.out.println("---------------------------");

        System.out.println("第三个人的牌:");
        System.out.println(hand3);
        System.out.println("---------------------------");

        System.out.println("剩下的牌");
        System.out.println(cards);
    }
}

揭牌示例图
在这里插入图片描述
在这里插入图片描述

3.杨辉三角

杨辉三角leetcode链接
在这里插入图片描述

6. ArrayList的问题及思考

在这里插入图片描述
在这里插入图片描述

  1. ArrayList底层使用连续的空间,任意位置插入或删除元素时,需要将该位置后序元素整体往前或者往后搬
    移,故时间复杂度为O(N)
  2. 增容需要申请新空间,拷贝数据,释放旧空间。会有不小的消耗。
  3. 增容一般是呈2倍的增长,势必会有一定的空间浪费。例如当前容量为100,满了以后增容到200,我们再继
    续插入了5个数据,后面没有数据插入了,那么就浪费了95个数据空间。
    思考: 如何解决以上问题呢?
    也就是我的下一篇博客–链表!
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: ArrayListJava中的一个类,它可以动态地存储一组元素,可以根据需要动态增加或减少元素的数量,是一种非常方便的数据结构。 ArrayList的基本用法包括创建ArrayList对象、添加元素、获取元素、修改元素、删除元素等。首先,可以使用如下代码创建一个空的ArrayList对象: ```java ArrayList<String> list = new ArrayList<String>(); ``` 上面代码创建了一个类型为String的ArrayList对象,该对象初始为空。然后,可以使用add()方法向ArrayList中添加元素,例如: ```java list.add("apple"); list.add("banana"); list.add("orange"); ``` 上述代码向list中添加了三个字符串元素。可以使用get()方法获取ArrayList中的元素,例如: ```java String first = list.get(0); // 获取第一个元素 ``` 可以使用set()方法修改ArrayList中的元素,例如: ```java list.set(1, "pear"); // 将第2个元素改为"pear" ``` 可以使用remove()方法删除ArrayList中的元素,例如: ```java list.remove(2); // 删除第3个元素 ``` 以上就是ArrayList的基本用法。需要注意的是,ArrayList中的索引从0开始。 ### 回答2: ArrayListJava中非常常用的数据结构。它提供了一个可以动态添加、删除、修改的可变长度的序列。 使用ArrayList时,首先需要引入它的包:java.util。然后可以使用如下语法创建一个ArrayList对象: ```java ArrayList<String> list = new ArrayList<String>(); ``` 这里的`<String>`说明了这个ArrayList中的元素类型是String。当然,也可以使用其他类型作为元素类型。例如: ```java ArrayList<Integer> numbers = new ArrayList<Integer>(); ArrayList<Double> prices = new ArrayList<Double>(); ``` 可以使用`add()`方法来向ArrayList中添加元素: ```java list.add("apple"); list.add("orange"); list.add("banana"); ``` 可以使用`get()`方法来获取指定位置的元素: ```java String fruit = list.get(1); //获取第二个元素,即"orange" ``` 可以使用`size()`方法来获取ArrayList中元素的个数: ```java int size = list.size(); //获取ArrayList中元素的个数 ``` 可以使用`set()`方法来修改指定位置的元素: ```java list.set(1, "pear"); //将第二个元素修改为"pear" ``` 可以使用`remove()`方法来删除指定位置的元素: ```java list.remove(2); //删除第三个元素,即"banana" ``` 需要注意的是,ArrayList中的元素是有序的,且可以重复。因此,可以使用循环来遍历ArrayList中的元素: ```java for(int i=0; i<list.size(); i++){ String fruit = list.get(i); System.out.println(fruit); } ``` 或者使用增强型循环(foreach): ```java for(String fruit : list){ System.out.println(fruit); } ``` 总之,使用ArrayList可以方便地处理可变长度的序列。在实际开发中,它有着广泛的应用场景,例如处理文件或数据库中的数据,实现算法或数据结构等。 ### 回答3: ArrayListJava中一个非常常用的容器类。他的优点是可以存储任意类型的对象,可以动态扩容,因此在使用上非常的方便。 使用ArrayList需要在代码中首先调用import java.util.ArrayList进行导入,随后可以通过ArrayList<类型> name = new ArrayList<类型>()这个语句声明一个ArrayList,并将其命名为name,同时指定ArrayList中存储的对象类型为类型。当我们需要添加元素时,可以通过name.add(element)将元素添加到ArrayList中。我们也可以通过name.get(index)方法获取ArrayList中指定位置的元素,通过name.set(index,value)方法将ArrayList中某个位置的元素替换为新的元素。同时,我们也可以调用name.size()方法获取ArrayList中元素的数量。 值得注意的是,ArrayList中的元素是以索引的方式存储的,这意味着我们可以根据元素的位置进行添加、修改、删除等操作。而且,由于ArrayList的容量是可变的,因此其内部必须动态地管理数据的内存,这会影响到ArrayList的性能。当然,这个影响是很小的,不会对代码的运行产生显著的影响。 总之,ArrayListJava中非常常用的容器类,其可以存储任意类型的对象,同时调用也非常方便。但在使用时需要注意其操作的复杂度,以及不能存储基本数据类型。如果需要在ArrayList中存储基本数据类型,需要借助Boxing和Unboxing机制将其转换为对应的包装类。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值