Arrays类及其方法分析

从源码分析Arrays类的常用方法 文章目录Arrays类概述常用方法排序sort搜索binarySearch比较equals填充fill赋值copyOf将数组转换成列表asList获取哈希码hashCodetoString Arrays类概述 Arrays类在源码中的声明: /** * This class contains various methods for manipulating arrays (such as * sorting and searching). This class also contains a stati 阅读详情

排序

Arrays.sort()方法,对于基本数据类型采用DualPivotQuicksort(多路快排)进行排序,对于引用类型的数组,采用MergeSort(归并排序)进行排序,下面我们分别来讲一下这两类排序算法。

对基本类型数组的排序

Java中的八种基本数据类型,除了boolean,其它七种都是可以且有需求进行排序的,如果一个数组是单一的基础类型,形如int[] data, long data[]都可以直接使用Arrays.sort()进行排序。对于所有可排序的基本类型,都是采用DualPivotQuicksort来进行排序的。首先来看个例子:

package com.adam.java.algo.arrays;

import java.util.Arrays;

import org.junit.Test;

public class ArraysBasicTest {

@Test

public void testSortInteger() {

int data[] = { 10, 8, 9, 1, 2, 5, 98, 3, 7, 66 };

Arrays.sort(data);

for (int i : data) {

System.out.print(i + " ");

}

}

@Test

public void testSortChar() {

char data[] = { 'D', 'B', 'E', 'C', 'H', 'A', 'Y', 'G', 'I', 'O' };

Arrays.sort(data);

for (char i : data) {

System.out.print(i + " ");

}

}

}

输出:

1 2 3 5 7 8 9 10 66 98

A B C D E G H I O Y

这里我们要看一下Arrays.sort()采用的算法了,我们查看下JDK源码。

/**

* Sorts the specified array into ascending numerical order.

*

* <p>Implementation note: The sorting algorithm is a Dual-Pivot Quicksort

* by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm

* offers O(n log(n)) performance on many data sets that cause other

* quicksorts to degrade to quadratic performance, and is typically

* faster than traditional (one-pivot) Quicksort implementations.

*

* @param a the array to be sorted

*/

public static void sort(int[] a) {

DualPivotQuicksort.sort(a, 0, a.length - 1, null, 0, 0);

}

发现所有的基本排序都是直接使用DualPivotQuicksort.sort()进行的,因此,我们有必要了解一下DualPivotQuicksort的原理。基本思想就是:

元素个数从1-47,则直接使用插入排序进行排序。

元素个数从47-286,则使用多路快速排序。

元素个数大于286,则使用归并排序

这里我们研究下多路快排的原理,首先我们回顾一下经典快排是怎么实现的。

经典快排实现思路:

1. 找一个中轴,一般情况选取数组的第一个元素。

2. 定义两个指针,分别指向最左边和最右边,从右边开始遍历,如果大于中轴,则右边指针左移一位,如果小于中轴,则互换位置;同理再从左边开始和中轴比较,如果小于中轴,指针向右移动,如果大于中轴,则互换位置。

3. 一趟排序下来,中轴左边的都小于中轴,右边的都大于中轴。

4.递归的对子数组进行如上操作,不稳定,时间复杂度最优情况O(nlogn),最坏情况为基本有序时为O(n2)。关于快排的详细说明,请参考另一篇博文。

多路快排实现思路:

1. 选取两个中轴P1, P2。

2. 假设P1<P2,否则交换。

3. 过程中原数组会分为四个部分:小于中轴1,大于中轴2,介于两个中轴之间,未排序部分(刚开始除了两个中轴,其它元素都属于这部分)。

4. 开始后,从未排序部分选取一个数,和两个中轴作比较,然后放到合适的位置,一直到未排序部分无数据,结束一趟排序。

5. 递归地处理子数组,稳定排序,时间复杂度稳定为O(nlogn)。

对引用类型的数组排序

我们举个例子,对User类型的数组,根据年龄进行排序,此处用到Comparator接口,更多关于Comparator的介绍,请点击。

新建一个User类:

package com.adam.java.algo.arrays;

public class User {

private String name;

private String gender;

private int age;

public User(String name, String gender, int age) {

this.name = name;

this.gender = gender;

this.age = age;

}

/**

* @return the name

*/

public String getName() {

return name;

}

/**

* @param name

* the name to set

*/

public void setName(String name) {

this.name = name;

}

/**

* @return the gender

*/

public String getGender() {

return gender;

}

/**

* @param gender

* the gender to set

*/

public void setGender(String gender) {

this.gender = gender;

}

/**

* @return the age

*/

public int getAge() {

return age;

}

/**

* @param age

* the age to set

*/

public void setAge(int age) {

this.age = age;

}

}

再建一个排序类:

package com.adam.java.algo.arrays;

import java.util.Comparator;

public class UserComparator implements Comparator<User> {

@Override

public int compare(User o1, User o2) {

return o1.getAge() - o2.getAge();

}

}

测试:

package com.adam.java.algo.arrays;

import java.util.Arrays;

public class ArraysTest {

public static void main(String[] args) {

User[] users = new User[]{new User("egg", "male", 26), new User("Kity", "Female", 25), new User("Pole", "male", 23), new User("Jack", "male", 28)};

Arrays.sort(users, new UserComparator());

for (User user : users) {

System.out.println("name: " + user.getName() + " ,age: "+user.getAge());

}

}

}

输出:

name: Pole ,age: 23

name: Kity ,age: 25

name: egg ,age: 26

name: Jack ,age: 28

这就是一个简单的对引用类型的数组排序的例子,在JDK1.8中,对引用类型的排序,采用的归并排序的算法。

在JDK1.8中,对于排序方法,还引入了parallelSort(),每个sort()都有对应的并行排序方法,当数组元素个数大于2的13次(8196)后采用parallelSort()。

搜索

在用二分搜索对一个已经有序的数组进行查找,如果存在,返回key在该数组中的位置,如果不存在,返回负数,值为:-插入点-1,举个例子:

假设一个排好序的数组是:1,6,8,10,12,如果key为7,则返回值为-3,因为7应该插入到6,8之间,所以插入点为2(下标从0开始),所以返回值为-2-1=-3。

ArrayToList

这方面,是将一个数组,转换成一个list形式,注意:通常情况下,如果该数组是int型的,如int[[ data,这种情况会出现并不是直接将该数组中的所有元素转成新的list的所有元素,而是将整个数组,转成list的一个元素,这是一种特殊情况,将类型int改成Integer就可以避免了。此处感谢网友@Java我人生指正!

/**

* Returns a fixed-size list backed by the specified array. (Changes to

* the returned list "write through" to the array.) This method acts

* as bridge between array-based and collection-based APIs, in

* combination with {@link Collection#toArray}. The returned list is

* serializable and implements {@link RandomAccess}.

*

* <p>This method also provides a convenient way to create a fixed-size

* list initialized to contain several elements:

* <pre>

* List<String> stooges = Arrays.asList("Larry", "Moe", "Curly");

* </pre>

*

* @param <T> the class of the objects in the array

* @param a the array by which the list will be backed

* @return a list view of the specified array

*/

@SafeVarargs

@SuppressWarnings("varargs")

public static <T> List<T> asList(T... a) {

return new ArrayList<>(a);

}

根据注释得知,返回的新list是个定长的list,而且并不可以就行添加或者删除元素,否则报:java.lang.UnsupportedOperationException异常。这是为什么?因为此处的ArrayList并非我们常用的java.util.ArrayList类,而是Arrays类的一个内部类,因为继承了AbstractList,所有可以和list相互转换,但是不具备add和remove等操作。

CopyOf

Arrays.copyOf()用来进行数组的复制,返回一个全新的数组,可以传入一个参数来定义新数组的大小,如果传入的数小于原来的数组长度,则直接把原数组多余的部分剪掉,如果传入的值大于原数组,则新数组多余的部分补默认值(对于int类型的,补0)。

HyperMesh实战:用Field工具搞定复杂载荷映射(附TCL脚本示例) 本文深入探讨了HyperMesh中Field工具在复杂载荷映射中的高级应用,包括从CSV到有限元网格的温度场映射全流程、稀疏数据处理技巧及TCL自动化脚本示例。通过Field工具,工程师可以高效实现CFD温度场到结构网格的精准映射,显著提升有限元分析的精度与效率。 阅读详情

相关推荐

python数据处理与分析案例,python如何进行数据处理

大家好,本文将围绕基于python的数据处理案例展开说明,python数据处理与分析案例是一个很多人都想弄明白的事情,想搞清楚python如何进行数据处理需要先了解以下几个事情。大家好,小编来为大家解答以下问题,python数据处理案例步骤及其代码,python数据处理与分析教程,今天让我们一起来看看吧!哈喽~今天学习记录的是数据分析实训小案例。就用这个案例来好好巩固一下 python 数据分析三剑客。

a17348的博客 1240

Java基础——Arrays类的排序方法

public static void sort(类型[] a, Comparator

weixin_61275790的博客 1698

别再死记硬背了!用‘小乌龟’实战图解ROS1核心指令(rosnode/rostopic/rosparam保姆级手册)

本文通过经典的turtlesim乌龟仿真器,以可视化实战方式讲解ROS1核心指令(rosnode/rostopic/rosparam),帮助初学者摆脱死记硬背,在操控乌龟的过程中轻松掌握节点管理、话题通信和参数设置等ROS1核心概念。

weixin_28731223的博客 371

Java Arrays类进行数组排序详解

Java Arrays类进行数组排序   排序算法,基本的高级语言都有一些提供。C语言有qsort()函数,C++有sort()函数,java语言有Arrays类(不是Array)。用这些排序时,都可以写自己的排序规则。 Java API对Arrays类的说明是:此类包含用来操作数组(比如排序和搜索)的各种方法。 1.对基本数据类型的数组的排序 说明:(1)Arrays类中的sort()使用的是“...

weixin_38061311的博客 718

实战分享:如何用Jetson Nano+HM30图传搭建低空YOLOv5检测系统(附VNC避坑指南)

本文详细介绍了如何利用Jetson Nano和HM30图传搭建低空YOLOv5检测系统,重点解决了无人机应用中的硬件连接和VNC延迟优化问题。通过对比WiFi直连与图传方案的优劣,提供了网络配置、VNC优化及YOLOv5模型加速的实战技巧,帮助开发者实现高效稳定的低空目标检测系统。

weixin_29174385的博客 110

硬件电路(22)-TTL和232切换电路

工作中会遇到TTL和232电平的通信的状态,为了实现一种便捷的切换方式,参考了一些文章,提供一种电路方便大家使用。

剑藏锋的博客 1868

Java之美[从菜鸟到高手演练]之Arrays类及其方法分析

本章主要介绍一下 java.util.Arrays类的重点方法,包括怎么使用及实现原理。这是一个算法类,主要是辅助数组类实现一些排序、搜索等功能,同时也支持数组到List的转换。本章系Java之美[从菜鸟到高手演练]系列之Arrays类及其方法分析,如果有任何问题,欢迎通过上面任何一种方式与我联系!

智慧演绎,无处不在 2万+

SSE 传输过程中,丢失空格和回车符,怎么解决?

Server - Sent Events(SSE)即服务器发送事件,是 HTML5 中的一项 Web API,用于实现服务器向客户端浏览器推送实时数据的功能。

938

八大排序方法及对Arrays类的排序实现探讨

1.插入排序—直接插入排序(Straight Insertion Sort) 基本思想: 将一个记录插入到已排序好的有序表中,从而得到一个新,记录数增1的有序表。即:先将序列的第1个记录看成是一个有序的子序列,然后从第2个记录逐个进行插入,直至整个序列有序为止。 要点:设立哨兵,作为临时存储和判断数组边界之用。 如果碰见一个和插入元素相等的,那么插入元素把想插入的元素放在相等...

weixin_30681615的博客 213

备赛电赛学习硬件篇(六):复位电路工作原理

上电复位的工作过程是在加电时,复位电路通过电 容加给RST端一个短暂的高电平信号,此高电平信号随着Vcc对电容的充电过程而逐渐回落,即RST端的高电平持续时间取决于电容的充电时间。在图2的复位电路中,当Vcc掉电时,必然会使RST端电压迅速下降到0V以下,但是,由于内部电路的限制作用,这个负电压将不会对器件产生损害。在上电或复位过程中,控制CPU的复位状态:这段时间内让CPU保持复位状态,而不是一上电或刚复位完毕就工作,防止CPU发出错误的指令、执行错误操作,也可以提高电磁兼容性能。

m0_61022809的博客 6774

PyQt(Python+Qt)学习随笔:PyQt界面派生类构造方法中super方法的使用

老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 在《第15.7节 PyQt入门学习:PyQt5应用构建详细过程介绍》和订阅专栏《第二章、PyQt5应用构建详细过程介绍》中,老猿介绍界面派生类的构造方法如下: class MediaPlayerWin(QtWidgets.QWidget,Ui_UI_PlayerWin): def __i...

老猿Python 2711

Java Arrays类排序方法

Arrays类排序方法

小钟不想敲代码 1513

零基础入门Simulink——基于Simulink的MIMO-OFDM系统仿真建模示例

MIMO概述MIMO技术利用多个天线进行信号发送和接收,通过空间复用来提高数据传输速率,或通过空间分集来增强信号的可靠性。OFDM概述OFDM是一种将高速率数据流分成多个低速数据流并行传输的技术,每个子载波都采用调制方式(如BPSK、QPSK),并通过IFFT/FFT变换实现串并转换。MIMO-OFDM优势结合了MIMO的空间分集增益与OFDM对抗多径效应的能力,适用于宽带无线通信系统。提供了更高的数据速率和更好的频谱效率,是现代无线通信标准(如4G LTE、5G NR等)的核心技术之一。

amy_mhd的博客 891

Arrays类常用方法详解(源码分析)

将指定的值分配给指定数组值的指定范围的每个元素。二分搜索,Arrays类中定义的可用来以二分搜索的方法是用于在有序数组中查找特定元素的索引。并返回该值的下标,没有的话返回,它会返回一个负数,这个负数是目标元素应该插入的位置的相反数减1。众所周知,equals方法是比较里面的内容是否相等的方法,那Arrays中的equals()方法,就是重写了Object中equals(),用来比较数组中的内容是否相等的方法。与equals方法一样,Arrays类中的toString()与我们所知道的。

yygr的博客 390

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Arrays类分析

Arrays类的一些功能: sort方法,对数组进行排序(采用快排) parallelSort 多路排序 二分查找 比较相等 。 用值去填充数组 拷贝数组 计算hashCode和toStrin

hyEnA_Tiger的博客 320

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

Arrays类【JDK源码分析】

Arrays类【JDK源码分析】

小心星的博客 290

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

数组、内存分析、Arrays类、冒泡排序(重点)、稀疏数组

数组 数组概述: 数组是相同数据类型的数据的有序集合 数组中的每一个数据被称为数组的元素,可以通过索引下标来访问 数组的声明创建: //声明数组 //首选的方法:数据类型 变量名 ; int[] array0; //下面的方法也可以声明数组,不推荐使用 int array1[]; //数字4代表长度,即该数组中可存放的...

RElim的博客 215

Arrays类的几个方法及源码分析

Arrays类 方法 public static String toString(int[] a) 返回指定数组内容的字符串表示形式。 字符串表示形式由数组的元素列表组成,括在方括号("[]")中。 相邻元素用字符 ", "(逗号加空格)分隔。 这些元素通过 String.valueOf(int) 转换为字符串。 如果 a 为 null,则返回 "null"。 

whaleluo的博客 705

04数组(创建,初始化及内存分析,基本特点,二维数组,Arrays类,冒泡排序)

数组(array) 1数组创建 首先必须声明(定义)数组变量,才能在程序中使用数组,下面是声明(定义)数组的语法: int[] name; //首选的方法 或 int name[]; //效果相同,但不是首选方法 Java语言使用new操作符来创建数组: //变量类型 变量名字 = 变量值 //数组类型[] 数组名字 = new 数组类型[数组长度] int[] name = new int[10]; //创建一个长度为10的int数组 //给数组中元素赋值 name[0] = 1; name

qq_42735509的博客 300

Arrays类中sort源码分析

public static void sort(int[] a) { sort1(a, 0, a.length);    }  private static void sort1(int x[], int off, int len) { // Insertion sort on smallest arrays if (len      for (int i=off; i  for (int

Jim20的专栏 1042

方法 方法的重载 可变参数 ; 数组的内存分析(堆,栈),初始化,使用 Arrays类 稀疏矩阵变三元组

方法 何谓方法 System.out.println():调用系统类里面的标准输出对象out中的方法,方法叫做println() 分别为 类 对象 方法。 Java方法是语句的集合,他们在一起执行一个功能 方法是解决一类问题的步骤的有序组合 方法包含于类或者对象中 方法在程序中被创建在其他地方被引用 设计原则:保持方法的原子性,一个方法只完成一个功能,有利于后期的扩展。 类似于C语言种的函数 方法的重载 方法的重载的规则: 方法名称必须相同 参数列表必须不同(个数不同 或 类型不同 、参数排列顺序

weixin_45964083的博客 181

Java学习第四天-可变参数-数组分析-数组越界-Arrays类

可变参数 有时候我们会因为参数类型不确定而大量书写重复重载方法,为了精简代码,Java为我们提供了可变参数。 可变参数在一个重载中最多存在一个,且必须处于参数的最后一个。 使用方法是 “函数名(可变参数类型…参数名)”。 个人认为当有多个参数传入的时候,参数变成了一个数组参数。 递归 算法思想,参见C语言。 数组 与C语言类似。 Java在兼容C语言部分语法的时也提供了特有的数组声名方式,方式如下 “数组类型 [] 数组名”。 数组内存分析 在定义数组的时候,内存中会开辟一块内存用于存放数组实际内存的位置,

weixin_45731448的博客 191

7.Java集合-Arrays类实现原理及源码分析

Java集合---Arrays类源码解析 转自:http://www.cnblogs.com/ITtangtang/p/3948765.html 一、Arrays.sort()数组排序 JavaArrays中提供了对所有类型的排序。其中主要分为Primitive(8种基本类型)和Object两大类。   基本类型:采用调优的快速排序;   对象类型:采用改进的归并排序。 ...

weixin_34143774的博客 103

03Java方法和数组_回顾----方法重载、命令行传参、可变参数、Java数组、Arrays类、稀疏数组、Java内存分析、IDEA技巧

03Java方法和数组_回顾----方法重载、命令行传参、可变参数、Java数组、Arrays类、稀疏数组、Java内存分析、IDEA技巧什么是方法方法的重载命令行传参可变参数Java 数组Java Arrays类稀疏数组Java 内存分析IDEA 技巧 什么是方法 System.out.println() 中 System是类,out是对象,println()是方法 形参是定义的时候参数,实参是实际外部传入的参数 Java都是值传递而不是引用传递,值传递就有拷贝的概念 方法的重载 就是方法名字相同,形参

从头再来的博客 194
上一篇: Hadoop原理及架构
下一篇: spring框架初识
java1856905
博客等级 码龄8年 100粉丝 249原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值