19_JavaSE_ArrayList类

Posted Jack·Kwok

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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);

    



[Dogid=1, name='dd', Dogid=2, name='bb', Dogid=4, name='aa', Dogid=5, name='ee', Dogid=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);

    



[Dogid=6, name='cc', Dogid=5, name='ee', Dogid=4, name='aa', Dogid=2, name='bb', Dogid=1, name='dd']

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

以上是关于19_JavaSE_ArrayList类的主要内容,如果未能解决你的问题,请参考以下文章

数据结构(04)_数组类的实现

c ++初始化类的char数组成员

在 C++ 中的类构造函数中初始化结构数组

Widget的类变量和构造函数中初始化数组的区别?

[19/03/16-星期六] 常用类_Date时间类&DateFormat类

数组_指针_字符串