Java中与JavaScript的"splice(a,b,...)"方法相对应的方法是什么?

5
在JavaScript中,someArray.splice(a,b,...)方法用于向数组中添加或移除项目。那么在Java语言中,实现这种方法的好而简单的解决方案是什么?假设我们有一个String[]数组。

1
如果你正在寻找一种调整数组大小的方法,那么你可能应该使用List而不是数组。这将为您提供addAll(index, Collection),您可以使用addAll(index, Arrays.asList("foo", "bar")) - Pshemo
在Java中,数组无法添加(增长)。请使用ArrayList - Jonas Czech
6个回答

6

以下是根据JavaScript MDN规范编写的Java实现Array.prototype.splice()方法。

  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规范不同,因为它没有改变/修改原始数组。相反,这个实现返回一个新的数组实例。

编辑:此实现可用于以下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>

请修正您的介绍,它没有实现splice的规范,因为它不会修改传递的数组,而是返回一个新的数组。正如之前回答的那样,在Java中修改数组是不可能的(使用列表是明智且快速的最佳实践)。 - Denys Séguret
我希望将此作为一个库。谢谢 :) - msangel
1
@msangel,我已经更新了答案,并提供了一个Maven工件,您可以将其作为依赖引用。 - Seva Safris

4
Java数组长度是固定的,因此没有这样的方法。您可以想象编写一个类似于Java中splice的实用程序函数,但它将返回不同的数组。如果你调整数组大小,就没有在Java中使用数组的意义了:这并不高效,而且你不能共享它的实例。通常和清晰的解决方案是使用List,它是可调整大小的集合。最常用的List实现ArrayList由数组支持,但它很高效,因为数组不会在每次调整集合大小时更改。

现在我正在考虑 substring() 方法。我们等着瞧吧。 - Ernestas Gruodis
@ErnestasGruodis substring 有什么关系? - Denys Séguret
我可以将 Array 转换为 String,然后使用 substring() 方法创建 Array。但这不是一种有效的方法。 - Ernestas Gruodis

0
Java 中的数组有固定数量的元素。但你可以像这样把某个元素设为 null:
array[element]==null;
这相当于从数组中删除它。你还可以有一个变量来跟踪有多少个元素不是 null,这样你甚至可以有一个类似于 array.length 的东西来跟随它。那就是我做的事情。

0

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

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


0

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

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, ...)


不是这样的。他在谈论变异,这将创建数组的副本。 - Crazyjavahacking
不,这会返回一个新的数组。splice 中有趣的一点是它会改变源数组。 - Denys Séguret
1
我假设这里的 splice: http://www.w3schools.com/jsref/jsref_slice_array.asp 并且它不会改变被调用的数组,而是返回一个新的数组。 - DenisG
我喜欢这个方法,很快就会尝试。 - Ernestas Gruodis
但是 splice 方法也可以向 Array 添加元素,使其变大... 所以我认为唯一的方法是使用 ArrayList - Ernestas Gruodis

0
Java数组具有固定的长度,因此不能直接完成此操作。
如果您想要合并两个数组,请查看这个答案
如果您想要向数组添加元素,应该使用ListArrayList

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