- 浏览: 306319 次
- 性别:
- 来自: 郴州
文章分类
- 全部博客 (70)
- hadoop (0)
- lucene (1)
- heritrix (1)
- webservice (0)
- css+div (0)
- java (29)
- javaweb (3)
- spring (2)
- hibernate (3)
- struts (5)
- struts2 (3)
- tomcat (1)
- map/reduce (0)
- ajax (0)
- android (3)
- oracle (3)
- 面试题 (1)
- 生活 (0)
- 开发工具 (1)
- 面试实习 (0)
- 设计模式 (3)
- 数据结构 (5)
- 论坛 (2)
- flex (3)
- PureMVC (1)
- java,jdk (1)
- sql server (1)
- 报表 (1)
- 算法 (4)
- 工作 (0)
最新评论
-
lp895876294:
第三种方式类似于工厂方法模式了
设计模式之单例模式(三种实现方式) -
xchsh12345:
如果用的是linux服务器呢
解决利用iText导出PDF报表中文乱码两种方式 -
memoryisking:
写的不错,关于Timer和TimeTask的内容网上资料挺多的 ...
Java定时调度 Timer类和TimerTask类 -
linfeng0169:
写的不错~!不过就是解释的不算好!
Calendar类add()与roll()方法的区别 -
u013606853:
好流弊的样子,LZ V5~
hibernate注解详解
最近在暑假实习,没什么任务给我做,不是我不能做,而是还没那资格,毕竟才来了一周多。闲着无事,在网上看看国内的牛公司的招聘要求,想自己能达到他们的要求,准备研究下JDK中的常用类的源代码。今天就来看看java.util.Arrays类。这个类是个数组工具类。主要提供方法sort(),fill(),binarySearch(),还有数组复制等方法。打开源文件,刚超过4千行,不过包括很多注释,那么我在这里主要讲讲这里面涉及的排序算法和查找算法。
一、binarySearch()方法,二分法查找算法,算法思想:当数据量很大适宜采用该方法。采用二分法查找时,数据需是排好序的。 基本思想:假设数据是按升序排序的,对于给定值x,从序列的中间位置开始比较,如果当前位置值等于x,则查找成功;若x小于当前位置值,则在数列的前半段中查找;若x大于当前位置值则在数列的后半段中继续查找,直到找到为止。
二、sort()方法针对引用类型数组采取的算法是归并排序。算法思想:归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列。
三、sort()方法采取的是快速排序算法,算法思想:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
四、针对double,float类型数组排序的sort()方法,采取了先把所有的数组元素值为-0.0d的转换成0.0d,再利用快速排序排好序,最后再还原。
下面是源代码中的方法:
一、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]) { //这段搞不懂,源代码怪怪的,感觉多此一举 double 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; } }
发表评论
-
利用微软翻译API替代被停用谷歌翻译API
2012-02-13 13:37 10418众所周知,谷歌已经不支持翻译API1版本了,现在提供了A ... -
(转)Java回调实现
2011-12-08 14:38 1157Java回调实现 轮询:过10分钟就到女朋友宿舍前面去看她有 ... -
java实现排序算法之插入排序(直接插入排序、折半插入、shell排序)
2011-09-15 09:29 2509插入排序主要包括直接插入排序、shell排序和折半插入等几种排 ... -
java实现排序算法之交换排序(冒泡排序、快速排序)
2011-09-14 21:28 2617交换排序的主体操作是对数组中的数据不断进行交换操作。交换排序主 ... -
java实现排序算法之选择排序(直接选择排序、堆排序)
2011-09-14 20:44 2667常用的选择排序算法有两种:直接选择排序和堆排序。 一、直接选择 ... -
java 实现数据结构之队列
2011-09-14 15:27 12646队列是一种特殊的线性表,它只允许在表的前端(front)进行删 ... -
java 实现数据结构之线性表
2011-09-14 11:44 10697应用程序后在那个的数据大致有四种基本的逻辑结构: 集合:数 ... -
java 实现undo和redo操作链表的一种实现
2011-09-14 10:32 2163今天在iteye论坛逛,发现有这么一道笔试题目:实现一个可以增 ... -
jdbc连接mysql oracle sql server数据库的连接字符串
2011-09-13 10:41 2749jdbc连接mysql oracle sql serv ... -
java 利用label标记退出多重循环
2011-09-10 09:16 12083学过C语言的都知道,有个goto关键字,利用goto关键字可以 ... -
深入JDK源代码之定时操作Timer类和TimerTask类实现
2011-07-26 14:45 3504Timer类是一种线程设施,可以用来实现某一个时间或某 ... -
(转)Java中对象的深复制(深克隆)和浅复制(浅克隆)
2011-07-25 20:31 12261.浅复制与深复制概念 ⑴浅复制(浅克隆) 被复制对象 ... -
深入JDK源代码之LinkedList类
2011-07-26 09:09 1918public class LinkedList<E> ... -
Java中的transient关键字
2011-07-25 14:36 24924transient说明一个属性是临时的,不会被序列化。 下面是 ... -
深入JDK源代码之Observer接口和Observable类实现观察者模式
2011-07-25 11:46 3448一、何为观察者模式? 观察者模式(有时又被称为发布/ ... -
深入JDK源代码之ArrayList类
2011-07-22 11:19 2944public class ArrayList<E&g ... -
java 实现数据结构之栈
2011-07-10 21:51 4676在学数据结构课程 ... -
Java定时调度 Timer类和TimerTask类
2011-07-10 15:38 23944Timer类是一种线程设施,可以用来实现某一个时间或某一段 ... -
Calendar类add()与roll()方法的区别
2011-07-06 22:45 10965JDK API中对这两个方法的说明如下: abstract ... -
Date和Calendar类及日期操作的常用用法
2011-07-06 22:25 13041.计算某一月份的最大 ...
相关推荐
- **多路归并排序**: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方法进行自动排序。数组的相关知识点也是面试中的常客,包括如何创建和使用数组,以及数组排序和复制的方法。 九、...