Java数组与ArrayList
数据的组织形式无非两种:连续的、离散的,数组就是一种连续的数据组织。
数组
数组
是一个固定长度的,包含了相同类型数据的容器。
数组的使用
//创建数组
int [] a;//声明一个数组,int表示数组类的元素类型,a为变量名
a = new int[10];//创建一个长度为10的数组,并让a引用指向数组
int[] b = new int[10];//声明的同时指向一个新数组
//访问数组
a[0] = 1; //将数组的第一个数赋值为1
a[10] = 1; //数组访问下标范围为0到length-1,超过范围会产生数组下标越界异常,即ArrayIndexOutOfBoundsException
//初始化数组方法
1.先分配空间,再赋值
int [] a = new int[10];//未赋值状态,int类型数组默认值为0
for(i=0;i<a.length;i++){
a[i] = i+1;
}
2.分配空间,同时赋值
int [] a = new int[]{1,2,3,4,5};//分配空间同时赋值,不需要指定长度
int [] b = {1,2,3,4,5};//省略new int
上面的都是一维数组,二位数组创建与之类似。
int a [] [] = new int [] []{{1,2,3},{2,3,4},{3,4,5}};//形式就像数组里的数组
//初始化二维数组方法
int [] [] a = new int[3][3];//三个一维数组,每个一维数组长度为3
int [] [] b = new int[3][];//有三个一维数组,但以为长度的具体长度未知
b[0] = new int[3];
b[0][0] = 1;//需要对每个一维数组分配长度,才能访问
int [] [] c = new int[][]{
{1,2,3},
{2,3},
{3,4,5,6}
};//分配空间同时赋值
数组的排序
- 选择法排序
第一位与其他所有位比较,只要比第一位小,就换到第一位。
第二位再与后面的所有位比较,只要比第二位小,就换到第二位。
以此类推:
public static void main(String[] args){
int a [] = new int [];{90,24,565,23,56};
for (int j=0;j<a.length-1;j++){
if(a[i]<a[j]){
//把原位置数存在一个中间变量中,然后交换位置
int temp = a[j];
a[j] = a[i];
a[i] = temp;
}
}
}
- 冒泡法排序
从第一位开始,相邻两位两两比较,较大的交换到后面,一轮循环后最大就在最后一位。
第二位重复操作至倒数第二位。
直至完成排序。
public static void main(String[] args){
int a [] = new int []{90,24,565,23,56};
for(int j=0;j<a.length;j++){
for(int i=0;i<a.length-j-1;i++){
if(a[i]>a[i+1]){
//a[i]和a[i+1]交换位置
int temp = a[i];
a[i] = a[i+1];
a[i+1] = temp;
}
}
}
}
for each取值
int a [] = new int []{90,24,565,23,56};
for(int each:a){
System.out.println(each);
}
//取最小值
int min = 100;
for(int each:a){
if(each < min){
min = each;
}
}
System.out.println("最小值为"+min);
复制数组
数组的长度在分配完空间后就不能再改变。
public static void main(String[] args){
int a [] = new int []{90,24,565,23,56};
int b [] = new int [4];
//for循环
for (int i=0;i<b.length;i++){
b[i] = a [i];
}
//System.arrayCopy(src,srcPos,dest,destPos,length)
//src: 源数组
//srcPos: 从源数组复制数据的启始位置
//dest: 目标数组
//destPos: 复制到目标数组的启始位置
//length: 复制的长度
System.arrayCopy(a,0,b,0,4);
ArrayList
数组的长度一旦确定就不可更改,我们常常需要实现长度可变的数组列表,ArrayList就可以实现这种效果。
我们先尝试手写一个简单的ArrayList。
//List interface
public interface MyList<E> {
//增加数据
void add(E e);
//插入数据
void insert(E e,int index);
//删除数据
void del(int index);
//修改数据
void update(int index,E e);
//获取数据
E get(int index);
//获取大小
int getSize();
}
因为要保证代码的复用性,而数组中的值类型有很多种,所以使用了泛型
。泛型指的是将类型在类/接口/方法定义的时候,参数化,直到使用时,指定具体类型
。
以类为例,在类名后加<>
。常用的有E元素、K键、V值。
public class MyArrayList<E> implements MyList<E>{
int size;//元素个数
Object[] data;//存储数据的数组
@Override
public void add(E e) {
// TODO Auto-generated method stub
//创建一个新的数组
Object[] tempArr = new Object[size+1];
//将原数组中的内容复制到新数组中
for(int i=0; i<size; i++) {
tempArr[i] = data[i];
}
//将新数组赋给data
data = tempArr;
//添加元素,大小加1
data[size++] = e;
}
@Override
public E get(int index) {
// TODO Auto-generated method stub
//强制转型成E类型数据
return (E)data[index];
}
@Override
public int getSize() {
// TODO Auto-generated method stub
return size;
}
}
主函数:
public class Mainer {
public static void main(String[] args) {
// TODO Auto-generated method stub
//实例化泛型类
MyList<String> list = new MyArrayList<>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
//取数据
for(int i=0; i<list.getSize(); i++) {
System.out.println(list.get(i));
}
}
}
java的ArrayList
中为保证代码安全性,设置了很多避免数组超限的判断函数。