2015-03-14 2 views
3

someArray.splice(a,b,...) метод в JavaScript добавляет или удаляет элементы в/из массива. Что может быть хорошим и простым решением для реализации такого метода на языке Java? Предположим, что мы имеем массив String[].Java eqivalent method of "splice (a, b, ...)" в методе JavaScript

+1

Если вы ищете способ изменения размера массива, вы, вероятно, должны использовать 'List' вместо массива. Это даст вам 'addAll (index, Collection)', который вы можете использовать как 'addAll (index, Arrays.aslList (" foo "," bar "))' – Pshemo

+0

В Java массивы не могут быть добавлены (выросли). Для этого используйте 'ArrayList'. – JonasCz

ответ

2

Вот реализация Java метода Array.prototype.splice() согласно 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; 
    } 

Следующий код 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) { 
    } 
    } 

Edit: Как @ Denys-Séguret указал правильно, эта реализация отличается от спецификации JavaScript, поскольку он не мутировать/изменении размера оригинальный массив. Вместо этого эта реализация возвращает новый экземпляр массива.

Edit: Эта реализация доступна со следующей 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> 
+0

Мне нравится это решение, спасибо. Работает. –

+0

Пожалуйста, исправьте свое введение, оно не реализует спецификацию сплайсинга, так как не изменяет переданный массив, а возвращает новый. Как уже было сказано, изменение массива в Java невозможно (и использование списка - это умная и быстрая передовая практика). –

+0

Я хочу это как библиотеку. Спасибо :) – msangel

3

Java-массивы имеют фиксированную длину, поэтому такого метода нет.

Вы можете представить себе функцию утилиты, похожую на сращивание в Java, но она вернет другой массив. Нет смысла иметь массивы в java, если вы измените их размер: это неэффективно, и вы не можете поделиться экземпляром.

Обычным и чистым решением является использование List, который представляет собой изменяемую по размеру коллекцию. ArrayList, наиболее часто используемая реализация списка поддерживается массивом, но эффективна, поскольку массив не изменяется при каждом изменении размера коллекции.

+0

Теперь я думаю о методе 'substring()'. Посмотрим. –

+0

@ErnestasGruodis Каково отношение с 'подстрокой'? –

+0

Я могу преобразовать 'Array' в' String', затем 'substring()' и создать 'Array'. Но не эффективный способ. –

0

В стандартных библиотеках Java нет эквивалентной функциональности.

Существует java.util.Arrays класс, но нет аналогичной функциональности.

0

Я неправильно разобрал ваш вопрос и перепутал splice и slice.

Класс 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 вместо массива, и с ним невозможно удалить элементы. Вы должны были бы предоставить элементы в качестве другой коллекции, например. a ArrayList. Таким образом, это эквивалентно вызову splice(index, 0, element1, element2, ...)

+0

Нет, это не так. Он говорит о мутации, это создаст копию массива. – Crazyjavahacking

+0

Нет, это возвращает новый массив. Интересным моментом в 'splice' является то, что он изменяет исходный массив. –

+1

Я предположил, что это «сращивание»: http://www.w3schools.com/jsref/jsref_slice_array.asp, и он не изменяет массив, на который он вызывается, но возвращает новый массив. – DenisG

0

Ядра Java имеют фиксированную длину, поэтому это невозможно сделать напрямую.

Если вы хотите совместить два массива, посмотрите на this answer.

Если вы хотите добавить в массив, вы должны использовать вместо него List или ArrayList.

0

Массивы в Java имеют фиксированное число элементов. Но вы можете сделать этот элемент нулевым:

массив [element] == ​​null;

И это то же самое, что удаление его из массива. У вас также может быть переменная, которая отслеживает, сколько элементов не равно null, так что вы можете даже иметь тип array.length, который следует за этим. вот что я делаю.

Смежные вопросы