someArray.splice(a,b,...)
method in JavaScript adds or removes items to/from array. What could be good and simple solution to implement such method in Java language? Assume we have String[]
array.

- 8,567
- 14
- 55
- 117
-
1If you are looking for a way to resize array then you probably should be using `List` instead of array. This will give you `addAll(index, Collection)` which you can use as `addAll(index, Arrays.aslList("foo", "bar"))` – Pshemo Mar 14 '15 at 17:59
-
In Java, arrays cannot be added to (grown) . Use `ArrayList` for that. – Jonas Czech Mar 14 '15 at 17:59
6 Answers
Here is a Java implementation of the Array.prototype.splice()
method as per the JavaScript MDN specification.
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;
}
The following JUnit code tests this implementation:
@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) {
}
}
Edit: As @denys-séguret pointed out correctly, this implementation differs from the JavaScript spec as it does not mutate/modify the original array. Instead, this implementation returns a new array instance.
Edit: This implementation is available with the following maven artifact, at the given maven repo:
<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>

- 401
- 4
- 12
-
Please fix your introduction, it doesn't implement splice's specification as it doesn't modify the passed array but returns a new one. As previously answered, modifying an array in Java isn't possible (and using a list is the smart and fast best practice). – Denys Séguret Feb 16 '17 at 14:24
-
-
1@msangel, I've updated the answer with a maven artifact you can reference as a dependency. – Seva Safris May 15 '17 at 16:45
Java arrays have a fixed length, so there's no such method.
You could imagine writing a utility function similar to splice in Java but it would return a different array. There's no point in having arrays in java if you resize them: it's not efficient and you can't share the instance.
The usual and clean solution is to use a List, which is a resizeable collection. ArrayList, the most commonly used List implementation is backed by an array but is efficient as the array isn't changed every time you resize the collection.

- 372,613
- 87
- 782
- 758
-
-
-
I can convert `Array` to `String`, then `substring()` and create `Array`. But not effective way.. – Ernestas Gruodis Mar 14 '15 at 18:09
In standard Java libraries, there is no equivalent functionality.
There is java.util.Arrays
class, but no similar functionality there.

- 9,343
- 2
- 31
- 40
I misread your question and mixed up splice
and slice
.
The class java.util.Arrays
provides some static functions useful when working with arrays. See the official documentation for other functions: http://docs.oracle.com/javase/8/docs/api/java/util/Arrays.html.
Java's equivalent for slice
is: Arrays.copyOfRange(array, from, to)
.
A similar method to splice
is addAll
(http://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html#addAll-int-java.util.Collection-). But you need to use a java.util.ArrayList
instead an array and it is not possible to remove elements with it. You would have to provide the elements as another collection, e.g. an ArrayList
. So it is equivalent to calling splice(index, 0, element1, element2, ...)

- 59
- 1
- 5
-
No it's not. He is talking about mutation, this will create copy of the array. – Crazyjavahacking Mar 14 '15 at 18:02
-
No, this returns a new array. The interesting point in `splice` is that it changes the source array. – Denys Séguret Mar 14 '15 at 18:02
-
1I assumed this `splice`: http://www.w3schools.com/jsref/jsref_slice_array.asp and it does not change the array it is called upon but returns a new array. – DenisG Mar 14 '15 at 18:03
-
-
But `splice` method can also add to `Array`, make it larger... So I think the only way is to work with `ArrayList`. – Ernestas Gruodis Mar 14 '15 at 18:22
Java arrays have a fixed length, so this cannot be done directly.
If you want to combine two arrays, look at this answer.
If you want to add to the array, you should use a List
or an ArrayList
instead.

- 1
- 1

- 12,018
- 6
- 44
- 65
Arrays in Java have a fixed number of elements. But you can make that element null like this:
array[element]==null;
And that is the same as removing it from the array. You can also have a variable that keeps track of how many elements aren't null, so that you can even have an array.length kind of thing that follows that. that's what I do anyway.

- 3,169
- 4
- 39
- 51

- 13
- 2