【Java SE】Arrays类

参考笔记:

Java中Arrays类(操作数组的工具)_java arrays-CSDN博客

Java——Arrays 类详解_java arrays类-CSDN博客


目录

1.Arrays类简介

2.Arrays.toString

2.1 使用示例

2.2 源码

3. Arrays.copyOf 

3.1 使用示例

3.2 源码

4.Arrays.sort

4.1 默认排序使用示例

4.2 定制排序使用实例

4.3 Arrays.sort使用的算法

5.Arrays.binarySearch

5.1 使用示例

5.2 源码

6.Arrays.fill

6.1 使用示例

6.2 源码

7. Arrays.equals

7.1 使用案例

7.2 源码

8. Arrays.deepEquals

9.Arrays.asList

9.1 使用细节和案例


1.Arrays类简介

① Arrays 类是 Java 语言中用于操作数组的一个工具类,提供了多种静态方法来处理数组,包括排序、搜索、填充、比较等操作

 Arrays 类位于 java.util.Arrays 中,该类所有的构造方法被设置为 private ,因此无法创建 Arrays 对象

Arrays 所有方法都是静态的,可以直接通过 "Arrays.方法" 调用

2.Arrays.toString

Arrays.toString(...):返回任何类型数组的字符串形式

2.1 使用示例

import java.util.Arrays;
public class demo {public static void main(String[] args) {int[] arr = {1,2,3};System.out.println(Arrays.toString(arr));}
}

运行结果:

2.2 源码

底层是重载了多个 toString 方法,这里以 String toString(int[ ] a) 为例

public static String toString(int[] a) {if (a == null){//判断数组a是否为空,为空则返回字符串"null"return "null";}int iMax = a.length - 1;//数组a的最后一个元素索引if (iMax == -1){//如果iMax == -1,说明数组a的长度为0return "[]";}StringBuilder b = new StringBuilder();b.append('[');for (int i = 0; ; i++) {b.append(a[i]);//依次将数组的元素追加到字符串中if (i == iMax){//判断是否为最终一个元素,如果是最后一个元素,则返回最终的字符串return b.append(']').toString();}b.append(", ");}
}

3. Arrays.copyOf 

Arrays.copyOf(type[ ] original,int newLength):拷贝任意类型数组,返回值是要拷贝的那个数组类型

original:  原数组

newLength: 指定新数组的长度

补充:也可以理解为从原数组 original 中复制 newLength 个元素到新数组中,如果 newLength 大于原数组的大小,则新数组中大于原数组大小的部分的元素都是类型默认值

3.1 使用示例

import java.util.Arrays;
public class demo {public static void main(String[] args) {int[] arr1 = {1,2,3,4};int arr1_len = arr1.length;int[] tmp1 = Arrays.copyOf(arr1,arr1_len); //指定tmp1数组的长度为arr1_len,并拷贝array数组并赋值到tmp1数组上System.out.println(tmp1.length);System.out.println(Arrays.toString(tmp1)); //打印tmp1数组,[1,2,3,4]System.out.println("-----------------------------");int[] arr2 = {4,5,6,7};int arr2_len = arr2.length;int[] tmp2 = Arrays.copyOf(arr2,2 * arr2_len); //指定tmp2数组的长度为2 * arr2_len,并拷贝array数组并赋值到tmp2数组上,System.out.println(tmp2.length);System.out.println(Arrays.toString(tmp2)); //打印tmp2数组,[4,5,6,7,0,0,0,0]System.out.println("-----------------------------");int[] arr3 = {9,10,11,12};int[] tmp3 = Arrays.copyOf(arr3,2);//指定tmp3数组的长度为2,则只会拷贝array数组的前2个元素到tmp3数组上System.out.println(tmp3.length);System.out.println(Arrays.toString(tmp3));//打印tmp3数组,[9,10]}
}

3.2 源码

4.Arrays.sort

注:Arrays.sort 之前,最好先学一下关于 ComparableComparator 接口,可以看到我写的另外一篇博客:【Java SE】Java比较器:Comparable、Comparator-CSDN博客

默认排序规则:

        String:按照字符串中字符的 ASCII 值进行比较
        Character:按照字符的 ASCII 值来进行比较
        数值类型对应的包装类以及 BigInteger、BigDecimal :按照它们对应的数值大小进行比较
        Boolean:true 对应的包装类实例大于 false 对应的包装类实例
        Date、Time等:后面的日期时间比前面的日期时间大

Arrays.sort(type[ ] a):对整个 a 数组进行默认排序

② Arrays.sort(type[ ] a,int fromIndex,int toIndex):a 数组索引在 [fromIndex,toIndex) 的元素进行默认排序

③ Arrays.sort( T[ ]  a,Comparator <? super T> c):指定比较器 Comparator,对整个 a 数组进行定制排序

④ Arrays.sort( T[ ]  a,int fromIndex,int toIndex,Comparator <? super T> c):指定比较器 Comparator,对 a 数组索引在 [fromIndex,toIndex) 的元素进行定制排序

4.1 默认排序使用示例

import java.util.Arrays;
public class demo {public static void main(String[] args) {//1:Arrays.sort(type[ ] a):int[] arr1 = {-1,10,300,4};Arrays.sort(arr1);//从小到大排序System.out.println(Arrays.toString(arr1));//[-1,4,10,300]//2:Arrays.sort(type[ ] a,int fromIndex,int toIndex):int[] arr2 = {100,10,5,1};Arrays.sort(arr2,0,2);System.out.println(Arrays.toString(arr2));//[10,100,5,1]}
}

4.2 定制排序使用实例

import java.util.Arrays;
import java.util.Comparator;public class demo {public static void main(String[] args) {//方式1.使用匿名内部类传入比较器 Comparator 接口Integer[] arr = {-1,100,4444,23};System.out.println("arr降序排序前:"+Arrays.toString(arr));//对arr实现降序排序Arrays.sort(arr, new Comparator<Integer>() {@Overridepublic int compare(Integer o1, Integer o2) {if(o1 > o2){return -1;//返回任何小于0的整数都可以}return 1;//返回任何大于0的整数都可以}});System.out.println("arr降序排序后:"+Arrays.toString(arr));//[4444,100,23,-1]System.out.println("--------------------------------");//方式2.定制比较器类实现 Comparator 接口StudentAgeComparator sc = new StudentAgeComparator();Student s1 = new Student("小马", 55);Student s2 = new Student("蔡徐坤", 24);Student s3 = new Student("ftt", 17);Student s4 = new Student("jack", 30);Student[] personList  = {s1,s2,s3,s4};System.out.println("personList按年龄降序排序前:");Arrays.stream(personList).forEach(student -> System.out.println(student));//对personList数组按对象的年龄降序排序Arrays.sort(personList,sc);System.out.println("personList按年龄降序排序后:");Arrays.stream(personList).forEach(student -> System.out.println(student));}
}//定制比较器类,按学生的年龄降序排序
class StudentAgeComparator implements Comparator<Student>{@Overridepublic int compare(Student s1, Student s2) {if (s1.age > s2.age){return -1;}else if (s1.age < s2.age){return 1;}else {return 0;}}
}class Student{public String name;public int age;public Student(){}public Student(String name, int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';}
}

运行结果

Debug追溯

这里以上面的代码 Debug 一下看看 Arrays.sort 底层是如何用到我们指定的比较器 Comparator 来进行排序的,如下 GIF 所示:

可以看到,Arrays.sort 底层最终会调用 TimSort 类的 binarySort 方法,该方法中,

if (c.compare(pivot, a[mid]) < 0)right = mid;

c 即为我们传入的比较器 StudentAgeComparator

4.3 Arrays.sort使用的算法

① 基本类型数组(如 int[ ], char[ ] 等):

对于基本数据类型数组,Arrays.sort( ) 方法使用了一种名为 Dual-Pivot Quicksort 的排序算法这是一种改进的快速排序算法,由 Vladimir Yaroslavskiy 提出。它在平均情况下具有 O(n log n) 的时间复杂度,在实践中通常表现良好

② 引用类型数组(如 Integer[ ], String[ ] 等):

对于引用类型数组,Arrays.sort( ) 方法则使用 Timsort 算法。这是一种混合排序算法,结合了归并排序和插入排序的优点。Timsort 是为了优化对部分有序数据的排序而设计的,具有 O(n log n) 的时间复杂度,在实际应用中表现出色

5.Arrays.binarySearch

Arrays.binarySearch为二分查找算法。在已排序的数组中查找指定的某个元素,返回在数组中的索引

① Arrays.binarySearch(type[ ] a,type key):在整个数组 a 中查找元素 key,返回其索引。未找到时返回的是一个特定的负数,为 - (low + 1) 

② Arrays.binarySearch(type[ ] a,int fromIndex,int toIndex,type key):在数组 a 索引为[fromIndex,toIndex) 的元素中查找元素 key,返回其索引

5.1 使用示例

import java.util.Arrays;
public class demo {public static void main(String[] args) {int[] arr1 = {11, 22, 33, 44};int index1 = Arrays.binarySearch(arr1, 44);System.out.println("index of 44: " + index1);//3int[] arr2 = {11, 22, 33, 44};int index2 = Arrays.binarySearch(arr2,0,1,44);System.out.println("index of 44: " + index2);//返回的是一个负数,在[0,1)区间没找到44}
}

5.2 源码

流程图

 binarySearch0源码

binarySearch0 就是传统的二分查找算法,比较简单

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;//相当于mid = (low + high) / 2int midVal = a[mid];//中间元素值if (midVal < key)low = mid + 1;else if (midVal > key)high = mid - 1;elsereturn mid;}return -(low + 1); // 没有找到不是直接返回负一,返回一个特定的负数
}

6.Arrays.fill

① Arrays.fill (type[ ] a,type val):a 数组中的所有元素赋值为 val 

② Arrays.fill (type[ ] a,int fromIndex,int toIndex,type val):a 数组中索引为 [fromIndex,toIndex) 的元素赋值为 val 

6.1 使用示例

import java.util.Arrays;
public class demo {public static void main(String[] args) {//1:Arrays.fill (type[ ] a,type val):将a数组中的所有元素赋值为valint[] arr = new int[10];Arrays.fill(arr, 5);Arrays.stream(arr).forEach(i -> System.out.print(i + " "));System.out.println();System.out.println("-------------------");//2:Arrays.fill (type[ ] a,int fromIndex,int toIndex,type val):将a数组中索引为[fromIndex,toIndex)的元素赋值为valArrays.fill(arr,0,5,4);Arrays.stream(arr).forEach(i -> System.out.print(i + " "));}
}

6.2 源码

public static void fill(int[] a, int val) {for (int i = 0, len = a.length; i < len; i++)a[i] = val;
}public static void fill(int[] a, int fromIndex, int toIndex, int val) {rangeCheck(a.length, fromIndex, toIndex);for (int i = fromIndex; i < toIndex; i++)a[i] = val;
}

7. Arrays.equals

Arrays.equals (type[ ] a,type[ ] a2):返回值为 boolean ;判断一维数组 a 与 一维数组 a2 的内容是否完全相同,两个数组的 type 需要一致

7.1 使用案例

import java.util.Arrays;
public class demo {public static void main(String[] args) {int[] arr1 = {1,2,3,4};int[] arr2 = {1,2,3,4};int[] arr3 = {100,99};System.out.println(Arrays.equals(arr1, arr2));//trueSystem.out.println(Arrays.equals(arr1, arr3));//false}
}

7.2 源码

public static boolean equals(int[] a, int[] a2) {if (a==a2)//地址相同,内容一定相同return true;if (a==null || a2==null)//如果有一个为空,则返回falsereturn false;int length = a.length;if (a2.length != length)//长度不同,则返回falsereturn false;for (int i=0; i<length; i++)//逐个比较if (a[i] != a2[i])return false;return true;
}

8. Arrays.deepEquals

Arrays.deepEquals(Object[ ] a1,Object[ ] a2) :用于比较两个多维数组 a1a2 的内容是否完全相同

使用案例

import java.util.Arrays;public class demo {public static void main(String[] args) {int[][] array1 = {{1, 2, 3}, {4, 5, 6}};int[][] array2 = {{1, 2, 3}, {4, 5, 6}};int[][] array3 = {{1, 2, 3}, {4, 5, 7}};// 比较相同的二维数组boolean isEqual1 = Arrays.deepEquals(array1, array2);System.out.println("array1 和 array2 相等? " + isEqual1); // 输出: true// 比较不同的二维数组boolean isEqual2 = Arrays.deepEquals(array1, array3);System.out.println("array1 和 array3 相等? " + isEqual2); // 输出: false}
}

9.Arrays.asList

Arrays.asList( ) 方法是 Arrays 类的一个静态方法。它可以将传入的数据转换为一个固定大小的列表 List

    public static <T> List<T> asList(T... a) {return new ArrayList<>(a);}

    9.1 使用细节和案例

    形参是 (T.. a) 表示可以接收 0 个或者多个类型为 T(String、八大包装类型、自定义类型) 的参数,编译器会将传入的实参转换为T[ ] a 数组,当然也可以直接传入一个 T[ ] 数组

    返回的 List 的运行类型是 java.util.Arrays.ArrayList,是 Arrays 类的一个内部类,并不是平时经常使用的 java.util.ArrayList。这里要注意区分,很容易弄混

    验证

    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    public class demo {public static void main(String[] args) {//1:传入多个数据List<String> list1 = Arrays.asList("小马","唱跳rap篮球");//2:直接传入数组Integer[] arr1 = {1,2,3};List<Integer> list2 = Arrays.asList(arr1);System.out.println("list1的运行类型:" + list1.getClass());System.out.println("list2的运行类型:" + list2.getClass());//这里new的是java.util.ArrayListList<Object> list3 = new ArrayList<>();System.out.println("list3的运行类型:" + list3.getClass());}
    }

    运行结果:

    返回的 List 不是一个全新的独立集合,而是对原始数组的包装视图:Wrapper View ,具体来说:

    • 共享存储空间:

      • 返回的 List 直接引用原数组的内存地址

      • 修改 List 中的元素 = 直接修改数组对应位置的元素,反之亦然

    • 固定大小特性

      • 由于数组长度不可变,因此返回的 List 会禁止结构性修改,比如不能使用 addremove 来增加或删除元素,这与 java.util.ArrayList 是完全不一样的

    验证:共享存储空间

    import java.util.Arrays;
    import java.util.List;public class demo {public static void main(String[] args) {Integer[] arr = {1, 2, 3, 4, 5};//转换为列表List<Integer> list = Arrays.asList(arr);//修改列表中的元素list.set(0, 10);//打印修改后的列表和数组System.out.println("执行:list.set(0,10)");System.out.println("执行后的列表list: " + list); // 输出: 修改后的列表: [10, 2, 3, 4, 5]System.out.println("执行后的数组arr: " + Arrays.toString(arr)); // 输出: 修改后的数组: [10, 2, 3, 4, 5]System.out.println("------------------------------------------------");//修改数组中的元素arr[1] = 999;//打印修改后的列表和数组System.out.println("执行:arr[1] = 999");System.out.println("执行的列表list: " + list); // 输出: 修改后的列表: [10, 999, 3, 4, 5]System.out.println("执行后的数组arr: " + Arrays.toString(arr)); // 输出: 修改后的数组: [10, 999, 3, 4, 5]}
    }

    运行结果: 

    验证:固定大小特性,即不能使用 add 和 remove,编译可以通过,但会报异常

    从控制台的异常信息可以看到,调用的是父类 AbstractList .add 方法,这里溯源一下,如下图:

    父类 AbstractListadd 方法只是简单的 throw 一个异常,因此在使用 add 方法时会发生异常。 remove 方法也是类似,这里就不再赘述了

    本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/76197.shtml

    如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

    相关文章

    git命令简陋版本

    git push git pull 临时仓库暂存区 ##############创建提交################ git init #创建git地址 git config --global user.name "***YQ1007" git config --global user.email "***gmail.com" git remote…

    6. 王道_网络协议

    1 网络协议和网络模型 2 TCP/IP协议族概览 2.1 四层模型的各层实体 2.2 协议数据单元的转换 2.3 常见协议以及分层 2.4 ifconfig 2.5 本地环回设备 3 以太网 3.1 以太网和交换机 3.2 以太网帧 MAC地址大小 48位 6字节 IP地址 32位 4字节 port 16位 2字节 3.3 ARP协议 4 IP协…

    minecraft.service 文件配置

    minecraft.service 文件配置 # /etc/systemd/system/minecraft.service [Unit] DescriptionMinecraft Fabric Server Afternetwork.target Wantsnetwork-online.target[Service] Usermcfabricuser Groupmcfabricuser WorkingDirectory/minecraft/1.21.1-fabric-server ExecStar…

    python leetcode简单练习(2)

    20 有效括号 方法思路 要判断一个仅由括号组成的字符串是否有效&#xff0c;可以使用栈这一数据结构。核心思路是遍历字符串中的每个字符&#xff0c;遇到左括号时压入栈中&#xff0c;遇到右括号时检查栈顶的左括号是否匹配。若匹配则弹出栈顶元素&#xff0c;否则返回false。…

    AI 数字人短视频数字人口播源码:短视频内容生产的新引擎​

    在当下信息爆炸的时代&#xff0c;短视频已成为主流的信息传播与娱乐方式之一。在如此庞大的市场需求下&#xff0c;如何高效、创新地生产短视频内容成为了行业关注的焦点。AI 数字人短视频数字人口播源码应运而生&#xff0c;为短视频内容生产带来了全新的变革。​ 一、行业背…

    AI对传统IT行业的变革

    传统 IT 行业长期以来面临着诸多挑战。系统类型繁杂、复杂度高&#xff0c;不少环节依赖人工操作&#xff0c;智能化水平偏低&#xff0c;极大地制约了业务运营效率。此外&#xff0c;传统 IT 企业背负沉重的历史包袱&#xff0c;重构系统不仅成本高昂&#xff0c;由于现有系统…

    mapbox基础,使用geojson加载cluster聚合图层

    👨‍⚕️ 主页: gis分享者 👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍⚕️ 收录于专栏:mapbox 从入门到精通 文章目录 一、🍀前言1.1 ☘️mapboxgl.Map 地图对象1.2 ☘️mapboxgl.Map style属性1.3 ☘️circle点图层样式二、🍀使用geojson加…

    Git回退文件到指定提交

    你可以使用 git checkout 命令将某个文件回退到指定提交的版本。以下是具体步骤&#xff1a; 1. 找到目标提交的哈希值 git log --oneline通过 git log 查看提交历史&#xff0c;找到你要回退到的目标提交的哈希值&#xff08;例如 abc123d&#xff09;。 2. 回退文件到指定提…

    如何屏蔽mac电脑更新提醒,禁止系统更新

    最烦mac的系统更新提醒了&#xff0c;过几天就是更新弹窗提醒&#xff0c;现在可以直接禁掉了&#xff0c;眼不见心不乱&#xff0c;不然一升级&#xff0c;开发环境全都不能用了&#xff0c;那才是最可怕的&#xff0c;屏蔽的方法也很简单&#xff0c;就是屏蔽mac系统更新的请…

    mac m1/m2/m3 pyaudio的安装

    google了很多方法&#xff0c;也尝试了 issue68的方法&#xff0c; 但是均失败了&#xff0c;但是问deepseek竟然成功了&#xff0c;下面是deepseek r1给出的方法。在M3 pro芯片上可以成功运行. 安装homebrew /bin/bash -c "$(curl -fsSL https://raw.githubusercontent…

    hackmyvm-JO2024

    arp-scan -l nmap -sS -v 192.168.222.202 gobuster dir -u http://192.168.222.202 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x php -b 301,401,403,404 访问/preferences.php 看一下cookie 解密 TzoxNToiVXNlclByZWZlcmVuY2VzIjoyOntzOjg6Imxhbmd1…

    从零开始学习SQL

    1.1 MySQL概述 1. 数据管理技术的发展过程 数据库技术是应数据管理任务的需要而产生的 a. 什么是数据管理 ** 对数据进行收集、分类、组织、编码、存储、检索和维护一系列活动的总和 **b. 数据管理技术的发展过程 人工管理阶段&#xff08;20世纪50年代中之前&#xff09;…

    输电线路在线监测通信规约,即I1协议

    文章目录 概要整体架构流程数据帧格式技术细节 概要 输电线路在线监测系统 transmission lines online monitoring system 监测输电线路设备本体、气象环境、通道状况等信息&#xff0c;定性或定量分析输电线路运行状况的应用系 统。一般包括主站系统、监测装置以及主站系统与…

    【AI】Orin NX+ubuntu22.04上移植YoloV11,并使用DeepStream测试成功

    【AI】郭老二博文之:AI学习目录汇总 1、烧写系统 新到的开发板,已经烧写好Ubuntu系统,版本为22.04。 如果没有升级到Ubuntu22.04,可以在电脑Ubuntu系统中使用SDKManager来烧写Ubuntu系统,网络情况好的话,也可以直接将CUDA、cuDNN、TensorRT、Deepstream等也安装上。 2…

    C++之输入与输出

    文章目录 C 输入输出 (I/O) 详解基本 I/O 组件&#xff08;input / output&#xff09;基本输出 (cout)基本输入 (cin)格式化输出文件 I/O字符串流常见 I/O 方法比较错误处理其他保留小数 C 输入输出 (I/O) 详解 C 使用标准库中的 iostream 库来处理输入输出操作。主要包括以下…

    流动的梦境:GPT-4o 的自回归图像生成深度解析

    每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

    eBay多账号安全运营技术体系:从环境隔离到智能风控的工程化实践

    一、多账号运营风险模型解析 &#xff08;技术化重构关联检测机制&#xff09; 环境指纹维度&#xff1a; 浏览器指纹参数&#xff1a;Canvas/WebGL渲染特征&#xff08;差异度要求≥98%&#xff09; 设备指纹参数&#xff1a;GPU型号/声卡特征&#xff08;识别准确率92%&…

    Vue 3 模板引用(Template Refs)详解与实战示例

    Vue 3 模板引用&#xff08;Template Refs&#xff09;详解与实战示例 引言 在 Vue 开发中&#xff0c;通常推荐使用 响应式数据 (ref 和 reactive) 进行数据绑定&#xff0c;而不是直接操作 DOM。但是&#xff0c;在某些情况下&#xff0c;我们确实需要访问某个组件或 DOM 元…

    《Operating System Concepts》阅读笔记:p495-p511

    《Operating System Concepts》学习第 44 天&#xff0c;p495-p511 总结&#xff0c;总计 17 页。 一、技术总结 1.cache (1)定义 A cache is a region of fast memory that holds copies of data. (2)cache 和 buffer 的区别 The difference between a buffer and a cac…

    通过Spring Boot集成WebSocket进行消息通信

    文章目录 通过Spring Boot集成WebSocket进行消息通信1. 创建 Spring Boot 项目2. 添加 WebSocket 依赖3. 配置 WebSocket4. 创建 WebSocket 处理器5. 创建控制器&#xff08;可选&#xff09;6. 前端页面测试7. 运行项目注意事项 通过Spring Boot集成WebSocket进行消息通信 1.…