接上两篇博文《数组(一)——普通数组》;《数组——ArrayList与LinkedList》;
在前面讲述的数组是编程中常见的数据结构,使用率非常高。但是,数组也是有缺陷的。比如,数组的大小必须事先定义,而且过程中不能改变。
C语音中也有类似情况,那时的解决方案是“链表”。但链表也有其不便之处,比如,编程复杂、不支持“随机定位”等。
Java为解决上述问题,提供了两个高度封装的类:ArrayList和LinkedList。这两个类都是数组,只是实现原理不同。
ArrayList内部使用的是“动态数组”,而LinkedList内部使用的是“链表”。
ArrayList:
ArrayList是泛型类,可以存储任意指定类型数据。
ArrayList最大的好处就是“动态”,使用时可以不必关心数组空间的大小。因为ArrayList可以根据实际存储的数据来调整数组空间的大小。
我们在访问数组时,也可以采用下标遍历的方法。
下面看关于ArrayList的例子:
package com.JYX.ArrayList;
import java.util.ArrayList;
public class AboutArrayList {
public static void main(String[] args) {
ArrayList<Integer> array = new ArrayList<>();
//初始化ArrayList对象array
array.add(10);
//增加一个int数值10
array.add(20);
//增加一个int数值20
int num = array.get(1);
System.out.println(num);
}
}
ArrayList最大的好处就是“动态”,可以不必关心数组空间的大小。
下面介绍一种变形的for循环遍历数组或List的方法:
package com.JYX.ArrayList;
import java.util.ArrayList;
public class AboutArrayList_2 {
public static void main(String[] args) {
int[] a = {1,2,3,4,5};
ArrayList<Integer> arr = new ArrayList<>();
for(int i = 0;i < a.length;i++) {
arr.add(a[i]);
}
for(int num: arr) {
System.out.println(num);
}
}
}
输出结果为:
“:”前是元素,元素的类型必须与ArrayList的泛型一致;
这个元素就是后面数组的每一个元素,而且是按照下标顺序从前往后取的
LinkedList:
上述操作对于LinkedList也是一样的。
下面用代码进行解析(调用之前博文中的Complex类)
阶段总结:
数组对于插入、删除操作,时间复杂度较高,为O(n);
链表对于插入删除的操作,时间复杂度为常量,O(1);
所以在未来程序中基本没有数据的插入删除,主要是查找的话,那么,ArrayList的效果更好;反之,LinkedList的效果更好。
1、泛型的好处
容量大,可以方便的存储和处理任何类型的数据;
2、元素定位方法——indexOf方法
indexOf()方法是ArrayList和LinkedList都提供的方法,可以取得指定元素的下标。
Complex c = new Complex(2,3);
int index = complexList.indexOf(c);
System.out.println(index);
输出的结果是2;
这里要注意一个问题,Complex类的equals()方法;
上述程序能够定位成功的关键是,在Complex类中覆盖了equals()方法。而这个方法在indexOf()方法执行时自动被调用,用来判断“相等”与否。
首先,无论我们是否覆盖equals()方法,indexOf()方法在执行时都会自动调用equals()方法进行“相等”判断!只是,在没有覆盖的情况下,调用的是Object类原始的equals()方法,其“相等比较”原则是“地址相等”;
首先,使Complex类中的equals()方法注释起来,使其失去作用;在执行下图中的代码,并观察运行结果:
可以看到,返回值是-1,没错,上述的猜想是正确的:
调用indexOf()方法,就会自动调用equals()方法,
若不匹配,则返回-1;
3、判断元素是否存在——contains()方法
contains()方法和indexOf()方法的原因一样;
感谢mec铁血教主。