Java Java 脚本方法中 "splice(a,b,...)" 的等效方法

Java eqivalent method of "splice(a,b,...)" in JavaScript method

someArray.splice(a,b,...) 方法在 Java 脚本中添加或删除项目 to/from 数组。用 Java 语言实现这种方法的简单好方法是什么?假设我们有 String[] 个数组。

Java数组长度固定,所以没有这种方法

您可以想象在 Java 中编写类似于 splice 的效用函数,但它会 return 一个不同的数组。如果您调整数组的大小,那么在 java 中使用数组是没有意义的:它效率低下并且您无法共享实例。

通常且干净的解决方案是使用 List, which is a resizeable collection. ArrayList,最常用的 List 实现由数组支持,但效率很高,因为每次调整集合大小时数组都不会更改。

在标准 Java 库中,没有等效的功能。

java.util.Arrays class,但没有类似的功能。

我误读了你的问题,混淆了 spliceslice

class java.util.Arrays 提供了一些在处理数组时有用的静态函数。其他功能见官方文档:http://docs.oracle.com/javase/8/docs/api/java/util/Arrays.html.

Java 等价于 slice 是:Arrays.copyOfRange(array, from, to).

splice 类似的方法是addAll (http://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html#addAll-int-java.util.Collection-)。但是您需要使用 java.util.ArrayList 而不是数组,并且无法使用它删除元素。您必须将元素作为另一个集合提供,例如一个 ArrayList。所以相当于调用splice(index, 0, element1, element2, ...)

Java数组的长度是固定的,不能直接这样做

如果要合并两个数组,请查看this answer

如果要添加到数组中,您应该使用 ListArrayList

根据 JavaScript MDN specification.

Array.prototype.splice() 方法的 Java 实现
  public static <T>T[] splice(final T[] array, int start) {
    if (start < 0)
      start += array.length;

    return splice(array, start, array.length - start);
  }

  @SuppressWarnings("unchecked")
  public static <T>T[] splice(final T[] array, int start, final int deleteCount) {
    if (start < 0)
      start += array.length;

    final T[] spliced = (T[])Array.newInstance(array.getClass().getComponentType(), array.length - deleteCount);
    if (start != 0)
      System.arraycopy(array, 0, spliced, 0, start);

    if (start + deleteCount != array.length)
      System.arraycopy(array, start + deleteCount, spliced, start, array.length - start - deleteCount);

    return spliced;
  }

  @SuppressWarnings("unchecked")
  public static <T>T[] splice(final T[] array, int start, final int deleteCount, final T ... items) {
    if (start < 0)
      start += array.length;

    final T[] spliced = (T[])Array.newInstance(array.getClass().getComponentType(), array.length - deleteCount + items.length);
    if (start != 0)
      System.arraycopy(array, 0, spliced, 0, start);

    if (items.length > 0)
      System.arraycopy(items, 0, spliced, start, items.length);

    if (start + deleteCount != array.length)
      System.arraycopy(array, start + deleteCount, spliced, start + items.length, array.length - start - deleteCount);

    return spliced;
  }

以下 JUnit 代码测试此实现:

@Test
  public void testSplice() {
    final String[] array = new String[] {"a", "b", "c", "d", "e", "f"};

    Assert.assertArrayEquals(new String[] {"c", "d", "e", "f"}, Arrays.splice(array, 0, 2));
    Assert.assertArrayEquals(new String[] {"a", "d", "e", "f"}, Arrays.splice(array, 1, 2));
    Assert.assertArrayEquals(new String[] {"a", "b", "e", "f"}, Arrays.splice(array, 2, 2));
    Assert.assertArrayEquals(new String[] {"a", "b", "c", "f"}, Arrays.splice(array, 3, 2));
    Assert.assertArrayEquals(new String[] {"a", "b", "c", "d"}, Arrays.splice(array, 4, 2));
    try {
      Arrays.splice(array, 5, 2);
      Assert.fail("Expected ArrayIndexOutOfBoundsException");
    }
    catch (final ArrayIndexOutOfBoundsException e) {
    }

    try {
      Arrays.splice(array, -2, 3);
      Assert.fail("Expected ArrayIndexOutOfBoundsException");
    }
    catch (final ArrayIndexOutOfBoundsException e) {
    }
    Assert.assertArrayEquals(new String[] {"a", "b", "c", "d"}, Arrays.splice(array, -2, 2));
    Assert.assertArrayEquals(new String[] {"a", "b", "c", "f"}, Arrays.splice(array, -3, 2));
    Assert.assertArrayEquals(new String[] {"a", "b", "e", "f"}, Arrays.splice(array, -4, 2));
    Assert.assertArrayEquals(new String[] {"a", "d", "e", "f"}, Arrays.splice(array, -5, 2));
    Assert.assertArrayEquals(new String[] {"c", "d", "e", "f"}, Arrays.splice(array, -6, 2));
    try {
      Arrays.splice(array, -7, 2);
      Assert.fail("Expected ArrayIndexOutOfBoundsException");
    }
    catch (final ArrayIndexOutOfBoundsException e) {
    }

    Assert.assertArrayEquals(new String[] {}, Arrays.splice(array, 0));
    Assert.assertArrayEquals(new String[] {"a"}, Arrays.splice(array, 1));
    Assert.assertArrayEquals(new String[] {"a", "b"}, Arrays.splice(array, 2));
    Assert.assertArrayEquals(new String[] {"a", "b", "c"}, Arrays.splice(array, 3));
    Assert.assertArrayEquals(new String[] {"a", "b", "c", "d"}, Arrays.splice(array, 4));
    Assert.assertArrayEquals(new String[] {"a", "b", "c", "d", "e"}, Arrays.splice(array, 5));
    Assert.assertArrayEquals(new String[] {"a", "b", "c", "d", "e", "f"}, Arrays.splice(array, 6));
    try {
      Arrays.splice(array, 7);
      Assert.fail("Expected ArrayIndexOutOfBoundsException");
    }
    catch (final ArrayIndexOutOfBoundsException e) {
    }

    Assert.assertArrayEquals(new String[] {"a", "b", "c", "d", "e"}, Arrays.splice(array, -1));
    Assert.assertArrayEquals(new String[] {"a", "b", "c", "d"}, Arrays.splice(array, -2));
    Assert.assertArrayEquals(new String[] {"a", "b", "c"}, Arrays.splice(array, -3));
    Assert.assertArrayEquals(new String[] {"a", "b"}, Arrays.splice(array, -4));
    Assert.assertArrayEquals(new String[] {"a"}, Arrays.splice(array, -5));
    Assert.assertArrayEquals(new String[] {}, Arrays.splice(array, -6));
    try {
      Arrays.splice(array, -7);
      Assert.fail("Expected NegativeArraySizeException");
    }
    catch (final NegativeArraySizeException e) {
    }

    Assert.assertArrayEquals(new String[] {"x", "y", "z", "c", "d", "e", "f"}, Arrays.splice(array, 0, 2, "x", "y", "z"));
    Assert.assertArrayEquals(new String[] {"a", "x", "y", "z", "d", "e", "f"}, Arrays.splice(array, 1, 2, "x", "y", "z"));
    Assert.assertArrayEquals(new String[] {"a", "b", "x", "y", "z", "e", "f"}, Arrays.splice(array, 2, 2, "x", "y", "z"));
    Assert.assertArrayEquals(new String[] {"a", "b", "c", "x", "y", "z", "f"}, Arrays.splice(array, 3, 2, "x", "y", "z"));
    Assert.assertArrayEquals(new String[] {"a", "b", "c", "d", "x", "y", "z"}, Arrays.splice(array, 4, 2, "x", "y", "z"));
    try {
      Arrays.splice(array, 5, 2, "x", "y", "z");
      Assert.fail("Expected ArrayIndexOutOfBoundsException");
    }
    catch (final ArrayIndexOutOfBoundsException e) {
    }

    Assert.assertArrayEquals(new String[] {"a", "b", "c", "d", "x", "y", "z"}, Arrays.splice(array, -2, 2, "x", "y", "z"));
    Assert.assertArrayEquals(new String[] {"a", "b", "c", "x", "y", "z", "f"}, Arrays.splice(array, -3, 2, "x", "y", "z"));
    Assert.assertArrayEquals(new String[] {"a", "b", "x", "y", "z", "e", "f"}, Arrays.splice(array, -4, 2, "x", "y", "z"));
    Assert.assertArrayEquals(new String[] {"a", "x", "y", "z", "d", "e", "f"}, Arrays.splice(array, -5, 2, "x", "y", "z"));
    Assert.assertArrayEquals(new String[] {"x", "y", "z", "c", "d", "e", "f"}, Arrays.splice(array, -6, 2, "x", "y", "z"));
    try {
      Arrays.splice(array, -7, 2, "x", "y", "z");
      Assert.fail("Expected ArrayIndexOutOfBoundsException");
    }
    catch (final ArrayIndexOutOfBoundsException e) {
    }
  }

编辑: 正如@denys-séguret 正确指出的那样,此实现不同于 JavaScript 规范,因为它不 mutate/modify原始数组。相反,此实现 returns 一个新的数组实例。

编辑:此实现可用于给定的 Maven 仓库中的以下 Maven 工件:

<project>
  ...
  <dependencies>
    <dependency>
      <groupId>org.safris.commons</groupId>
      <artifactId>commons-lang</artifactId>
      <version>1.6.4</version>
    </dependency>
  </dependencies>
  ...
  <repositories>
    <repository>
      <id>mvn.repo.safris.org</id>
      <url>http://mvn.repo.safris.org/m2</url>
    </repository>
  </repositories>
  ...
</project>

Java 中的数组具有固定数量的元素。但是您可以像这样使该元素为空:

数组[元素]==null;

这与从数组中删除它是一样的。你也可以有一个变量来跟踪有多少元素不为空,这样你甚至可以在它后面有一个 array.length 类型的东西。反正我就是这么做的。