Java工具类: Arrays
Arrays类是数组的操作类,定义在java.util包中,主要功能是实现数组元素的查找/数组内容的充填/排序等功能
1.排序数组的sort方法
重点:对数组元素进行排序操作,默认由小到大排序.
该方法的参数不仅可以是基础数据类型的数组,也可以是对象引用的数组。同时还可以指定数组中需要排序的元素的索引范围。
当对对象进行排序时,数组中的所有元素都必须实现 Comparable 接口。(就当你没有看到,哈哈)
即数组中的所有元素都必须是可相互比较的(也就是说,对于数组中的任何 e1 和 e2 元素而言,e1.compareTo(e2) 不得抛出 ClassCastException)
(1) 数字排序
排序规则:由小到大排序
package com.shxt.demo03;
import java.util.Arrays;
public class ArraysTest01 {
public static void main(String[] args) {
int[] a = {9, 8, 7, 2, 3, 4, 1, 0, 6, 5};
Arrays.sort(a);
for(int i = 0; i < a.length; i ++) {
System.out.print(a[i] + "\t");
}
}
}
复制代码
(2) 字符串排序
排序规则:先大写后小写
package com.shxt.demo03;
import java.util.Arrays;
public class ArraysTest02 {
public static void main(String[] args) {
String[] a = {"a","A","b","B"};
Arrays.sort(a);
for(int i = 0; i < a.length; i ++) {
System.out.print(a[i] + "\t");
}
}
}
复制代码
(3) 字符串严格排序
排序规则:严格按字母表顺序排序,也就是忽略大小写排序 Case-insensitive sort
package com.shxt.demo03;
import java.util.Arrays;
public class ArraysTest03 {
public static void main(String[] args) {
String[] a = {"a","C","b","D"};
Arrays.sort(a,String.CASE_INSENSITIVE_ORDER);
for(int i = 0; i < a.length; i ++) {
System.out.print(a[i] + "\t");
}
}
}
复制代码
(4) 反向排序
排序规则:先小写后大写
字符串反向
package com.shxt.demo03;
import java.util.Arrays;
import java.util.Collections;
public class ArraysTest04 {
public static void main(String[] args) {
String[] a = {"a","A","b","B"};
Arrays.sort(a, Collections.reverseOrder());//Collections 集合类中的工具类
for(int i = 0; i < a.length; i ++) {
System.out.print(a[i] + "\t");
}
}
}
复制代码
数字排序,要使用包装类
package com.shxt.demo03;
import java.util.Arrays;
import java.util.Collections;
public class ArraysTest05 {
public static void main(String[] args) {
//不能使用基本数据类型
Integer[] a = {9, 8, 7, 2, 3, 4, 1, 0, 6, 5};
Arrays.sort(a, Collections.reverseOrder());
for(int i = 0; i < a.length; i ++) {
System.out.print(a[i] + "\t");
}
}
}
复制代码
这个里面我们使用了Collections工具类,如果想自己完成规则的定义,那么就需要使用比较器接口Comparable(简单了解即可)
package com.shxt.demo03;
import java.util.Arrays;
import java.util.Comparator;
public class ArraysTest05_1 {
public static void main(String[] args) {
//不能使用基本数据类型
Integer[] a = {9, 8, 7, 2, 3, 4, 1, 0, 6, 5};
Arrays.sort(a, new IntegerComparator());
for(int i = 0; i < a.length; i ++) {
System.out.print(a[i] + "\t");
}
}
}
/**
* Comparator是一个接口
* 所以这里我们自己定义的类IntegerComparator要implents该接口
* 而不是extends Comparator
*
*/
class IntegerComparator implements Comparator<Integer> {
@Override
public int compare(Integer o1, Integer o2) {
//如果o1小于o2,我们就返回正值,如果n1大于n2我们就返回负值,
//这样颠倒一下,就可以实现反向排序了
if(o1 < o2) {
return 1;
}else if(o1 > o2) {
return -1;
}else {
return 0;
}
}
}
复制代码
(5) 忽略大小写反向排序
package com.shxt.demo03;
import java.util.Arrays;
import java.util.Collections;
public class ArraysTest04 {
public static void main(String[] args) {
String[] a = {"a","C","b","D"};
Arrays.sort(a, Collections.reverseOrder());
Collections.reverse(Arrays.asList(a));//先忽略吧
for(int i = 0; i < a.length; i ++) {
System.out.print(a[i] + "\t");
}
}
}
复制代码
(6) 区间排序-了解
Arrays.sort(int[] a, int fromIndex, int toIndex)
复制代码
这种形式是对数组部分排序,也就是对数组a的下标从fromIndex到toIndex-1的元素排序,注意:下标为toIndex的元素不参与排序!
package com.shxt.demo03;
import java.util.Arrays;
public class ArraysTest07 {
public static void main(String[] args) {
int[] a = {9, 8, 7, 2, 3, 4, 1, 0, 6, 5};
Arrays.sort(a, 0, 3);
for(int i = 0; i < a.length; i ++) {
System.out.print(a[i] + " ");
}
}
}
//运行结果为: 7 8 9 2 3 4 1 0 6 5
复制代码
Java初学者最常见的错误思想,就是试图去写一些方法来完成数组的排序功能,
其实,数组排序功能,在java的api里面早已实现,我们没有必要去重复制造*。
如果你是应届生,还是需要学习各种排序的,参考网址:http://geek.csdn.net/news/detail/113928
JDK8强大了排序功能:parallelSort
parallelSort是java8中新出的一种排序API,
这是一种并行排序,Arrays.parallelSort使用了Java7的Fork/Join框架使排序任务可以在线程池中的多个线程中进行,
Fork/Join实现了一种任务窃取算法,一个闲置的线程可以窃取其他线程的闲置任务进行处理
发现数据量越大,parallelSort的优势就越明显。
复制代码
2.查找数组的binarySearch方法
public static int binarySearch(T[] a, T key)
复制代码
使用二分搜索法来搜索指定类型数组,以获得指定的值。
[重点]必须在进行此调用之前对数组进行排序(通过 sort() 方法)。
如果没有对数组进行排序,则结果是不确定的。如果数组包含多个带有指定值的元素,则无法保证找到的是哪一个。
返回值说明:
1、如果找到关键字,则返回值为关键字在数组中的位置索引,且索引从0开始
2、如果没有找到关键字,返回值为负的插入点值,所谓插入点值就是第一个比关键字大的元素在数组中的位置索引,而且这个位置索引从1开始 (-(插入点)),如果数组中的所有元素都小于指定的键,则为(-a.length-1)。
package com.shxt.demo03;
import java.util.Arrays;
public class ArraysTest08 {
public static void main(String[] args) {
int[] b = new int[]{4, 25, 10, 95, 06, 21};
System.out.println("原数组为:");
for (int dim1 : b) {
System.out.print("" + dim1 + " ");
}
//一定要先排序
Arrays.sort(b);
System.out.println("排序后为:");
for (int x : b) {
System.out.print(x + " ");
}
System.out.println();
int index = Arrays.binarySearch(b, 2);
System.out.println("关键字2的返回值为:" + index);
index = Arrays.binarySearch(b, 20);
System.out.println("关键字20的返回值为:" + index);
index = Arrays.binarySearch(b, 30);
System.out.println("关键字30的返回值为:" + index);
index = Arrays.binarySearch(b, 100);
System.out.println("关键字100的返回值为:" + index);
index = Arrays.binarySearch(b, 10);
System.out.println("关键字10的返回值为:" + index);
}
}
复制代码
结果分析如下:
原数组为:
4 25 10 95 6 21
排序后为:
4 6 10 21 25 95
关键字2的返回值为:-1
关键字2并没有在数组中,而且2比数组中的任何一个元素都小,所以其插入点的值应为元素4的位置也就是1(没有找到关键字从1开始)
关键字20的返回值为:-4
关键字20也不在数组中,数组中第一个比20大的数是21,所以20的插入点值为4(没用找到关键字从索引从1开始)
关键字30的返回值为:-6
关键字30也不在数组中,数组中第一个比30大的数是95,所以30的插入点值为6(没用找到关键字从索引从1开始)
关键字100的返回值为:-7
关键字100也不在数组中,而且100比数组中所有的元素都大,此时插入点值为length+1 为7(没有找到关键字索引从1开始)
关键字10的返回值为:2
关键字10在数组中,所以返回其在数组中的索引为2(找到关键字索引从0开始)
复制代码
3.充填数组的fill()方法
用指定的值来填充数组,可以指定需要填充的索引范围。
package com.shxt.demo03;
import java.util.Arrays;
public class ArraysTest09 {
public static void main(String[] args) {
Integer[] a = new Integer[5];
Arrays.fill(a, 2);
System.out.println("当前数组容器:"+Arrays.toString(a));
Arrays.fill(a, 5);
// 数字3覆盖并填满了整个Array容器
System.out.println("当前数组容器:"+Arrays.toString(a));
// 填充的开始位
Integer startIndex = 1;
// 填充的结束位
Integer endIndex = 3;
Arrays.fill(a, startIndex, endIndex, 8);
System.out.println("当前数组容器:"+Arrays.toString(a));
}
}
/*
当前数组容器:[2, 2, 2, 2, 2]
当前数组容器:[5, 5, 5, 5, 5]
当前数组容器:[5, 8, 8, 5, 5]
*/
复制代码
4.比较两个数组的equals方法
如果两个指定类型数组彼此相等,则返回 true。如果两个数组包含相同数量的元素,并且两个数组中的所有相应元素对都是相等的,则认为这两个数组是相等的。换句话说,如果两个数组以相同顺序包含相同的元素,则两个数组是相等的。此外,如果两个数组引用都为 null,则认为它们是相等的。
equals方法适用于一维数组,多维数组则使用deepEquals(),用法同equals。
package com.shxt.demo03;
import java.util.Arrays;
public class ArraysTest10 {
public static void main(String[] args) {
int[] array1={5,6,9,3,2,4};
int[] array2={5,6,9,3,2,4};
int[] array3={6,5,9,3,2,4};
boolean flag1=Arrays.equals(array1,array2); // true
boolean flag2=Arrays.equals(array1,array3); // false
//直接使用equals方法会是什么结果呢?
boolean flag3 = array1.equals(array2); //堆内存地址不一样 false array1==array2
System.out.println(flag1+" "+flag2+" "+flag3);
}
}
复制代码
5.数组转字符串toString()方法
返回指定数组内容的字符串表示形式。
字符串表示形式由数组的元素列表组成,括在方括号("[]")中。
相邻元素用字符 ", "(逗号加空格)分隔。
这些元素通过 String.valueOf(short) 转换为字符串。如果 a 为 null,则返回 "null"。
package com.shxt.demo03;
import java.util.Arrays;
public class ArraysTest11 {
public static void main(String[] args) {
String[] array01 = new String[3];
System.out.println(array01);
System.out.println(Arrays.toString(array01));
String[] array02 = {"悟空","八戒","唐僧"};
System.out.println(array02);
System.out.println(Arrays.toString(array02));
}
}
复制代码
6.克隆数组的copyOf方法
如果你想扩大数组容量又不想改变它的内容的时候可以使用这个方法
package com.shxt.demo03;
import java.util.Arrays;
public class ArraysTest13 {
public static void main(String[] args) {
int[] array1={5,6,9,3,2,4};
System.out.println("array1的数组长度:"+array1.length);
int[] array2 = Arrays.copyOf(array1,array1.length+1);//根据实际情况扩容
System.out.println("array2的数组长度:"+array2.length);
array2[0]=100;
System.out.println("array1:"+Arrays.toString(array1));
System.out.println("array2:"+Arrays.toString(array2));
}
}
/**
array1的数组长度:6
array2的数组长度:7
array1:[5, 6, 9, 3, 2, 4]
array2:[100, 6, 9, 3, 2, 4, 0]
*/
复制代码
array1 和 array2 是两个不相干的数组
7.克隆数组的copyOfRange方法
copyOfRange(int []original,int from,int to)
复制代码
original为原始的int型数组,from为开始角标值,to为终止角标值。(其中包括from角标,不包括to角标。即处于[from,to)状态)
package com.shxt.demo03;
import java.util.Arrays;
public class ArraysTest14 {
public static void main(String[] args) {
int[] array1={5,6,9,3,2,4};
int[] array2 = Arrays.copyOfRange(array1,1,5);
System.out.println("array2的数组长度:"+array2.length);
System.out.println("array2:"+Arrays.toString(array2));
}
}
// 运行结果: array2的数组长度:4
// array2:[6, 9, 3, 2]
复制代码
这个方法比循环遍历复制数组效率要高。
8.数组转列表asList方法
返回一个受指定数组支持的固定大小的列表。(对返回列表的更改会“直接写”到数组。)此方法同Collection.toArray()一起,充当了基于数组的 API 与基于 collection 的 API 之间的桥梁。返回的列表是可序列化的,并且实现了 RandomAccess。
package com.shxt.demo03;
import java.util.Arrays;
import java.util.List;
public class ArraysTest15 {
public static void main(String[] args) {
Integer[] array1={5,6,9,3,2,4};
List list = Arrays.asList(array1);
System.out.println("list的长度:"+list.size());
}
}
// list的长度:6
复制代码
避免使用基本数据类型数组转换为列表
对上述的代码改造一下,改为基本数据类型的数组
package com.shxt.demo03;
import java.util.Arrays;
import java.util.List;
public class ArraysTest15 {
public static void main(String[] args) {
int[] array1={5,6,9,3,2,4};
List list = Arrays.asList(array1);
System.out.println("list的长度:"+list.size());
System.out.println(list);
}
}
/**
list的长度:1
[[[email protected]]
*/
复制代码
程序的运行结果并没有像我们预期的那样是 6 而是逆天的 1,这是什么情况?
从这个运行结果我们可以充分证明 list 里面的元素就是 int 数组。
转换为列表后不能添加元素
package com.shxt.demo03;
import java.util.Arrays;
import java.util.List;
public class ArraysTest15 {
public static void main(String[] args) {
Integer[] array1={5,6,9,3,2,4};
List list = Arrays.asList(array1);
list.add(99);//添加元素
}
}
复制代码
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.AbstractList.add(AbstractList.java:148)
at java.util.AbstractList.add(AbstractList.java:108)
at com.shxt.demo03.ArraysTest15.main(ArraysTest15.java:10)
复制代码
如果想给列表添加数据,需要重新构造列表
package com.shxt.demo03;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class ArraysTest15 {
public static void main(String[] args) {
Integer[] array1={5,6,9,3,2,4};
List list = Arrays.asList(array1);
//再次转换
List tempList = new ArrayList(list);
tempList.add(666);
//可以添加
System.out.println(tempList);
}
}
复制代码
9.数组的哈希码hashCode
基于指定数组的内容返回哈希码。对于任何两个满足 Arrays.equals(a, b) 的同类 型数组 a 和 b,也可以说 Arrays.hashCode(a) ==Arrays.hashCode(b)。
此方法返回的值与在 List 上调用 hashCode 方法获得的值相同,该 List 包含以相同顺序表示 a 数组元素的实例的序列。如果 a 为 null,则此方法返回 0。
package com.shxt.demo03;
import java.util.Arrays;
public class ArraysTest12 {
public static void main(String[] args) {
int[] array1={5,6,9,3,2,4};
int[] array2={5,6,9,3,2,4};
int[] array3={6,5,9,3,2,4};
System.out.println(Arrays.hashCode(array1));
System.out.println(Arrays.hashCode(array2));
System.out.println(Arrays.hashCode(array3));
System.out.println("---------------------");
//所有的都不一样
System.out.println(array1.hashCode());
System.out.println(array2.hashCode());
System.out.println(array3.hashCode());
}
}
/*
1036461630
1036461630
1064167260
---------------------
1163157884
1956725890
356573597
*/
复制代码