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));