数组
数组与继承
父类类型数组引用 子类类型数组 √
将父类类型存入 实际上是子类类型的数组 ——> 运行时产生 java.lang.ArrayStoreException 异常
- 数组元素的类型称为该数字的基类型
- 数组的长度为固定属性 length
- java支持引用类型和基类型的数组
- 通过索引操作符[ ]来访问元素
一维数组
//声明
int [] arrayOfInts;//建议使用这种
int arrayOfInts [];//C风格
//创建 创建后数组元素会初始化为其类型的默认值
//[ ]内必须有整数值
arrayOfInts = new int [20];
int [] arr = new int [20];
//对象数组元素 是 对象的引用
String [] name = new String [5];
//支持c风格的{} 且,分隔
int [] a = {2,5,7,9}; //隐式的创建一个有着适当类型和长度的数组
//注意:: java中关于字符数组的赋值 char [] ch ="abc"; 这是错误的
双引号" " 表字符串常量 可以直接赋值给String的
char [] ch ={'a','b','c'};
//遍历
//1
for(int i = 0;i < a.length; i++;){
System.out.println(a[i]);
}
//2
for(int i:a){
System.out.println(i);
}
多维数组
//以二维数组为例
int [] [] twoDimension ;
// new操作 运行不设置维的大小 但 第一维必须设置大小 长度大于等于0
int [] [] towDimension1 = new int [8][];
//第二维数组大小可以不同
towDimension1[0] =new int [8];
towDimension1[1] =new int [5];
方法
System.arraycode(source,sourceStart,destination,deStart,length);
//条件 1 source destination 均已初始化
2. destination数组中 deStarat+length 不能大于 destination.length
关系 : AbstractCollection<E> implements Collection
AbstractList<E> extends AbstractCollection<E> implements List<E>
ArrayList<E> extends AbstractList<E>
数组 如int [] a = {1,2} | Arrays 工具类 | ArrayList | |
最基本的一个存储结构 | 用来操作array ,提供搜索、排序、复制等静态方法。 | 动态数组 ArrayList的构造方法可以接受一个Collection类型的对象 | |
类型必须相同。 效率高,但容量固定且无法动态改变。 | 静态类Arrays (其包含的方法全部为静态) | ArrayList <变量名> = new ArrayList(); | |
(rt.jar)java.util | ()rt.jar)java.util | ||
不能增加与删除 | 含有内部类ArrayList不具有任何添加或移除元素的任何方法 | 具有修改数组的功能 | |
长度 | a.length | size(实际数量) 扩容到 capacity>1.5x?c :1.5x trimToSize() 删除多余容量 | |
访问 | a[0] | 通过get() set(int,Element) |
byte [] array = new byte[]{1,2,3,4,5}; //这种方式初始化是 []内不得有数字
ArrayList<Employee> staff = new ArrayList<>(100);
Arrays
asList(obj) 和subList(from,to )
asList
//1.asList 返回的长度 与数组的基类型有关
//返回ArrayList对象,但是该类是Arrays类中一个私有静态内部类,而不是常见的java.util.ArrayList类
int[] array = new int[]{1,2,3,4,5};
List list = Arrays.asList( array );
System.out.println( list.size() ); //1
//asList参数不接受基本类型数组
Integer[] array = new Integer[]{1,2,3,4,5};
List list = Arrays.asList( array ); //list.size() 返回5
Integer [] integers = list.toArray();//List->数组
//2.由于list引用的是Arrays.ArrayList 不能进行添加等操作
list.add(6);//异常: java.lang.UnsupportedOperationException
ArrayList<Integer> arrayList = new ArrayList<> ( Arrays.asList(array) );
arrayList.add(6);
System.out.println( arrayList.size() );//6
subList为ArrayList内部类
//返回内部类SubList extends AbstractList<E> implements RandomAccess
//RandomAccess 是一个标记接口,用于标明实现该接口的List支持快速随机访问,主要目的是使算法能够在随机和顺序访问的list中表现的更加高效。
ArrayList<Integer> list1=new ArrayList<Integer>();
list1.add(1);
list1.add(2);
list1 =(ArrayList<Integer>) list1.subList(1, 2);//不可以java.util.ArrayList$SubList cannot be cast to java.util.ArrayList
ArrayList<Integer> arrayList = new ArrayList<> (list1.subList(1, 2) );//可以
binarySearch 二分搜索法( obj[], int fromIndex, int toIndex, obj)
int [] array = {1,3,3,5,7};
System.out.println( Arrays.binarySearch(array, 1,3,2) );//-2
System.out.println( Arrays.binarySearch(array,2) ); //-2
System.out.println( Arrays.binarySearch(array,3) ); //2
//使用条件 1).数组是升序 2).[fromIndex,toIndex-1] 合法
//binarySearch()返回值
// 1、找到关键字,则返回值为关键字在数组中的位置索引,且索引从0开始
// 2、没有找到关键字,返回值为负的插入点值
// (第一个比关键字大的元素在数组中的位置索引,且该位置索引从整个数组的第一个元素算作1开始)
//源码
public static int binarySearch(int[] a, int fromIndex, int toIndex,
int key) {
rangeCheck(a.length, fromIndex, toIndex);//检查[fromIndex,toIndex-1]是否合法
return binarySearch0(a, fromIndex, toIndex, key);
}
private static int binarySearch0(int[] a, int fromIndex, int toIndex,
int key) {
int low = fromIndex;
int high = toIndex - 1;
while (low <= high) {
int mid = (low + high) >>> 1;
int midVal = a[mid];
if (midVal < key)
low = mid + 1;
else if (midVal > key)
high = mid - 1;
else
return mid; // key found
}
return -(low + 1); // key not found.
}
可以用来延长数组 copyOf(obj, int) 和copyOfRange(obj,int from,int to)
copyOfRange可以拷贝指定范围内的数组元素,
//copyOf
String [] a = new String [] {"AB","sf","15","sa","fw","WER"};
String [] b = Arrays.copyOf(a,2);//AB sf
//从 被复制数组下标为0开始 复制长度为 int
//若int 大于原数组的长则补基类型的默认值
String []b = Arrays.copyOf(a,9); //AB sf 15 sa fw WER null null null
//copyOfRange(obj,from,to) 从原数组(下标重0开始计算) from 开始赋值已知赋值到to(不包括下标为to的值)
String []b = Arrays.copyOfRange(a,1,3);//sf 15
//若to-from > 原数组的长则补基类型的默认值
String []b = Arrays.copyOfRange(a,1,9);//sf 15 sa fw WER null null null
//copyOf源码 ( copyOfRange 以copy多了检查newLength(to-from)的合法性 )
public static char[] copyOf(char[] original, int newLength) {
char[] copy = new char[newLength];
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}
关于复制
void java.lang.System.arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
将src中下标为 [srcPos,srcPos+length - 1]范围内的元素 复制到目标dest中[destPos,destPos+length - 1]
deepEquals和equals 比较两数组的值
deepToString 和toString
//deepEquals源码中有调用equals
//equals: 1).判断是否为相同对象的引用 2).是否有空数组 3).判断长度 4).遍历元素
String [] a = new String [] {"AB","sf","15"};
String [] b = new String [] {"AB","sf","15"};
String [] []a1 = new String [][] { {"AB"},{"sf"},{"15"}};
String [] []b1 = new String [][] { {"AB"},{"sf"},{"15"} };
System.out.println(Arrays.equals(a, b)); //true
System.out.println(Arrays.deepEquals(a, b)); //true
System.out.println(Arrays.equals(a1, b1)); //false
System.out.println(Arrays.deepEquals(a1, b1)); //true
//toString deepToString
System.out.println(Arrays.toString(b)); //[AB, sf, 15]
//[类型@哈希值]
System.out.println(Arrays.toString(a1)); //[[Ljava.lang.String;@7852e922, [Ljava.lang.String;@4e25154f, [Ljava.lang.String;@70dea4e]
System.out.println(Arrays.deepToString(b));//[AB, sf, 15]
System.out.println(Arrays.deepToString(a1));//[[AB], [sf], [15]]
//源码
public static String toString(double[] a) {
if (a == null)
return "null";
int iMax = a.length - 1;
if (iMax == -1)
return "[]";
StringBuilder b = new StringBuilder();
b.append('[');
for (int i = 0; ; i++) {
b.append(a[i]);
if (i == iMax)
return b.append(']').toString();
b.append(", ");
}
}
deepEquals | equals | 结论 | |
一维数组 | 相同 | 无差别 | |
多维数组 | 不相同 | 使用deepEquals equals结果错误,不能判断多维 |
fill (obj[],from,to,objValue)用obj填充obj数组
String [] b = new String [5];
Arrays.fill(b,2,3,"A"); //null A null null
Arrays.fill(b,"A"); //A A A A A
hashCode(obj[])
String [] a = new String [] {"A","A","A"};
String [] b = new String [3];
Arrays.fill(b,0,3,"A");
System.out.println(Arrays.hashCode(a));//94336
System.out.println(Arrays.hashCode(b));//94336
String [] c = new String [5];
Arrays.fill(b,0,3,"A");
System.out.println(Arrays.hashCode(c));//90656896
parallelPrefix parallelSetAll setAll parallelSort和sort
Integer []a =new Integer [] {8,16,32,64};
Arrays.parallelPrefix( a, (x,y)->(x>>1) );//8 4 2 1
Arrays.parallelPrefix( a, (x,y)->(x>+y) );//8 24 56 120
(x,y)->(x>+y)
赋值的左边必须是变量 (x,y)
//*并行地累积给定数组的每个元素,使用所提供的功能。
// parallelSetAll会将数组中的值按照一个函数的计算结果过滤出来。
//该函数会获得元素索引,并计算该位置处的值
Arrays.parallelSetAll(a,x->x);//0,1,2,3
Arrays.setAll(a,x->x);//0,1,2,3
int []arrray = new int []{227,5,575,79,35,7,99} ;
Arrays.parallelSort(a,2,5);//227 5 35 79 575 7 99
Arrays.sort(a,2,5);//227 5 35 79 575 7 99
spliterator()
返回数组的分片迭代器,暂时还没搞用途
stream()
转换成Stream,暂时还没搞懂用法和用途。
ArrayList
AbstractList
1.创建
ArrayList<String> list = new ArrayList<String>();
list.add("A");
list.add("B");
list.add("C");
ArrayList<String> list = new ArrayList<String>() {{
add("A");
add("B");
add("C");
}}
1.add(E) //默认在数组的末尾添加该元素
2.add(int ,E) //在下标为int的位置 添加E int后的元素右移以为
Integer[] array = new Integer[]{1,2,3,4,5};
ArrayList<Integer> arrayList = new ArrayList<> ( Arrays.asList(array) );
arrayList.add(4,50); //1,2,3,4,50,5
arrayList.add(99); //1,2,3,450,5,99
.addAll
clear()//删除数组
clone()//克隆数组
isEmpty()//判空 空 ->true 非空->fasle
get(int)//得到该下标的元素的值
set(int,E)//将下标int的值更换成E
contains()//是否存在该元素
subList(from,to)//截取 数组 from
ensureCapacity(int) //扩充数组, add一点点的扩充,ensureCapacity一次性扩充(效率高)
forEach //??
remove(int)//删除下标int的元素
removeAll()//??
removeIf()//??
iterator()//??
retainAll()//??
indexOf(obj) //使用 boolean java.lang.Object.equals(Object obj) 进行比较
lastIndexOf(obj)//返回最后一次 与obj值相等的元素下标 (实现反式:倒序遍历)