0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Arrays的copyOf,copyOfRange和fill方法

科技绿洲 来源:了不起 作者:了不起 2023-09-25 14:12 次阅读

在本文中,我们来看看 java.util.Arrays ,我们可以使用 Arrays 创建,比较,排序,搜索,stream 和转化数组。

创建

我们来看看,使用Arrays 怎么创建一个新的数组,一般来说,我们可以使用Arrays 的 copyOf , copyOfRange 和 fill 方法。

copyOf 和 copyOfRange

要使用copyOfRange,我们需要一个原始数组和我们想要复制的开始索引(包括)和结束索引(不包括)。 我们先定一个数组 intro。

String[] intro = new String[] { "once", "upon", "a", "time" };
String[] abridgement = Arrays.copyOfRange(storyIntro, 0, 3); 

assertArrayEquals(new String[] { "once", "upon", "a" }, abridgement); 
assertFalse(Arrays.equals(intro, abridgement));

要使用 copyOf ,,我们需要使用intro和一个目标数组大小,然后我们会得到一个该长度的新数组。

String[] revised = Arrays.copyOf(intro, 3);
String[] expanded = Arrays.copyOf(intro, 5);

assertArrayEquals(Arrays.copyOfRange(intro, 0, 3), revised);
assertNull(expanded[4]);

注意,如果我们的目标尺寸大于原始尺寸,copyOf会用 null 填充数组。

fill

另一种方法,我们可以创建一个固定长度的数组,就是填充,当我们想要一个所有元素都相同的数组时,这个方法很有用。

String[] stutter = new String[3];
Arrays.fill(stutter, "once");

assertTrue(Stream.of(stutter).allMatch(el - > "once".equals(el));

注意,我们需要事先将数组实例化,而不是像String[] filled = Arrays.fill("once", 3);,因为这个特性是在语言中出现泛型之前引入的。

比较

我们先走来看看 Arrays 的比较方法

equals 和 deepEquals

我们可以使用 equals 进行简单的数组大小和内容比较。 如果我们添加一个null作为其中一个元素,内容检查就会失败。

assertTrue(Arrays.equals(new String[] { "once", "upon", "a", "time" }, intro));
assertFalse(Arrays.equals(new String[] { "once", "upon", "a", null }, intro));

当我们有嵌套或多维数组时,我们可以使用deepEquals不仅检查顶层元素,还可以递归地执行检查。

Object[] story = new Object[] { intro, new String[] { "chapter one", "chapter two" }, end };
Object[] copy = new Object[] { intro, new String[] { "chapter one", "chapter two" }, end };

assertTrue(Arrays.deepEquals(story, copy));
assertFalse(Arrays.equals(story, copy));

注意,这里 deepEquals 是通过的,但equals却失败了。这是因为deepEquals在每次遇到数组时都会调用自己,而equals只是比较子数组的引用。

hashCode 和 deepHashCode

我们使用hashCode来计算一个基于数组内容的整数

Object[] looping = new Object[]{ intro, intro }; 
int hashBefore = Arrays.hashCode(looping);
int deepHashBefore = Arrays.deepHashCode(looping);

现在,我们将原数组的一个元素设置为空,并重新计算哈希值。

intro[3] = null;
int hashAfter = Arrays.hashCode(looping);

deepHashCode检查嵌套数组的元素数量和内容是否匹配。 如果我们用deepHashCode重新计算。

int deepHashAfter = Arrays.deepHashCode(looping);

现在,我们能够看到这两个方法的不同。

assertEquals(hashAfter, hashBefore);
assertNotEquals(deepHashAfter, deepHashBefore);

deepHashCode是我们在数组上使用HashMap和HashSet等数据结构时使用的基础计算。

排序和搜索

排序

如果我们的元素是原始类型,或者它们实现了 Comparable 接口,我们可以使用sort来执行排序。

String[] sorted = Arrays.copyOf(intro, 4);
Arrays.sort(sorted);

assertArrayEquals(new String[]{ "a", "once", "time", "upon" }, sorted);

请注意,排序会使原始引用发生变化,这就是为什么我们在这里进行复制。
排序将对不同的数组元素类型使用不同的算法。原始类型使用quicksort,对象类型使用Timsort。对于一个随机排序的数组,两者的平均情况都是O(n log(n))。
从Java 8开始,parallelSort可用于并行排序, 它提供了一种使用几个Arrays.sort任务的并发排序方法。

搜索

如果我们有一个排序的数组,那么我们可以在 O(log n) 中完成,我们可以用 binarySearch 来完成这样的任务。

int exact = Arrays.binarySearch(sorted, "time");
int caseInsensitive = Arrays.binarySearch(sorted, "TiMe", String::compareToIgnoreCase);

assertEquals("time", sorted[exact]);
assertEquals(2, exact);
assertEquals(exact, caseInsensitive);

如果我们没有提供一个比较器作为第三个参数,那么 binarySearch 就默认我们的元素类型是可比较的。如果我们的数组没有被首先排序,那么 binarySearch 将不会像我们所期望的那样工作。

我们都知道Arrays在Java 8中进行了更新,包含了Stream API的方法,如parallelSort、stream和setAll等。

stream 使我们能够完全访问我们的数组的Stream API。

Assert.assertEquals(Arrays.stream(intro).count(), 4);

exception.expect(ArrayIndexOutOfBoundsException.class);
Arrays.stream(intro, 2, 1).count();

我们可以为流提供包容性和排他性指数,但是如果指数失序、为负数或超出范围,我们应该判断 ArrayIndexOutOfBoundsException。

转化

toString、asList和setAll给了我们几种不同的方法来转换数组。

toString和deepToString

我们可以通过toString获得原始数组的可读版本的一个好方法。

assertEquals("[once, upon, a, time]", Arrays.toString(storyIntro));

当数组有嵌套的时候,我们必须再次使用deepToString 来打印嵌套数组的内容。

assertEquals(
    "[[once, upon, a, time], [chapter one, chapter two], [the, end]]",
    Arrays.deepToString(story));

asList

在所有的数组方法中,最方便我们使用的是asList。我们有一个简单的方法把数组变成一个列表。

List  String  > rets = Arrays.asList(storyIntro);

assertTrue(rets.contains("upon"));
assertTrue(rets.contains("time"));
assertEquals(rets.size(), 4);

返回的列表将是一个固定的长度,而且无法添加或删除元素,还要注意的是,asList会返回这个ArrayList的类型,和我们平常在使用的ArrayList 并不一样。在调试的时候,就可能是非常具有欺骗性的,我们在写的过程中特别要注意。

setAll

通过setAll,我们可以用一个 functional interface 来设置一个数组的所有元素。下面的代码现将位置索引作为一个参数传入到getWord方法中。

String[] longAgo = new String[4];
Arrays.setAll(longAgo, i - > this.getWord(i)); 
assertArrayEquals(longAgo, new String[]{"a","long","time","ago"});

当然,异常处理是使用lambda的一个比较棘手的部分。所以请记住,如果lambda抛出一个异常,那么Java就不会定义数组的最终状态。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 数据结构
    +关注

    关注

    3

    文章

    564

    浏览量

    39969
  • 数组
    +关注

    关注

    1

    文章

    409

    浏览量

    25688
  • Arrays
    +关注

    关注

    0

    文章

    6

    浏览量

    6374
  • Fill
    +关注

    关注

    0

    文章

    4

    浏览量

    2852
收藏 人收藏

    评论

    相关推荐

    Characterizing and Modeling the Impact of Power/Ground Via Arrays on Power Pl

    Characterizing and Modeling the Impact of Power/Ground Via Arrays on Power Plane
    发表于 07-01 18:03

    Altium中Fill,Polygon Pour,Plane的区别和用法

    `Fill表示绘制一块实心的铜皮,将区域中的所有连线和过孔连接在一块,而不考虑是否属于同一个网络。假如所绘制的区域中有VCC和GND两个网络,用Fill命令会把这两个网络的元素连接在一起,这样就有
    发表于 01-15 19:33

    AD中关于Fill,Polygon_Pour,Plane的区别和用法

    在 AD 中,大面积覆铜有 3 个重要概念:Fill填充Polygon Pour(灌铜)Plane(平面层)这 3 个概念对应 3 种的大面积覆铜的方法,下面我将对其做详细介绍:一.FillFill
    发表于 08-28 14:30

    填充FILL ,原理图导网络到PCB,FILL没网络的处理方法分享!

    问:我在封装的焊盘上填充了一个FILL原理图导网络到PCB,这个FILL没网络;只有焊盘有网络;有什么方法可以解决吗答:异形焊盘确实是这样的,解决办法就是Ctrl+H然后给他赋予网络就可以了,快捷键是选中物理连接
    发表于 09-11 03:02

    低电容TVS ESD ARRAYS保护器件

    时,一些*敏感的组件可能被低至20V以下的ESD电压损坏,过去所采用的传统保护方法,如火花放电器、齐纳二极管、RC网络和箝位二极管已经不能满足。      TVS ESD ARRAYS系列低电压低电容
    发表于 03-26 13:16

    fill_n的主要作用是什么

    fill_n的主要作用是什么?fill_n指令包含哪几个?
    发表于 09-30 09:15

    THAT300series Matched Transistor Arrays

    Array ICS作为 专业级的低噪音,高性能匹配阵列晶体管ICS。低噪音:0.75nV/√HZ 高速度:fT =350MHZ。可以很好的兼容ADI和TI的相关Matched Transistor Arrays/Matched Monolithic Transistor Arra
    发表于 04-26 11:29

    Allegro Fill铺铜教程

    Allegro Fill铺铜教程 如下我们将以四层印制板为例来进行讲解! 1.点击颜色按钮 ,在颜色设置的“Geometry”栏中设置PCB边框线颜色
    发表于 03-21 19:02 9759次阅读
    Allegro <b class='flag-5'>Fill</b>铺铜教程

    AD中关于Fill

    在AD中,大面积覆铜有3个重要概念: Fill(铜皮)3 Polygon Pour(灌铜) Plane(平面层)3 这3个概念对应3种的大面积覆铜的方法,对于刚接触AD的用户来说,很难区分。
    发表于 09-12 16:13 0次下载

    Digital Signal Processing with Field Programmable Gate Arrays

    FPGA,数字信号处理:Digital Signal Processing with Field Programmable Gate Arrays
    发表于 12-17 11:58 51次下载

    Java数组的常用方法_Java:数组工具类Arrays类的常用方法的用法及代码

    本文主要详细介绍了Java数组的常用方法以及数组工具类Arrays类的常用方法的用法及代码。
    发表于 01-29 10:25 2786次阅读

    S7-1200填充块指令(U)FILL_BLK使用说明

    (U)FILL_BLK指令是当EN条件满足时,实现用输入变量批量填充输出区域的功能。
    的头像 发表于 01-13 10:33 2498次阅读

    Java中Arrays类是什么 Arrays常用方法

    了解Arrays类的概念 **A****rrays** 位于java.util包下,Arrays是一个操作数组的工具类。 Arrays常用方法
    的头像 发表于 02-17 15:11 820次阅读
    Java中<b class='flag-5'>Arrays</b>类是什么 <b class='flag-5'>Arrays</b>常用<b class='flag-5'>方法</b>

    怎样运用Java实现冒泡排序和Arrays排序出来

    在数据结构中我们学习了解了冒泡排序和Arrays排序的基本算法,但没能够用编程语言实现出来。那我们应该怎样运用Java通过编程语言将冒泡排序和Arrays排序实现出来呢?
    的头像 发表于 03-02 09:37 372次阅读
    怎样运用Java实现冒泡排序和<b class='flag-5'>Arrays</b>排序出来

    JDK中java.lang.Arrays 类的源码解析

    来揭开它神秘的面纱。 java.util.Arrays 类是 JDK 提供的一个工具类,用来处理数组的各种方法,而且每个方法基本上都是静态方法,能直接通过类名
    的头像 发表于 10-11 15:31 411次阅读
    JDK中java.lang.<b class='flag-5'>Arrays</b> 类的源码解析