java.util.Arrays类。这个类是个数组工具类。主要提供方法sort(),fill(),binarySearch(),还有数组复制等方法。打开源文件,刚超过4千行,不过包括很多注释,那么我在这里主要讲讲这里面涉及的排序算法和查找算法。
一、binarySearch()方法,二分法查找算法, 算法思想:当数据量很大适宜采用该方法。采用二分法查找时,数据需是排好序的。 基本思想:假设数据是按升序排序的,对于给定值x,从序列的中间位置开始比较,如果当前位置值等于x,则查找成功;若x小于当前位置值,则在数列的前半段 中查找;若x大于当前位置值则在数列的后半段中继续查找,直到找到为止。
- //针对int类型数组的二分法查找,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.
- }
二、sort()方法针对引用类型数组采取的算法是归并排序。算法思想:归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列。
- private static final int INSERTIONSORT_THRESHOLD = 7;//插入排序门槛
- public static void sort(Object[] a) {
- Object[] aux = (Object[])a.clone();
- mergeSort(aux, a, 0, a.length, 0);
- }
- //归并排序
- private static void mergeSort(Object[] src,
- Object[] dest,
- int low,
- int high,
- int off) {
- int length = high - low;
- if (length < INSERTIONSORT_THRESHOLD) { //若数组长度小于7,则用冒泡排序
- for (int i=low; i<high; i++)
- for (int j=i; j>low &&
- ((Comparable) dest[j-1]).compareTo(dest[j])>0; j--)
- swap(dest, j, j-1);
- return;
- }
- // Recursively sort halves of dest into src
- int destLow = low;
- int destHigh = high;
- low += off;
- high += off;
- int mid = (low + high) >>> 1; //无符号左移一位,
- mergeSort(dest, src, low, mid, -off);
- mergeSort(dest, src, mid, high, -off);
- // If list is already sorted, just copy from src to dest. This is an
- // optimization that results in faster sorts for nearly ordered lists.
- if (((Comparable)src[mid-1]).compareTo(src[mid]) <= 0) {
- System.arraycopy(src, low, dest, destLow, length);
- return;
- }
- // Merge sorted halves (now in src) into dest
- for(int i = destLow, p = low, q = mid; i < destHigh; i++) {
- if (q >= high || p < mid && ((Comparable)src[p]).compareTo(src[q])<=0)
- dest[i] = src[p++];
- else
- dest[i] = src[q++];
- }
- }
三、sort()方法采取的是快速排序算法,算法思想:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
- /**
- * Swaps x[a] with x[b].
- */
- private static void swap(int x[], int a, int b) {
- int t = x[a];
- x[a] = x[b];
- x[b] = t;
- }
- public static void sort(int[] a) {
- sort1(a, 0, a.length);
- }
- private static int med3(int x[], int a, int b, int c) {//找出三个中的中间值
- return (x[a] < x[b] ?
- (x[b] < x[c] ? b : x[a] < x[c] ? c : a) :
- (x[b] > x[c] ? b : x[a] > x[c] ? c : a));
- }
- /**
- * Sorts the specified sub-array of integers into ascending order.
- */
- private static void sort1(int x[], int off, int len) {
- // Insertion sort on smallest arrays
- if (len < 7) {//采用冒泡排序
- for (int i=off; i<len+off; i++)
- for (int j=i; j>off && x[j-1]>x[j]; j--)
- swap(x, j, j-1);
- return;
- }
- //采用快速排序
- // Choose a partition element, v
- int m = off + (len >> 1); // Small arrays, middle element
- if (len > 7) {
- int l = off;
- int n = off + len - 1;
- if (len > 40) { // Big arrays, pseudomedian of 9
- int s = len/8;
- l = med3(x, l, l+s, l+2*s);
- m = med3(x, m-s, m, m+s);
- n = med3(x, n-2*s, n-s, n);
- }
- m = med3(x, l, m, n); // Mid-size, med of 3
- }
- int v = x[m];
- // Establish Invariant: v* (<v)* (>v)* v*
- int a = off, b = a, c = off + len - 1, d = c;
- while(true) {
- while (b <= c && x[b] <= v) {
- if (x[b] == v)
- swap(x, a++, b);
- b++;
- }
- while (c >= b && x[c] >= v) {
- if (x[c] == v)
- swap(x, c, d--);
- c--;
- }
- if (b > c)
- break;
- swap(x, b++, c--);
- }
- // Swap partition elements back to middle
- int s, n = off + len;
- s = Math.min(a-off, b-a ); vecswap(x, off, b-s, s);
- s = Math.min(d-c, n-d-1); vecswap(x, b, n-s, s);
- // Recursively sort non-partition-elements
- if ((s = b-a) > 1)
- sort1(x, off, s);
- if ((s = d-c) > 1)
- sort1(x, n-s, s);
- }
四、针对double,float类型数组排序的sort()方法,采取了先把所有的数组元素值为-0.0d的转换成0.0d,再利用快速排序排好序,最后再还原。
- public static long doubleToRawLongBits(double value)根据 IEEE 754 浮点“双精度格式”位布局,返回指定浮点值的表示形式,并保留 NaN 值。
- 第 63 位(掩码 0x8000000000000000L 选定的位)表示浮点数的符号。第 62-52 位(掩码 0x7ff0000000000000L 选定的位)表示指数。第 51-0 位(掩码 0x000fffffffffffffL 选定的位)表示浮点数的有效数字(有时也称为尾数)。
- 如果参数是正无穷大,则结果为 0x7ff0000000000000L。
- 如果参数是负无穷大,则结果为 0xfff0000000000000L。
- 如果参数是 NaN,则结果是表示实际 NaN 值的 long 整数。与 doubleToLongBits 方法不同,doubleToRawLongBits 并没有压缩那些将 NaN 编码为一个“规范的”NaN 值的所有位模式。
- 在所有情况下,结果都是一个 long 整数,将其赋予 longBitsToDouble(long) 方法将生成一个与 doubleToRawLongBits 的参数相同的浮点值。
- 参数:
- value - 双精度 (double) 浮点数。
下面是源代码中的方法:
- public static void sort(double[] a) {
- sort2(a, 0, a.length);
- }
- private static void sort2(double a[], int fromIndex, int toIndex) {
- //static long doubleToLongBits(double value)
- //根据 IEEE 754 浮点双精度格式 ("double format") 位布局,返回指定浮点值的表示形式。
- final long NEG_ZERO_BITS = Double.doubleToLongBits(-0.0d);
- /*
- * The sort is done in three phases to avoid the expense of using
- * NaN and -0.0 aware comparisons during the main sort.
- */
- /*
- * Preprocessing phase: Move any NaN's to end of array, count the
- * number of -0.0's, and turn them into 0.0's.
- */
- int numNegZeros = 0;
- int i = fromIndex, n = toIndex;
- while(i < n) {
- if (a[i] != a[i]) { //这段搞不懂,源代码怪怪的,感觉多此一举
- ouble swap = a[i];
- a[i] = a[--n];
- a[n] = swap;
- } else {
- if (a[i]==0 && Double.doubleToLongBits(a[i])==NEG_ZERO_BITS) {
- a[i] = 0.0d;
- numNegZeros++;
- }
- i++;
- }
- }
- // Main sort phase: quicksort everything but the NaN's
- sort1(a, fromIndex, n-fromIndex);
- // Postprocessing phase: change 0.0's to -0.0's as required
- if (numNegZeros != 0) {
- int j = binarySearch0(a, fromIndex, n, 0.0d); // posn of ANY zero
- do {
- j--;
- } while (j>=0 && a[j]==0.0d);
- // j is now one less than the index of the FIRST zero
- for (int k=0; k<numNegZeros; k++)
- a[++j] = -0.0d;
- }
- }
http://zengzhaoshuai.iteye.com/blog/1130376
http://hxraid.iteye.com/blog/665095/
相关推荐
- **多路归并排序**:JDK7中的`Arrays.sort()`和`Collections.sort()`方法使用了新的多路归并排序算法,提高了排序性能。 - **Fork/Join框架**:用于并行执行任务,提高计算密集型任务的执行效率。 - **元空间**...
本篇将围绕"jdk 1.8 api"这一主题,深入探讨Java SDK 1.8中的关键知识点,帮助开发者提升效率,实现更高效、更优雅的代码编写。 1. **Lambda表达式** JDK 1.8引入了Lambda表达式,这是对函数式编程的一大迈进。...
【标签】"源码软件" 暗示JDK包含的不仅有二进制文件,还可能包括Java语言的源代码,这对于学习和理解Java的内部工作原理非常有帮助。"windows" 表明这是为Windows操作系统设计的版本。"jdk-7" 指的是Java SE(标准版...
"JDK11_DSA_SrcComment"可能是指一个项目或者资源,它专注于分析和解释JDK 11源代码中的数据结构和算法。这个项目可能是为了帮助开发者更好地理解JDK 11中实现的各种内部机制,从而提升编程技能和效率。 JDK(Java ...
在这个"txtSort"的压缩包中,很可能包含了一个或多个Java源代码文件,用于实现文本文件的排序功能。这些文件可能演示了如何读取文本文件,处理其中的数据(比如字符串或数字),然后进行排序,并可能将排序后的结果...
7. **注解**:提供了一种元数据机制,可以在源代码中添加元信息,用于编译时或运行时的处理,如`@Override`、`@Deprecated`等。 四、反射增强 8. **`java.lang.reflect.ParameterizedType`**:增加了对泛型类型的...
以下是一些关于Java中类排序及其相关的深入知识点: 1. **Java类排序**: - `Comparable`接口:Java中的每个类都可以实现`Comparable`接口,定义自己的比较逻辑。通过实现`compareTo()`方法,可以定义对象之间的...
- **javac**:Java编译器,将源代码编译成字节码。 - **jar**:打包工具,可以创建、更新和提取.jar文件。 - **javadoc**:生成API文档的工具。 - **jconsole**:Java监控和管理控制台,用于监控应用程序...
1. **Java编译器 (javac)**:负责将源代码(.java文件)编译成字节码(.class文件),这是Java程序执行的第一步。 2. **Java虚拟机 (JVM)**:JVM是Java平台的核心,它负责运行编译后的字节码。JDK 7中的JVM在性能和...
3. **多路归并排序**:`Arrays.sort()`方法在Java 7中使用了多路归并排序算法,提高了数组排序的性能。 4. **尝试-with资源**(Try-with-resources):这个新语法结构使得资源管理更加简洁和安全,确保了在finally...
4. **多路归并排序**:Java 7引入了一个新的并发排序算法,提高了`Arrays.sort()`和`Collections.sort()`的性能。 5. **新文件系统API (NIO.2)**:提供了更高级别的文件操作,如路径、文件属性和异步I/O。 6. **...
- **多路归并排序**:在`java.util`包中,JDK7引入了`java.util.Arrays.sort()`方法的改进版,采用了多路归并排序算法,提高了大规模数据排序的性能。 - **try-with-resources**:在`java.lang`包中,新增了`try-...
Java 1.8 源码是 Java 开发者深入理解 JDK 内部工作原理的重要资源,它揭示了 Java 核心库的实现细节。在 JDK 1.8 版本中,引入了许多重要的更新和优化,包括 Lambda 表达式、Stream API、Date 和 Time API 的改进...
3. **方法引用**:除了Lambda表达式,JDK8还提供了方法引用,它可以直接引用类中的静态方法或者对象实例上的非静态方法,进一步简化了代码。例如,`Arrays.sort(list, Comparator.comparing(Person::getName))`。 4...
1. **Java编译器 (javac)**:这是JDK的核心组件之一,用于将源代码编译成可执行的Java字节码。在JDK 1.7中,编译器支持新的语法特性,如钻石操作符()和多线程注解(@SafeVarargs)。 2. **Java运行时环境 (JRE)**...
安装和配置JDK是进行Java编程的第一步,常用命令如`javac`用于编译Java源代码,`java`用于运行已编译的类。 2. **数据类型**:Java有两大类数据类型:基本数据类型(如字节byte、短整型short、整型int、长整型long...
调试是识别和修复代码错误的过程,Java开发工具(JDK)内置的Java Debugger(JDB)可以帮助进行源代码级别的调试。 4. **集合框架**:集合是Java中存储多个对象的容器,包括接口(如`List`, `Set`, `Map`)和实现...
在某些特定情况下,如算法竞赛的在线评测系统,需要在运行时动态编译Java源代码。JSR 199引入了Java编译器API,允许在JDK 6及更高版本中动态编译Java代码。以下是一个简单的示例,展示了如何使用该API编译"Hello ...
排序数组时,既可以使用手动实现的排序算法(如冒泡排序),也可以使用Java的Arrays类提供的sort方法进行自动排序。数组的相关知识点也是面试中的常客,包括如何创建和使用数组,以及数组排序和复制的方法。 九、...