Java: Список массивов String и удалить

В тесте, подобном этому:

    @Test
    public void test() {
        List<String[]> l = new LinkedList<String[]>();
        l.add(new String [] {"test", "123"});
        l.add(new String [] {"test", "456"});
        l.add(new String [] {"test", "789"});

        assertEquals(3, l.size());

        l.remove(new String [] {"test", "456"});

        assertEquals(2, l.size());
    }

второе утверждение (= 2) терпит неудачу, поскольку equals/hashcode, используемый в list.remove, является default для Object. Есть ли способ сделать список способным использовать Arrays.equals/Arrays.hashcode для сравнения массивов? Или единственным решением является перенос массивов String в объект и переопределение equals/hashcode?

Ответ 1

Используя Guava, есть. Вам нужно будет выполнить Equivalence<String[]>:

public final class MyEquivalence
    extends Equivalence<String[]>
{
    @Override
    protected boolean doEquivalent(final String[] a, final String[] b)
    {
        return Arrays.equals(a, b);
    }

    @Override
    protected int doHash(final String[] t)
    {
        return Arrays.hashCode(t);
    }
}

Затем вам понадобится, чтобы ваш список был List<Equivalence.Wrapper<String[]>>, и вставляем/удаляем/etc с помощью метода Equivalence .wrap():

final Equivalence<String[]> eq = new MyEquivalence();
list.add(eq.wrap(oneValue));
list.remove(eq.wrap(anotherValue));

Использовать Guava. Повторяй за мной. Использовать Guava: p

Ответ 2

Вы создаете новую ссылку на объект и передаете ее методу remove(). Из данных, которые вы опубликовали, похоже, что вы можете создать собственный класс с двумя свойствами и переопределить его equals() и hashCode() вместо сохранения их как String[] ИЛИ сохранить ссылку на объект String[] и использовать ссылку для удаления.

Ответ 3

Метод List часто основан на методе Object equals(Object o), который по умолчанию сравнивает ссылку на объект. Вы можете сохранить вкладку, если хотите удалить ее позже, или создать свой собственный класс и переопределить equals(Object o);)

    @Test
    public void test() {
        List<String[]> l = new LinkedList<String[]>();
        l.add(new String [] {"test", "123"});
        String[] tab = new String [] {"test", "456"};
        l.add(tab);
        l.add(new String [] {"test", "789"});

        assertEquals(3, l.size());

        l.remove(tab);

        assertEquals(2, l.size());
    }

Ответ 4

Кстати, Java 8 вводит новый метод removeIf, который удаляет все элементы этой коллекции, которые удовлетворяют заданному предикату

Его можно использовать для простого удаления массива строк из списка:

List<String[]> l = new LinkedList<String[]>();
l.add(new String [] {"test", "123"});
l.add(new String [] {"test", "456"});
l.add(new String [] {"test", "789"});

String[] newArray = new String[] {"test", "456"};
l.removeIf(array -> Arrays.equals(array, newArray));