Arrays
Arrays
我们在操作一组连续的数据时,通常会想到使用数组或者集合,这些都是十分优秀的数据结构。但是java.util也为我们提供了一个工具类Arrays,其中有一些比较便利的方法来操作数组。下面我就来介绍一下。
1、toString:遍历数组返回一个字符串,他不同于我们平时使用的 对象名.toString,这个返回的是对象的16进制哈希地址。而这个方法需要我们传入一个数组对象,将数组的元素以字符串的形式返回。
1 String[] arr ={"a","b","c","d","e"}; //定义一个字符串数组 2 Integer[] nums={1,2,3,4,5,6}; //定义一个整形数组 3 String strs = Arrays.toString(arr); //对字符串数组进行遍历 4 String nums1 = Arrays.toString(nums); //对整型数组进行遍历 5 System.out.println(arr.toString()); //区别于我们介绍的toString()方法,这是对象名的toString,输出对象的哈希地址 6 System.out.println(strs); //对刚刚的字符数组进行遍历 7 System.out.println(nums1); //对刚刚的整型数组进行遍历 8 9 10 输出结果: 11 [Ljava.lang.String;@1540e19d 12 [a, b, c, d, e] 13 [1, 2, 3, 4, 5, 6]
可以看到,该方法同样可以遍历元素,不过一定要区分另外一个toString()方法。
2、asList(T..a);传入一个数组对象,返回一个该数组对象对应类型的固定长度的List集合
1 Integer[] nums={1,2,3,4,5,6}; //定义一个整形数组 2 List<Integer> list = Arrays.asList(nums); //返回该数组同样类型的固定长度list集合 3 for (Integer i :list) { 4 System.out.print(i+" "); 5 } 6 7 输出结果:1 2 3 4 5 6
我们这里一定要注意一个坑,一定是固定长度,固定长度,固定长度,,所以我们就不能对其进行,增加和删除,我们看下面实例↓(对返回的集合添加一个元素,黄色部分)
1 Integer[] nums={1,2,3,4,5,6}; //定义一个整形数组 2 List<Integer> list = Arrays.asList(nums); //返回该数组同样类型的固定长度list集合 3 list.add(7); 4 for (Integer i :list) { 5 System.out.print(i+" "); 6 } 7 8
可以看到,代码报错这里我们去看看add()的源码,我们发现这个list并没有add方法,这也是我们java官方都不让我们用的原因,但是我们进入报错信息中的‘’AbstractList‘’,可以发现存在这个add方法,但是其中可以发现他会直接抛出异常:UnsupportedOperationException ↓,这刚好就是我们抛出的异常
这里我们需要注意另外一个坑,我们去看看文档会发现,asList是需要传入一个支持泛化的参数,那么什么是支持泛化类型的参数勒?通过查阅资料,我们得知,java中的基本数据类型是不支持泛化的,然后其他的引用数据类型是支持泛化的。具体原因,我的理解就是,基本数据类型他的实际值保存在栈内存中,但是引用数据类型的栈内存只是保存了该数据的地址,其真实的值保存在堆内存中。下面我们就看一个例子↓↓↓
1 Integer[] num1={1,2,3,4,5,6}; //定义一个引用整形数组 2 int[] num2={1,2,3,4,5,6}; //定义一个基本数据类型的整形数组 3 List<Integer> list = Arrays.asList(num1); //返回该数组同样类型的固定长度list集合 4 List<int[]> ints = Arrays.asList(num2); 5 System.out.println(list.size()); //输出引用数据类型数组的长度 6 System.out.println(ints.size()); //输出基本数据类型数组的长度 7 8 输出结果: 9 6 10 1
我们可以看到,基本数据数据类型的数组长度只有1,原因就是,我们传入整个数组,并不是数组中的每一个元素作为参数,而是将整个数组作为参数,所以长度只有1. 引用数据类型的数组,长度就是符合要求的
3、sort():该方法的能够支持基本数据类型(除去boolean类型)的排序,而且还包括实现了comparable接口的object类型。下面我们试一下基本数据类型↓↓↓
1 int[] num2={7,2,9,3,5,6}; //定义一个基本数据类型的整形数组 2 Arrays.sort(num2); //对num2进行排序 3 System.out.println(Arrays.toString(num2)); //输出结果 4 5 6 输出结果: 7 [2, 3, 5, 6, 7, 9]
sort的源码,我们暂且就不去追究(其中使用有快排,插入排序等多种思想),哈哈哈哈,其实就是我们的功底不够
接着我们试一下自定义数据类型,并且自己定义排列顺序(黄色区域,返回的是负数,我们就是升序排列),案例如下↓↓↓
1 CollectionTest[] people =new CollectionTest[]{ 2 new CollectionTest("tom",18), 3 new CollectionTest("jack",19), 4 new CollectionTest("mary",20) }; //创建三个人的数组 5 6 7 Arrays.sort(people, new Comparator<CollectionTest>() { 8 @Override //重写我们的compare方法,自己定义排序规则(年龄小的排在前面)
9 public int compare(CollectionTest o1, CollectionTest o2) { 10 if (o1 == null || o2 == null){ 11 return 0; 12 } 13 return (o1.getAge()- o2.getAge()); //返回的是负数,我们就是升序排列 14 } 15 }); 16 17 for (CollectionTest collectionTest:people) { 18 System.out.println(collectionTest.toString()); 19 } //遍历 20 21 22 输出结果: 23 CollectionTest{name='tom', age=18} 24 CollectionTest{name='jack', age=19} 25 CollectionTest{name='mary', age=20}
4、binarySearch():二分查找法,这里我们需要传入一个已经排序好的数组,然后传入一个需要查找的值。
1 int[] num2={1,2,3,4,5,6,7,8,9,10}; 2 int index = Arrays.binarySearch(num2, 9); 3 System.out.println(index); 4 5 输出结果: 6 8
源码分析:low为fromIndex等于0,high等于数组的长度-1,中间mid就是(low+high),右移一位,就是跟除2一样的结果,移位运算更快而已,然后跟传入的key值比较,如果等于key值,我们就返回下标,如果比key值小,low的下标就位mid+1,反之比key值大,high就是mid-1,然后知道low大于high,就退出循环。
5、copyOf;数组的复制方法,需要我们传入一个,一个原数组,和我们需要复制的长度。
1 int[] num2={1,2,3,4,5,6,7,8,9,10}; 2 int[] ints = Arrays.copyOf(num2, num2.length); 3 System.out.println(Arrays.toString(ints)); 4 5 6 7 输出结果: 8 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
源码分析:
我们Arrays.copyOf其实调用的是,System.copyOf方法 ,参数列表:original, 0, copy, 0,,Math.min(original.length, newLength)
src:源数组
srcPos:源数组要复制的起始位置
dest:目的数组
destPos:目的数组放置的起始位置
length:复制的长度(就是原数组长度和我们给定长度中比较小的那一个)
好了以上就是,我们Arrays的常用方法。