拨开荷叶行,寻梦已然成。仙女莲花里,翩翩白鹭情。
IMG-LOGO
主页 文章列表 Java IndexOutOfBoundsException: “Source Does Not Fit in Dest”

Java IndexOutOfBoundsException: “Source Does Not Fit in Dest”

白鹭 - 2021-11-24 643 0 0

1.概述

在Java中,复制List有时会产生IndexOutOfBoundsException: “Source does not fit in dest”.在这个简短的教程中,我们将研究为什么使用Collections.copy方法时会出现此错误,以及如何解决该错误。我们还将研究Collections.copy替代方法,以制作列表的副本。

2.重现问题

让我们从使用Collections.copy方法创建List副本的方法开始:

static List<Integer> copyList(List<Integer> source) {

 List<Integer> destination = new ArrayList<>(source.size());

 Collections.copy(destination, source);

 return destination;

 }

在这里, copyList方法创建一个新列表,其初始容量等于源列表的大小。然后,它尝试将源列表的元素复制到目标列表:

List<Integer> source = Arrays.asList(1, 2, 3, 4, 5);

 List<Integer> copy = copyList(source);

但是,一旦调用copyList方法,它就会引发异常java.lang.IndexOutOfBoundsException: Source does not fit in dest

3. Exception原因

让我们尝试了解出了什么问题。根据Collections.copy方法的文档:

目标列表必须至少与源列表一样长。如果更长,则目标列表中的其余元素不受影响。

在我们的示例中,我们使用构造函数创建了一个新List ,其初始容量等于源列表的大小。它只是分配足够的内存,而实际上没有定义元素。新列表的大小保持为零,因为容量和大小是List不同属性。

因此,当Collections.copy方法尝试将源列表复制到目标列表时,它将引发java.lang.IndexOutOfBoundsException.

4.解决方案

4.1。 Collections.copy

让我们看一个使用Collections.copy方法将List复制到另一个List的工作示例:

List<Integer> destination = Arrays.asList(1, 2, 3, 4, 5);

 List<Integer> source = Arrays.asList(11, 22, 33);

 Collections.copy(destination, source);

在这种情况下,我们会将源列表的所有三个元素复制到目标列表。 Arrays.asList方法使用元素(而不只是大小)初始化列表,因此,我们能够成功地将源列表复制到目标列表。

如果仅交换Collections.copy方法的参数,则它将抛出java.lang.IndexOutOfBoundsException因为源列表的大小小于目标列表的大小.

执行此复制操作后,目标列表如下所示:

[11, 22, 33, 4, 5]

除了Collections.copy方法外,Java中还有其他方法可以复制List 。让我们看看其中的一些。

4.2。 ArrayList构造函数

复制List的最简单方法是使用带有Collection参数的构造函数:

List<Integer> source = Arrays.asList(11, 22, 33);

 List<Integer> destination = new ArrayList<>(source);

在这里,我们只是将源列表传递给目标列表的构造函数,目的列表将创建源列表的浅表副本。

目标列表将只是对源列表引用的同一对象的另一个引用。因此,任何引用所做的每次更改都会影响同一对象。

因此,使用构造函数是复制不可变对象(如IntegersStrings. )的好选择Strings.

4.3。 addAll

另一种简单的方法是使用ListaddAll方法:

List<Integer> destination = new ArrayList<>();

 destination.addAll(source);

The addAll方法会将源列表的所有元素复制到目标列表。

关于此方法,有几点要注意:

  1. 它创建源列表的浅表副本。
  2. 源列表的元素将附加到目标列表。

4.4。 Java 8 Streams

Java 8引入了Stream API,它是使用Java Collections.的出色工具Collections.

使用stream()方法,我们使用Stream API复制列表:

List<Integer> copy = source.stream()

 .collect(Collectors.toList());

4.5。 Java 10

在Java 10中,复制List甚至更简单。使用copyOf()方法允许我们创建一个包含给定Collection元素的不可变列表:

List<Integer> destination = List.copyOf(sourceList);

如果要采用这种方法,则需要确保输入List不为null ,并且其中不包含任何null元素。

5.结论

在本文中,我们研究了Collections.copy方法如何以及为什么引发IndexOutOfBoundException “Source does not file in dest” 。随之,我们还探索了将List复制到另一个List.不同方法List.

标签:

0 评论

发表评论

您的电子邮件地址不会被公开。 必填的字段已做标记 *