Arrays类的分析及使用
1. Arrays类介绍
Arrays类是Java API中提供的类,在java.util包中,此类包含用来操作数组的各种方法,比如排序和搜索,在这个类中如果指定数组引用为null,则此类方法都会抛出NullPointerException,此类还包含一个允许将数组作为列表来查看的静态工厂。
Arrays类包含sort,binarySearch,equals,fill,copyOf,asList,hashCode,deepHashCode,deepEquals,toString和deepToString public方法供其他类使用。其中从java.lang.Object继承的方法有clone,equals,finalize,getClass hashCode,notify,notifyAll,toString,wait。sort方法用来排序,binarySearch方法是二分查找,equals方法是用来比较,fill方法用来将某个特定的值填充到数组中,copyOf复制特定长度的数组,asList方法的作用是将数组作为列表来查看。
Arrays类包含两个私有类,分别是LegacyMergeSort类和ArrayList类,gacMergeSort是老版本的归并排序实现,而ArrayList是一个数组队列,用于实现asList方法。
Arrays的构造函数
private Arrays() {}
可以看到Arrays的构造函数被被设置为private的,表明这个类禁止使用默认构造函数并且不能被实例化,但是可以通过提供静态方法来使用这个类,这种模式就是单例模式。
Arrays方法摘要
public static void sort(Object[] a)
public static void sort(Object[] a, int fromIndex, int toIndex)
public static <T> void sort(T[] a, Comparator<? super T> c)
public static <T> void sort(T[] a, int fromIndex, int toIndex, Comparator<? super T> c) public static int binarySearch(Object[] a, Object key)
public static int binarySearch(Object[] a, int fromIndex, int toIndex, Object key)
public static <T> int binarySearch(T[] a, T key, Comparator<? super T> c)
public static <T> int binarySearch(T[] a, int fromIndex, int toIndex, T key, Comparator<? super T> c) public static boolean equals(Object[] a, Object[] a2) public static void fill(Object[] a, Object val)
public static void fill(Object[] a, int fromIndex, int toIndex, Object val)
public static <T> T[] copyOf(T[] original, int newLength)
public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) public static <T> T[] copyOfRange(T[] original, int from, int to)
public static <T,U> T[] copyOfRange(U[] original, int from, int to, Class<? extends T[]> newType) public static <T> List<T> asList(T... a) public static int hashCode(Object a[]) public static int deepHashCode(Object a[]) public static boolean deepEquals(Object[] a1, Object[] a2) public static String toString(Object[] a) public static String deepToString(Object[] a)
2. Arrays类源码分析
依据JDK1.7.0_45的源码对Arrays类中的主要方法进行分析。
public static void sort(Object[] a) {
if (LegacyMergeSort.userRequested)
legacyMergeSort(a);
else
ComparableTimSort.sort(a);
}
此方法表示根据元素的自然顺序对指定对象数组按升序进行排序,当用户没有请求使用老版本的归并排序时,直接使用ComparableTimSort类的方法实现,关于ComparableTimSort类之后会单独进行分析。
public static void sort(Object[] a, int fromIndex, int toIndex) {
if (LegacyMergeSort.userRequested)
legacyMergeSort(a, fromIndex, toIndex);
else
ComparableTimSort.sort(a, fromIndex, toIndex);
}
此方法表示的是根据元素的自然顺序对指定对象数组的指定范围按升序进行排序,其他实现与上面的额排序方法相同。
public static <T> void sort(T[] a, Comparator<? super T> c) {
if (LegacyMergeSort.userRequested)
legacyMergeSort(a, c);
else
TimSort.sort(a, c);
}
此方法表示根据指定比较器产生的顺序对指定对象数组进行排序。具体的排序实现是调用了TimSort的sort方法实现。
public static <T> void sort(T[] a, int fromIndex, int toIndex,
Comparator<? super T> c) {
if (LegacyMergeSort.userRequested)
legacyMergeSort(a, fromIndex, toIndex, c);
else
TimSort.sort(a, fromIndex, toIndex, c);
}
此方法表示根据指定比较器产生的顺序对指定对象数组的指定范围进行排序。同上具体的排序实现是调用了TimSort的sort方法实现。TimSort类在之后会单独分析。
public static int binarySearch(Object[] a, Object key) {
return binarySearch0(a, 0, a.length, key);
} // Like public version, but without range checks.
private static int binarySearch0(Object[] a, int fromIndex, int toIndex,
Object key) {
int low = fromIndex;
int high = toIndex - 1; while (low <= high) {
int mid = (low + high) >>> 1;
Comparable midVal = (Comparable)a[mid];
int cmp = midVal.compareTo(key); if (cmp < 0)
low = mid + 1;
else if (cmp > 0)
high = mid - 1;
else
return mid; // key found
}
return -(low + 1); // key not found.
}
此方法表示使用二分搜索法来搜索指定数组,以获得指定对象,二分查找的具体实现没有进行范围检查。
public static int binarySearch(Object[] a, int fromIndex, int toIndex,
Object key) {
rangeCheck(a.length, fromIndex, toIndex);
return binarySearch0(a, fromIndex, toIndex, key);
}
此方法表示使用二分搜索法来搜索指定数组的范围,以获得指定对象。
public static <T> int binarySearch(T[] a, T key, Comparator<? super T> c) {
return binarySearch0(a, 0, a.length, key, c);
} // Like public version, but without range checks.
private static <T> int binarySearch0(T[] a, int fromIndex, int toIndex,
T key, Comparator<? super T> c) {
if (c == null) {
return binarySearch0(a, fromIndex, toIndex, key);
}
int low = fromIndex;
int high = toIndex - 1; while (low <= high) {
int mid = (low + high) >>> 1;
T midVal = a[mid];
int cmp = c.compare(midVal, key);
if (cmp < 0)
low = mid + 1;
else if (cmp > 0)
high = mid - 1;
else
return mid; // key found
}
return -(low + 1); // key not found.
}
二分查找的的泛型实现,使用二分搜索法来搜索指定数组,以获得指定对象。
public static <T> int binarySearch(T[] a, int fromIndex, int toIndex,
T key, Comparator<? super T> c) {
rangeCheck(a.length, fromIndex, toIndex);
return binarySearch0(a, fromIndex, toIndex, key, c);
}
二分查找的泛型实现,使用二分搜索法来搜索指定数组的范围,以获得指定对象。
public static boolean equals(Object[] a, Object[] 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++) {
Object o1 = a[i];
Object o2 = a2[i];
if (!(o1==null ? o2==null : o1.equals(o2)))
return false;
} return true;
}
此方法为如果两个指定的 Objects 数组彼此相等,则返回 true。在具体的实现中如果两个Objects中有1个为null则返回false。
public static void fill(Object[] a, Object val) {
for (int i = 0, len = a.length; i < len; i++)
a[i] = val;
}
此方法表示将指定的 Object 引用分配给指定 Object 数组的每个元素。
public static <T> T[] copyOf(T[] original, int newLength) {
return (T[]) copyOf(original, newLength, original.getClass());
} public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
T[] copy = ((Object)newType == (Object)Object[].class)
? (T[]) new Object[newLength]
: (T[]) Array.newInstance(newType.getComponentType(), newLength);
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}
复制指定的数组,截取或用 null 填充(如有必要),以使副本具有指定的长度。这里注意对泛型的使用。,最终调用System.arraycopy函数进行复制操作。
public static <T> T[] copyOfRange(T[] original, int from, int to) {
return copyOfRange(original, from, to, (Class<T[]>) original.getClass());
} public static <T,U> T[] copyOfRange(U[] original, int from, int to, Class<? extends T[]> newType) {
int newLength = to - from;
if (newLength < 0)
throw new IllegalArgumentException(from + " > " + to);
T[] copy = ((Object)newType == (Object)Object[].class)
? (T[]) new Object[newLength]
: (T[]) Array.newInstance(newType.getComponentType(), newLength);
System.arraycopy(original, from, copy, 0,
Math.min(original.length - from, newLength));
return copy;
}
将指定数组的指定范围复制到一个新数组。
@SafeVarargs
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
} /**
* @serial include
*/
private static class ArrayList<E> extends AbstractList<E>
implements RandomAccess, java.io.Serializable
{
private static final long serialVersionUID = -2764017481108945198L;
private final E[] a; ArrayList(E[] array) {
if (array==null)
throw new NullPointerException();
a = array;
} public int size() {
return a.length;
} public Object[] toArray() {
return a.clone();
} public <T> T[] toArray(T[] a) {
int size = size();
if (a.length < size)
return Arrays.copyOf(this.a, size,
(Class<? extends T[]>) a.getClass());
System.arraycopy(this.a, 0, a, 0, size);
if (a.length > size)
a[size] = null;
return a;
} public E get(int index) {
return a[index];
} public E set(int index, E element) {
E oldValue = a[index];
a[index] = element;
return oldValue;
} public int indexOf(Object o) {
if (o==null) {
for (int i=0; i<a.length; i++)
if (a[i]==null)
return i;
} else {
for (int i=0; i<a.length; i++)
if (o.equals(a[i]))
return i;
}
return -1;
} public boolean contains(Object o) {
return indexOf(o) != -1;
}
}
返回一个受指定数组支持的固定大小的列表。@SafeVarargs注解抑制编译器警告的示例,只能用在参数长度可变的方法或构造方法上,且方法必须声明为static或final,否则会出现编译错误。一个方法使用@SafeVarargs注解的前提是,开发人员必须确保这个方法的实现中对泛型类型参数的处理不会引发类型安全问题。
public static int hashCode(Object a[]) {
if (a == null)
return 0; int result = 1; for (Object element : a)
result = 31 * result + (element == null ? 0 : element.hashCode()); return result;
}
基于指定数组的内容返回哈希码。这个方法继承自java.lang.Object。
public static int deepHashCode(Object a[]) {
if (a == null)
return 0; int result = 1; for (Object element : a) {
int elementHash = 0;
if (element instanceof Object[])
elementHash = deepHashCode((Object[]) element);
else if (element instanceof byte[])
elementHash = hashCode((byte[]) element);
else if (element instanceof short[])
elementHash = hashCode((short[]) element);
else if (element instanceof int[])
elementHash = hashCode((int[]) element);
else if (element instanceof long[])
elementHash = hashCode((long[]) element);
else if (element instanceof char[])
elementHash = hashCode((char[]) element);
else if (element instanceof float[])
elementHash = hashCode((float[]) element);
else if (element instanceof double[])
elementHash = hashCode((double[]) element);
else if (element instanceof boolean[])
elementHash = hashCode((boolean[]) element);
else if (element != null)
elementHash = element.hashCode(); result = 31 * result + elementHash;
} return result;
}
基于指定数组的“深层内容”返回哈希码。
public static boolean deepEquals(Object[] a1, Object[] a2) {
if (a1 == a2)
return true;
if (a1 == null || a2==null)
return false;
int length = a1.length;
if (a2.length != length)
return 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; // Figure out whether the two elements are equal
boolean eq = deepEquals0(e1, e2); if (!eq)
return false;
}
return true;
}
如果两个指定数组彼此是深层相等 的,则返回 true。
public static String toString(Object[] 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(String.valueOf(a[i]));
if (i == iMax)
return b.append(']').toString();
b.append(", ");
}
}
返回指定数组内容的字符串表示形式。
public static String deepToString(Object[] a) {
if (a == null)
return "null"; int bufLen = 20 * a.length;
if (a.length != 0 && bufLen <= 0)
bufLen = Integer.MAX_VALUE;
StringBuilder buf = new StringBuilder(bufLen);
deepToString(a, buf, new HashSet<Object[]>());
return buf.toString();
}
返回指定数组“深层内容”的字符串表示形式。
3. Arrays类的使用
一般主要使用Arrays类进行排序和查找,下面是简单的使用例子
import java.util.Arrays;
import java.util.Random; class RandomString {
private RandomString() {}
public static String getString(int length) {
String base = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
Random random = new Random();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < length; i++) {
int index = random.nextInt(base.length());
sb.append(base.charAt(index));
}
return sb.toString();
}
} public class ArraysTest {
public static void main(String[] args) {
int[] intArray = new int[10000000];
String[] stringArray = new String[10000000];
Random random = new Random(); // sort test
for (int i = 0; i < intArray.length; i++) {
intArray[i] = random.nextInt(1000000);
}
for (int j = 0; j < stringArray.length; j++) {
stringArray[j] = RandomString.getString(random.nextInt(20));
}
long startTime = System.currentTimeMillis();
Arrays.sort(intArray);
long endTime = System.currentTimeMillis();
System.out.println("sort int numbers cost: " + (endTime - startTime) + "ms"); startTime = System.currentTimeMillis();
Arrays.sort(stringArray);
endTime = System.currentTimeMillis();
System.out.println("sort string numbers cost: " + (endTime - startTime) + "ms");
//System.out.println(Arrays.toString(stringArray)); // search test
startTime = System.nanoTime();
Arrays.binarySearch(intArray, 97);
endTime = System.nanoTime();
System.out.println("search the numbers cost: " + (endTime - startTime) + "ns"); startTime = System.nanoTime();
Arrays.binarySearch(stringArray, "abcdef");
endTime = System.nanoTime();
System.out.println("search the numbers cost: " + (endTime - startTime) + "ns");
}
}
可以看到在使用Arrays类的sort和二分查找函数时,当给10000000个整数和10000000个字符串排序并且做查找时消耗时间如下
sort int numbers cost: 1123ms |
Arrays类的分析及使用的更多相关文章
- 7.Java集合-Arrays类实现原理及源码分析
Java集合---Arrays类源码解析 转自:http://www.cnblogs.com/ITtangtang/p/3948765.html 一.Arrays.sort()数组排序 Java A ...
- 《java入门第一季》之Arrays类前传(排序案例以二分查找注意的问题)
根据排序算法,可以解决一些小案例.举例如下: /* * 把字符串中的字符进行排序. * 举例:"dacgebf" * 结果:"abcdefg" * * 分析: ...
- 13-02 Java 数组高级算法,Arrays类
冒泡排序 冒泡排序原理 冒泡排序代码: package cn.itcast_01; /* * 数组排序之冒泡排序: * 相邻元素两两比较,大的往后放,第一次完毕,最大值出现在了最大索引处 */ pub ...
- 01 语言基础+高级:1-3 常用API第一部分_day08【String类、static、Arrays类、Math类】
day08[String类.static.Arrays类.Math类] String类static关键字Arrays类Math类 教学目标能够使用String类的构造方法创建字符串对象能够明确Stri ...
- Java数组声明创建和使用以及多维数组、Arrays类、稀疏数组
目录 数组概述 数组声明创建 内存分析 java内存分析 堆 栈 方法区 三种初始化 静态初始化 动态初始化 数组的默认初始化 数组的四个基本特点 数组边界 小结: 数组使用 数组基础使用 For E ...
- 6、Arrays类
Arrays类 Arrays里面包含了一系列静态方法,用于管理或操作数组(比如排序和搜索) 常用方法 toString 返回数组的字符串形式 Arrays.toString(arr) Integer[ ...
- MapReduce剖析笔记之八: Map输出数据的处理类MapOutputBuffer分析
在上一节我们分析了Child子进程启动,处理Map.Reduce任务的主要过程,但对于一些细节没有分析,这一节主要对MapOutputBuffer这个关键类进行分析. MapOutputBuffer顾 ...
- 使用 Arrays 类操作 Java 中的数组
Arrays 类是 Java 中提供的一个工具类,在 java.util 包中.该类中包含了一些方法用来直接操作数组,比如可直接实现数组的排序.搜索等(关于类和方法的相关内容在后面的章节中会详细讲解滴 ...
- Java Arrays类进行数组排序
排序算法,基本的高级语言都有一些提供.C语言有qsort()函数,C++有sort()函数,java语言有Arrays类(不是Array).用这些排序时,都可以写自己的排序规则. Java API对A ...
随机推荐
- Win7上安装WMware虚拟机和Ubuntu操作系统
效果图: 问题拾遗: 一.如何划分一个新硬盘空间? 参考链接:如何新建磁盘空间 效果图: 我划分了20G的内存空间给Ubuntu的硬盘空间.一般来说15G就够用了. 二.VMware上拷贝Ubuntu ...
- NYOJ 16 矩形嵌套(经典DP)
http://acm.nyist.net/JudgeOnline/problem.php?pid=16 矩形嵌套 时间限制:3000 ms | 内存限制:65535 KB 难度: ...
- java 编程技巧
1. 参数可空: @注解表示修改的字段可为空值.看它的定义,可以修饰在方法,参数和字段(类似c#中的?)上. @Target({ElementType.METHOD, ElementType.PARA ...
- List与数组的相互转换
1.从string[]转List<string> string[] str={“1”,”2”}; List <string> list=new List<string&g ...
- [ios]NSThread传值 NSValue传值
NSThread:http://www.cocoachina.com/bbs/read.php?tid=51873 NSValue:http://blog.sina.com.cn/s/blog_bf9 ...
- shell 命令行光标跳转快捷键和history的用法
Ctrl+a: 跳到命令行首 Ctrl+e: 跳到命令行尾 Ctrl+u: 删除光标至命令行首的内容 Ctrl+k: 删除光标至命令行尾的内容 Ctrl+<- 跳到前一个单词首部 Ctrl+-& ...
- Java8 新特性之默认接口方法
摘要: 从java8开始,接口不只是一个只能声明方法的地方,我们还可以在声明方法时,给方法一个默认的实现,我们称之为默认接口方法,这样所有实现该接口的子类都可以持有该方法的默认实现. · 待定 一. ...
- android中 检查网络连接状态的变化,无网络时跳转到设置界面
1:在AndroidManifest.xml中加一个声明 <receiver android:name="NetCheckReceiver"> <inten ...
- Unity项目中显示项目的FPS
using UnityEngine; using System.Collections; public class ShowFpsOnGUI : MonoBehaviour { public floa ...
- codeforces 521a//DNA Alignment// Codeforces Round #295(Div. 1)
题意:如题定义的函数,取最大值的数量有多少? 结论只猜对了一半. 首先,如果只有一个元素结果肯定是1.否则.s串中元素数量分别记为a,t,c,g.设另一个串t中数量为a',t',c',g'.那么,固定 ...