Java Arrays.copyOf

3
我希望能够将arr1中的“b”,“d”和“e”仅复制到arr2中,并在添加时动态增加arr2的大小。
我尝试添加了一个if条件。
 if(!arr1[i].equals("a") && !arr1[i].equals("c")) {
     arr2 = Arrays.copyOf(arr1, i + incrementLength);
 }

但它仍然将arr1中的所有内容复制到arr2中。
import java.util.Arrays;
public class Test {
    public static void main(String[] args) {
        String[] arr1 = new String[] { "a", "b", "c", "d", "e" };
        String[] arr2 = new String[0];
        int incrementLength = 1;
        for (int i = 0; i < arr1.length; i++) {
            if(!arr1[i].equals("a") && !arr1[i].equals("c")) {
                arr2 = Arrays.copyOf(arr1, i + incrementLength);
            }
        }
        for (String value : arr2) {
            System.out.println(value);
        }
    }
}

你为什么更喜欢使用数组而不是ArrayList?你介意使用Stream吗? - Roland
学习数组。好吧,这实际上是我的教授提出的挑战。他不允许我使用ArrayList。 - Test Account
2
提示:仔细阅读您正在使用的库调用的Javadoc。 - GhostCat
我会选择 StreamfiltertoArray 然后 ;-) - Roland
我认为我会采用另一种方法:创建一个与源数组大小相同的数组(在此示例中为5)。将元素复制到其中,跟踪已经复制了多少个元素,以便知道下一个应该放在哪里。最后使用 Arrays.copyOf() 将数组截断以适应其中的元素。 - Ole V.V.
4个回答

2
你代码中的 Arrays.copyOf(arr1, i + incrementLength); 会在循环内部创建 不必要的 多个 arr1 的副本。这是应该避免的。
可以参考这篇来自 Oracle 的文档。第二个参数是你将从 arr1 中复制到 arr2 的元素数量。
相反,你可以将所需元素添加到一个 List 中,并从该列表获取数组的副本。像这样:
    List<String> list = new ArrayList<>();

    for (int i = 0; i < arr1.length; i++) {
        if(!arr1[i].equals("a") && !arr1[i].equals("c")) {
            list.add(arr[i]);
        }
    }

    arr2 = list.toArray(new String[list.size()]);

更新

如果您不想使用列表,可以尝试以下方法:

    String[] arr1 = new String[] { "a", "b", "c", "d", "e" };
    String[] arr2 = new String[arr1.length];
    int j = 0;
    int finalLength = 0;
    for (int i = 0; i < arr1.length; i++) {
        if(!arr1[i].equals("a") && !arr1[i].equals("c")) {
            // add only elements that you need
            arr2[j++] = arr1[i];
            // keep track of how many elements you have added
            finalLength++;
        }
    }

    // truncate array to finalLength
    String[] arr3 = Arrays.copyOf(arr2, finalLength);
    for (String value : arr3) {
        System.out.println(value);
    }

这会生成以下输出:
    b
    d
    e

希望这能帮到你!

1
如果您想复制源数组的单独元素,则不能使用Arrays.copyOf。如果您要复制连续的子范围,则可以使用System.arraycopy,但这不是您所做的。 Arrays.copyOf只能用于复制整个数组或数组的前缀(即从第一个元素到某个索引处的所有元素)。 您必须先计算所需的输出数组长度,实例化输出数组,然后迭代输入数组的元素,并逐个复制相关元素到输出数组中。
public static void main(String[] args) {
    String[] arr1 = new String[] { "a", "b", "c", "d", "e" };
    int newLen = 0;
    for (int i = 0; i < arr1.length; i++) {
        if(!arr1[i].equals("a") && !arr1[i].equals("c")) {
            newLen++;
        }
    }
    String[] arr2 = new String[newLen];
    int index = 0;
    for (int i = 0; i < arr1.length; i++) {
        if(!arr1[i].equals("a") && !arr1[i].equals("c")) {
            arr2[index++] = arr1[i];
        }
    }
    for (String value : arr2) {
        System.out.println(value);
    }
}

这种方法的缺点是需要两次遍历输入数组,因为在不知道输出数组应该包含多少元素之前,无法创建输出数组。可以通过将输入数组的选定元素添加到一个 ArrayList<String> 中来避免这种情况,然后再将 ArrayList 转换为数组。

1
可以使用来完成:
String[] arr1 = new String[] { "a", "b", "c", "d", "e" };
String[] arr2 = Stream.of(arr1)
                      .filter(s -> !s.equals("a") && !s.equals("c"))
                      .toArray(String[]::new);

打印结果:
Stream.of(arr2)
      .forEach(System.out::println);

给出:
b
d
e


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接