java数组、Arrays、ArrayList、Vector简介
数组的定义
数组是一个固定长度的,包含了相同类型数据的 容器。
数组的长度是不可变的,一旦分配好空间,是多长,就多长,不能增加也不能减少。
数组声明与创建
数组中的值的类型必须一致。
一维数组
int[] a; // 声明一个数组
a = new int[5]; // 创建一个长度为5的int数组,并将a指向它
a[0] = 10;
a[1] = 11;
a[2] = 12;
int[] b = new int[]{1,2,3,4}; // 在初始化时就赋值,则不能指定数组的长度,会自动根据赋值来决定长度
int[] c = {1,2,3,4} // 声明时赋值也可以直接简写
二维数组
int[][] a = new int[2][3]; // 声明并创建一个2*3的数组
a[1][2] = 11;
int[][] b = new int[][]{ // 声明时直接赋值
{1,2,3},
{4,5},
{7,8,9}
};
int[][] c = new int[2][]; // 声明时只分配了二维数组
c[0] = new int[3]; // 必须先声明长度,才能访问
高维数组
int[][][] a = new int[3][2][1]; // 高维数组的声明与创建
数组的常用操作
数组复制
System.arraycopy(src, srcPos, dest, destPos, length);
//src: 源数组
//srcPos: 从源数组复制数据的起始位置
//dest: 目标数组
//destPos: 复制到目标数组的启始位置
//length: 复制的长度
数组排序
1、选择法排序
public class HelloWorld {
public static void main(String[] args) {
int a [] = new int[]{18,62,68,82,65,9};
//排序前,先把内容打印出来
for (int i = 0; i < a.length; i++) {
System.out.print(a[i] + " ");
}
System.out.println(" ");
//选择法排序
//第一步: 把第一位和其他所有位进行比较
//如果发现其他位置的数据比第一位小,就进行交换
for (int i = 1; i < a.length; i++) {
if(a[i]<a[0]){
int temp = a[0];
a[0] = a[i];
a[i] = temp;
}
}
//把内容打印出来
//可以发现,最小的一个数,到了最前面
for (int i = 0; i < a.length; i++) {
System.out.print(a[i] + " ");
}
System.out.println(" ");
//第二步: 把第二位的和剩下的所有位进行比较
for (int i = 2; i < a.length; i++) {
if(a[i]<a[1]){
int temp = a[1];
a[1] = a[i];
a[i] = temp;
}
}
//把内容打印出来
//可以发现,倒数第二小的数,到了第二个位置
for (int i = 0; i < a.length; i++) {
System.out.print(a[i] + " ");
}
System.out.println(" ");
//可以发现一个规律
//移动的位置是从0 逐渐增加的
//所以可以在外面套一层循环
for (int j = 0; j < a.length-1; j++) {
for (int i = j+1; i < a.length; i++) {
if(a[i]<a[j]){
int temp = a[j];
a[j] = a[i];
a[i] = temp;
}
}
}
//把内容打印出来
for (int i = 0; i < a.length; i++) {
System.out.print(a[i] + " ");
}
System.out.println(" ");
}
}
2、冒泡法排序
public class HelloWorld {
public static void main(String[] args) {
int a [] = new int[]{18,62,68,82,65,9};
//排序前,先把内容打印出来
for (int i = 0; i < a.length; i++) {
System.out.print(a[i] + " ");
}
System.out.println(" ");
//冒泡法排序
//第一步:从第一位开始,把相邻两位进行比较
//如果发现前面的比后面的大,就把大的数据交换在后面
for (int i = 0; i < a.length-1; i++) {
if(a[i]>a[i+1]){
int temp = a[i];
a[i] = a[i+1];
a[i+1] = temp;
}
}
//把内容打印出来
//可以发现,最大的到了最后面
for (int i = 0; i < a.length; i++) {
System.out.print(a[i] + " ");
}
System.out.println(" ");
//第二步: 再来一次,只不过不用比较最后一位
for (int i = 0; i < a.length-2; i++) {
if(a[i]>a[i+1]){
int temp = a[i];
a[i] = a[i+1];
a[i+1] = temp;
}
}
//把内容打印出来
//可以发现,倒数第二大的到了倒数第二个位置
for (int i = 0; i < a.length; i++) {
System.out.print(a[i] + " ");
}
System.out.println(" ");
//可以发现一个规律
//后边界在收缩
//所以可以在外面套一层循环
for (int j = 0; j < a.length; j++) {
for (int i = 0; i < a.length-j-1; i++) {
if(a[i]>a[i+1]){
int temp = a[i];
a[i] = a[i+1];
a[i+1] = temp;
}
}
}
//把内容打印出来
for (int i = 0; i < a.length; i++) {
System.out.print(a[i] + " ");
}
System.out.println(" ");
}
}
Arrays类
Arrays类位于 java.util 包中,主要包含了操纵数组的各种方法。
使用时导包:import java.util.Arrays。
数组复制
与使用System.arraycopy
进行数组复制类似的, Arrays提供了一个copyOfRange方法进行数组复制。
不同的是System.arraycopy,需要事先准备好目标数组,并分配长度。 copyOfRange 只需要源数组就就可以了,通过返回值,就能够得到目标数组了。
除此之外,需要注意的是 copyOfRange 的第3个参数,表示源数组的结束位置,是取不到的。
Arrays.copyOfRange(int[] original, int from, int to)
示例代码
import java.util.Arrays;
public class HelloWorld {
public static void main(String[] args) {
int a[] = new int[] { 18, 62, 68, 82, 65, 9 };
// copyOfRange(int[] original, int from, int to)
// 第一个参数表示源数组
// 第二个参数表示开始位置(取得到)
// 第三个参数表示结束位置(取不到)
int[] b = Arrays.copyOfRange(a, 0, 3);
for (int i = 0; i < b.length; i++) {
System.out.print(b[i] + " ");
}
}
}
数组输出
如果要打印一个数组的内容,就需要通过for循环来挨个遍历,逐一打印
但是Arrays提供了一个toString()方法,直接把一个数组,转换为字符串,这样方便观察数组的内容
Arrays.toString(a)
示例代码
import java.util.Arrays;
public class HelloWorld {
public static void main(String[] args) {
int a[] = new int[] { 18, 62, 68, 82, 65, 9 };
String content = Arrays.toString(a);
System.out.println(content);
}
}
数组排序
Arrays提供了排序的方法,调用后自动进行排序。
Arrays.sort(int[] a)
这种形式是对一个数组的所有元素进行排序,并且是按从小到大的顺序。
sort的返回是void,是直接在原数组上进行更新操作。
import java.util.Arrays;
public class ArraysLearning {
public static void main(String[] args) {
int[] a = new int[]{4,2,5,6,8,1,0,9};
Arrays.sort(a);
System.out.println(Arrays.toString(a));
// 输出内容为:[0, 1, 2, 4, 5, 6, 8, 9]
}
}
Arrays.sort(int[] a, int fromIndex, int toIndex)
这种形式是对数组部分排序,也就是对数组a的下标从fromIndex到toIndex-1的元素排序,注意:下标为toIndex的元素不参与排序。
import java.util.Arrays;
public class ArraysLearning {
public static void main(String[] args) {
int[] a = new int[]{4,2,5,6,8,1,0,9};
Arrays.sort(a,3,6);
System.out.println(Arrays.toString(a));
// 输出内容为:[4, 2, 5, 1, 6, 8, 0, 9]
}
}
倒叙排序
java中并没有原生提供倒叙排序的方法,因此需要我们自己写,其实内容比较简单,只要将sort后的结果,倒过来就可以了。倒叙的过程我使用了递归思想。以下是代码实例:
import java.util.Arrays;
public class ArraysLearning {
// 用来拼接两个一维数组
public static int[] concat(int[] first, int[] second) {
int[] result = Arrays.copyOf(first, first.length + second.length);
System.arraycopy(second, 0, result, first.length, second.length);
return result;
}
// 用来倒叙数组
public static int[] re_nums(int[] a){
if (a.length==1){
return a;
}
else {
int[] b = {a[a.length-1]};
int[] c = re_nums(Arrays.copyOfRange(a,0, a.length-1));
int[] d = concat(b, c);
return d;
}
}
// 主函数
public static void main(String[] args) {
int[] a = new int[]{4,2,5,6,8,1,0,9};
Arrays.sort(a);
int[] b = re_nums(a);
System.out.println(Arrays.toString(b));
}
}
动态数组
动态数组常用的是ArrayList和Vector两种类型,其区别在于ArrayList是线程不安全的。因此只建议在单线程应用中使用ArrayList,多线程中尽量使用Vector。
ArrayList
ArrayList类实现了List接口,其是一个数组队列,是一个动态数组的概念。传统的数组从定义来看,长度是固定的,不能添加和删除元素。动态数组补足了java数组的短板。
- 初始化
ArrayList在初始化时可以给其定义容量,也可不给定,或直接带入一个数组(或集合)初始化。
ArrayList al = new ArrayList(); // 当数组容量满时会自动扩容为当前数组容量的2倍
ArrayList al2 = new ArrayList(2);
ArrayList al3 = new ArrayList(a); // a为集合或数组
- 添加元素
al.add(Object); // 添加至尾部,使用add方法来添加,动态数组添加类型为Object,因此支持任意类型
- 获取元素
al.get(int index); // 根据index来获取元素,返回类型为Object
al.contains(Object value); // 判断value在数组中是否存在,返回布尔类型
al.indexOf(Object value); // 判断value在数组中的序号(从头开始的第一个相同元素),若不存在则返回-1
- 删除元素
al.remove(int index); // 根据下标删除元素
al.remove(Object value); // 根据对象删除元素(删除从头开始的第一个相同元素)
- 其他常用方法
al.size(); // 获取数组的大小
al.isEmpty(); // 判断数组是否为空
Vector
- 创建数组
Vector<Object> v1 = new Vector<Object>(); // 不指定默认大小,默认分配大小为10
Vector<Object> v2 = new Vector<Object>(4); // 创建一个容量为4的数组
- 添加元素
v.add("eg.1"); // 添加元素方式
v.add(int index, Object element); // 在指定序号位置添加
- 获取元素
v.get(int index); // 返回的是Object
- 删除元素
v.remove(int index);
v.remove(Object o);
// 两种删除元素的方式,与ArrayList类似
- 其他方法
boolean addAll(int index, Collection<? extends E> c);
// 从index索引位置开始添加c集合里所有的元素,后面的元素都往后移c.size()位
void addElement(E obj);
// 在集合后面添加一个元素,无论该元素是什么类型的,都会把他的toString()的返回值添加进去
int capacity();
// 返回此向量的当前容量,不是元素个数(注意数组容量和元素个数的区别)
void copyInto(Object[] anArray);
// 把集合中的元素复制到anArray数组中去