19_JavaSE_ArrayList类

1. ArrayList 的简介

我们前面学到了数组的概念,也知道像数组这种“元素的集合”的概念在程序开发中的重要性,但是我们发现数组有很多自身的弊端。其中,最明显地就是初始化数组时必须指定数组的长度。这个特点有时候很限制我们程序的拓展性能。那么,应该怎么解决呢?

最完美的解决方法莫过于将其功能设计成一个类。我们知道,在 Java 中,万物皆可以被设计成类。曾经我们也因为基本数据类型的弊端,将其设计成对应的包装类,那么,我们也可以设计一个类,类的内部维护一个数组,对外提供增删改查等方法。

这个思路看起来很不错,那关于“数组初始化时需要指定大小”这个问题,又是怎么解决的呢?其实,道理不难,只需要我们在内部初始化时,给数组一个常数的长度,接着当我们添加数据时,内部触发一个判断数组是否满了的判断,满了则实现“扩容”,扩容的机制实际上是:创建一个新数组,长度为原数组的若干倍,然后将旧数组的内容赋值给新数组,再将旧数组的应用指向新数组。

解决完了这些问题,还有一个问题:数组初始化时是可以指定其存放的类型的(包括引用数据类型和基本类型,或数组类型),设计成类时则是通过“泛型”的概念来实现这一功能(当然,因为面向对象的特点,泛型的类型只能是引用数据类型)。

2. 初始化

初始化 ArrayList (实际上只是类的初始化过程,只是加上了泛型):

ArrayList<E> al =new ArrayList<>();
  • E : 泛型。指定 al 中存储的类型的引用,例如:String、Integer 等等。

3. 常见方法

add() 添加元素
clear() 删除 ArrayList 中所有元素
contains() 判断元素是否属于该 ArrayList
get() 根据索引获取 ArrayList 中的元素
remove() 删除指定索引的元素
size() 获取 ArrayList 的元素个数
isEmpty() 判断 ArrayList 是否为空
set() 修改 ArrayList 中指定索引的值
toArray() 转换为数组
toString() 转化为字符串
可以使用传统 for 来迭代元素,也可以使用增强 for (for-each)来迭代

4. 排序

一般排序 ArrayList 中的元素的方法是:使用Collections工具类的静态方法sort()来实现排序。sort() 方法传入两个参数,一个是可排序的对象,一个是 Comparator 接口。具体例子如下:

1、正序排序。list 中存储着 Integer 的值。

public class Test {
    public static void main(String[] arg){
        List<Integer> list = new ArrayList<>();
        list.add(234);
        list.add(4);
        list.add(46);
        list.add(345);
        list.add(3);
        Collections.sort(list);
        System.out.println(list);
    }
}
[3, 4, 46, 234, 345]

2、倒序排序。list 中存储着 Integer 的值。

public static void main(String[] arg){
        List<Integer> list = new ArrayList<>();
        list.add(234);
        list.add(4);
        list.add(46);
        list.add(345);
        list.add(3);
        Collections.sort(list, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2-o1;
            }
        });
        System.out.println(list);

    }
[345, 234, 46, 4, 3]

3、设计一个 Dog 类。正序。

public class Dog {
    public Integer id;
    public String name;

    public Dog(Integer id, String name) {
        this.id = id;
        this.name = name;
    }
    @Override
    public String toString() {
        return "Dog{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}
public class Test {
    public static void main(String[] arg){
        List<Dog> list = new ArrayList<>();
        list.add(new Dog(4,"aa"));
        list.add(new Dog(2,"bb"));
        list.add(new Dog(6,"cc"));
        list.add(new Dog(1,"dd"));
        list.add(new Dog(5,"ee"));
        Collections.sort(list, new Comparator<Dog>() {
            @Override
            public int compare(Dog o1, Dog o2) {
                return o1.id - o2.id;
            }
        });
        System.out.println(list);

    }

}

[Dog{id=1, name='dd'}, Dog{id=2, name='bb'}, Dog{id=4, name='aa'}, Dog{id=5, name='ee'}, Dog{id=6, name='cc'}]

4、设计一个 Dog 类,倒序。

public class Test {
    public static void main(String[] arg){
        List<Dog> list = new ArrayList<>();
        list.add(new Dog(4,"aa"));
        list.add(new Dog(2,"bb"));
        list.add(new Dog(6,"cc"));
        list.add(new Dog(1,"dd"));
        list.add(new Dog(5,"ee"));
        Collections.sort(list, new Comparator<Dog>() {
            @Override
            public int compare(Dog o1, Dog o2) {
                return o2.id - o1.id;
            }
        });
        System.out.println(list);

    }

}

[Dog{id=6, name='cc'}, Dog{id=5, name='ee'}, Dog{id=4, name='aa'}, Dog{id=2, name='bb'}, Dog{id=1, name='dd'}]

从上面例子我们可以看出:
如果存储的类型的内部是已经实现 Comparable 接口的话(例如:Integer、String 等等),对于正序的情况,可以直接不传入 Comparable 接口,也可以传入该接口后实现其方法,返回 参数 1 - 参数 2;对于逆序的情况,需要传入该接口后实现其方法,返回 参数 1 - 参数 2。当然,你也可以有其他的实现策略。
如果存储的类型内部没有实现 Comparable 接口的话(例如自己写的类,如上面的 Dog 类等等),对于正序排序和逆序排序都需要传入 Comparable 接口并实现该接口的方法,如果是要正序,则是用 参数 1 的操作结果 - 参数 2 的操作结果;如果是倒序,则是用 参数 2 的操作结果 - 参数 1 的操作结果。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

执章学长

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

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

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

打赏作者

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

抵扣说明:

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

余额充值