数组
-
-
数组的定义:数组的本质是由java程序向虚拟机申请一串
连续的内存。
-
示意图
-
示意图
-
-
数组的初始化可以有几种形式
-
1 直接赋值(静态初始化)
Object[] obj1 ={new Object(),new String("asd") ,new LinkedList()};
-
2 初始化长度(动态初始化)
可以初始化数组的长度,也可以在初始化数组时赋值, 一般数组初始化时,数字为0,对象为nullObject[] obj =new Object[10];
-
1 直接赋值(静态初始化)
-
-
数组越界
- 数组越界属于运行时异常,当数组访问长度超过数组本身长度时,就会抛出数组越界异常 java.lang.ArrayIndexOutOfBoundsException
-
-
数组指向和传递
-
引用传递的本质是栈内存中的**字段(集合)**指向堆内存中的数据。当发生数组的赋值或者数组的函数参数传递时,传递的是值得引用,也就是将指向该数据的指针传递,使得指向同一块数据内存,从而达到数组传递的目的。所以,当堆内存的数据时,其他指向该数据段的引用都会被修改。
-
引用传递的本质是栈内存中的**字段(集合)**指向堆内存中的数据。当发生数组的赋值或者数组的函数参数传递时,传递的是值得引用,也就是将指向该数据的指针传递,使得指向同一块数据内存,从而达到数组传递的目的。所以,当堆内存的数据时,其他指向该数据段的引用都会被修改。
-
-
二维数组
- 二维数据是指在内存中定义一段连续的n m长度的内存,并且在java程序中可以理解为nm的表格。
-
-
数组的遍历
-
for遍历
foreach遍历for(int i = 0; i< 100 ;i++ ) { System.out.println(arr[i]); }
for(Intager i : arr) { System.out.println(i); }
-
for遍历
操作数组的工具类:Arrays
- 额外方法:System.arraycopy():array的复制。
输出int[] i = {0,1,2,3,4,5,6,7,8,9}; int[] j ={10,11,22,33,44,55,66,77,88,99}; //参数:被copy的数组,起始位置,copy的数组,起始位置,copy长度 System.arraycopy(i,3,j,4,6); for (int k = 0; k < 10; k++) { System.out.print(i[k]); } System.out.println(); for (int l = 0; l < 10; l++) { System.out.print(j[l]); }
0 1 2 3 4 5 6 7 8 9 10 11 22 33 3 4 5 6 7 8
- Arrays的asList()方法,返回值时一个list接口(必须强转成实现类才能接收)
//底层新建了一个ArraysList,并返回一个list接口 //以下语句会发生运行时错误,因为不能强转 ArrayList als =(ArrayList)Arrays.asList(i);
- Arrays的Arrays.binarySearch()方法,二分查找,返回一个int下标
//第一种方式(两个参数):查询的数组arr,查找的值(int,double,float等) //第二种方式(两个参数):查询的数组arr,查找的值(int,double,float等),对比函数comparator //第三种方式(四个参数):查询的数组arr,起始点int,结束点int,查找的值(int,double,float等) Arrays.binarySearch();
- Arrays的Arrays.copyOf()方法,复制数组,类似方法1,返回一个arr
底层是通过传入的对象新建一个数组,然后通过System.out.arraycopy()方法来复制数组
如果新数组的长度超过原数组的长度,则保留数组默认值//参数:被复制的数组arr,起始点int Arrays.copyOf(arr[],int );
//参数:被复制的数组arr,起始点int,结束点 Arrays.copyOfRange(arr[],int,int);
- Arrays的Arrays.equals()方法,返回一个boolean
源码
应用public static boolean equals(long[] a, long[] a2) { if (a==a2) return true; if (a==null || a2==null) return false; //判断长度 int length = a.length; if (a2.length != length) return false; //对比数据 for (int i=0; i<length; i++) if (a[i] != a2[i]) return false; return true; }
Arrays.equals();
- Arrays的 deepEquals(Object[] a1, Object[] a2)方法,返回一个boolean
源码分析:
Arrays的 deepEquals0(Object e1, Object e2)方法,放回一个booleanpublic static boolean deepEquals(Object[] a1, Object[] a2) { //判断地址是否相同 if (a1 == a2) return true; //判断是否为null if (a1 == null || a2==null) return false; //判断长度是否相等 int length = a1.length; if (a2.length != length) return false; //如果数组对象相等则返回true,否则为false for (int i = 0; i < length; i++) { Object e1 = a1[i]; Object e2 = a2[i]; if (e1 == e2) continue; if (e1 == null) return false; //调用deepEquals0(Object e1, Object e2)方法 // Figure out whether the two elements are equal boolean eq = deepEquals0(e1, e2); if (!eq) return false; } return true; }
源码分析
应用static boolean deepEquals0(Object e1, Object e2) { assert e1 != null; boolean eq; //如果传入参数是以下几种数组,则调用 deepEquals(Object[] a1, Object[] a2)方法,否则通过传入参数的equal方法对比。 if (e1 instanceof Object[] && e2 instanceof Object[]) eq = deepEquals ((Object[]) e1, (Object[]) e2); else if (e1 instanceof byte[] && e2 instanceof byte[]) eq = equals((byte[]) e1, (byte[]) e2); else if (e1 instanceof short[] && e2 instanceof short[]) eq = equals((short[]) e1, (short[]) e2); else if (e1 instanceof int[] && e2 instanceof int[]) eq = equals((int[]) e1, (int[]) e2); else if (e1 instanceof long[] && e2 instanceof long[]) eq = equals((long[]) e1, (long[]) e2); else if (e1 instanceof char[] && e2 instanceof char[]) eq = equals((char[]) e1, (char[]) e2); else if (e1 instanceof float[] && e2 instanceof float[]) eq = equals((float[]) e1, (float[]) e2); else if (e1 instanceof double[] && e2 instanceof double[]) eq = equals((double[]) e1, (double[]) e2); else if (e1 instanceof boolean[] && e2 instanceof boolean[]) eq = equals((boolean[]) e1, (boolean[]) e2); else eq = e1.equals(e2); return eq; }
//参数为两个对象数组,而不能是基本类型,如果对象里有数组,则递归调用。底层通过对象的equal()方法对比 Arrays.deepEquals(Object[],Object[]);
- Arrays的Arrays.deepHashCode();
//通过该方法获取数组的hashcode,底层是Arrays自己的hashcode()方法 Arrays.deepHashCode();
- Arrays的Arrays.fill()方法,让数组填充传入的参数
//底层是遍历数组然后为每个下标赋值 Arrays.fill(arr,int);
- Arrays的Arrays.sort()方法以及parallelSort此链接sort描述详细
//第一种:直接排序 :arr //第二种:部分排序 :arr,int,int Arrays.sort() //并行排序,稳定排序,当超过一定阈值时分多线程进行多段归并排序 Arrays.parallelSort();
- Arrays.parallelPrefix()方法
调用ArrayPrefixHelpers.CumulateTask<>//通过传入参数对数组进行自定义操作(笔者的理解,可能不对) //参数:arr,function Arrays.parallelPrefix();
- Arrays.setAll()方法以及parallelSetAll方法
//通过传入一个arr以及一个实现了IntFunction接口的方法,来实现对数组的初始化操作 //与fill不同 Arrays.setall(arr,function); //底层通过stream流的方式实现并行 Arrays.parallelSetAll(); //
- Arrays.stream();返回一个数组的流,可以对其进行流操作
- Arrays.spliterator();迭代器解析
数组变成List
- Arrays.asList();返回一个list接口,但数组转变成list,会变成一个存储数组的链表,很low对吧
- 通过初始化list,遍历数组加入
List<String> resultList = new ArrayList<>(array.length); for (String s : array) { resultList.add(s); }
- 通过Collections的add方法,注意泛型操作
List<String> resultList = new ArrayList<>(array.length); Collections.addAll(resultList,array);
- jdk9的list接口的List.of(array)方法
List<String> resultList = List.of(array);
自定义数组学习(笔者很菜的,所以自己写的代码也很菜不需要看)
- 要求
实现一个支持动态扩容的数组
实现一个大小固定的有序数组,支持动态增删改操作
实现两个有序数组合并为一个有序数组public class MyArray<E> { protected Object[] arr; protected int DEFAULT_CAPACITY = 10; protected int size = 0; public MyArray(){ this.arr = new Object[DEFAULT_CAPACITY]; } public MyArray(int length){ if(length < 0 ) {throw new IllegalArgumentException("Illegal Capacity: "+ length);} this.arr = new Object[length]; } public boolean add(Object obj){ if(obj == null) { return false; } check(size+1); arr[size]=obj; this.size++; return true; } public int delete(int index){ if(index - size >0){throw new IllegalArgumentException("Illegal Capacity: ");} int number =(int)arr[index]; System.arraycopy(arr, index+1 ,arr ,index ,(size - index - 1)); arr[arr.length-1]=null; size--; return number; } public E get(int index){ if(size-index >0) { return (E)arr[index]; }else { throw new IndexOutOfBoundsException(); } } private void check(int size){ if(size - arr.length > 0) { int newSize = arr.length+arr.length>>1; arr = Arrays.copyOf(arr,newSize); } } public void show(){ for (int i = 0; i < this.size; i++) { System.out.println(arr[i]); } } /** * 从小到大排序,归并排序 * @param obj1 * @param obj2 * @return */ public static MyArray sortAll(MyArray obj1 ,MyArray obj2){ MyArray obj = new MyArray(obj1.size+obj2.size); int obj1index = 0; int obj2index = 0; int number1 = -1; int number2 = -1; while(obj.size != obj1.size+obj2.size) { //获取下标对应的数字并下表加1 if(obj1index < obj1.size && number1 == -1){ number1 = (int)obj1.get(obj1index++); } if(obj2index < obj2.size && number2 == -1){ number2 = (int)obj2.get(obj2index++); } // if(number1 != -1 && number2 != -1) { if(number1 < number2) { obj.add(number1); number1 = -1; }else{ obj.add(number2); number2 = -1; } }else{ if(number1 == -1){ obj.add(number2); number2 = -1; }else{ obj.add(number1); number1 = -1; } } } return obj; } }