Вычитание одного arrayList из другого arrayList
у меня есть два arrayLists, и я пытаюсь "вычесть" один arrayList из другого. Например, если у меня есть один arrayList [1,2,3], и я пытаюсь вычесть [0, 2, 4], результирующий arrayList должен быть [1,3].
List<Integer> a = new ArrayList<>(Arrays.asList(1, 2, 3));
List<Integer> b = Arrays.asList(0, 2, 4);
subtract(a,b) // should return [1,3]
вот мой код.
//returns a new IntSet after subtracting a from b
// .minus().toString()
ArrayList<Integer> minusArray = new ArrayList<Integer>();
minusArray.addAll(array1);
for(int i =0; i< minusArray.size(); i++){
for(int j = 0; j < array2.size(); j++){
if(minusArray.get(i).equals(array2.get(j))){
minusArray.remove(i);
if(i == 0){
;
}
else if(j == 0){
;
}
else{
i = 0;
j = 0;
}
}
else{}
}
}
return minusArray;
мой код работает в некоторых случаях, например, если arrayList1 = [4,6]
и arrayList2 = [6]
это даст мне результат [4]
. Но если я попробую что-то вроде [1,2,4]
и [0,4,8]
Я понимаю это исключение:
java.lang.IndexOutOfBoundsException: Index: 2, Size: 2
at java.util.ArrayList.rangeCheck(Unknown Source)
at java.util.ArrayList.get(Unknown Source)
at IntSet.minus(IntSet.java:119)
at IntSetDriver.main(IntSetDriver.java:62)
вот код, который я придумал. Я сделал тестовые прогоны через него, и мне кажется, что он должен работать. Пользователь вводит эти arrayLists и они пресортированы, я также не знаю хэша или big-O.
ArrayList<Integer> minusArray = new ArrayList<Integer>();
minusArray.addAll(array1);
for(int i =0; i< minusArray.size(); i++){
for(int j = 0; j < array2.size(); j++){
if(minusArray.get(i).equals(array2.get(j))){
minusArray.remove(i);
}
else{}
}
}
return minusArray;
8 ответов
ваша проблема в том, что в вашем minusArray.снимать.(..) вызов вы можете уменьшить размер minusArray. Чтобы исправить это, начните с array.size () - 1 и обратный отсчет до 0
проверьте это-даже это не исправит его. Вам нужно изменить порядок ваших петель
есть ли причина, по которой Вы не можете просто использовать List.removeAll (список)?
List<Integer> one = new ArrayList<Integer>();
one.add(1);
one.add(2);
one.add(3);
List<Integer> two = new ArrayList<Integer>();
two.add(0);
two.add(2);
two.add(4);
one.removeAll(two);
System.out.println(one);
result: "[1, 3]"
попробуйте использовать метод вычитания org.апаш.палата общин.коллекции.Класс CollectionUtils.
возвращает новую коллекцию, содержащую a-b. Мощность каждого элемента e в возвращаемой коллекции будет равна мощности e в A минус мощность e в b или нулю, в зависимости от того, что больше.
CollectionUtils.вычесть (java.утиль.Коллекция a, java.утиль.Коллекция b)
пересекая minusArray
с помощью индекса-это один из способов сделать это, но я предлагаю вам использовать contains(Object)
метод, который позволит вам использовать remove(Object)
для конкретного элемента array2
.
конечно, всегда есть removeAll(Collection)
что делает почти все, что нужно...
вы можете использовать org.апаш.палата общин.коллекции.ListUtils и сделать все, что вы хотите только одну строку =)
List resultList = ListUtils.subtract(list, list2);
на всякий случай, если вы планируете использовать Java8, вы также можете использовать потоки:
List<Integer> list1 = Arrays.asList(1, 2, 3);
List<Integer> list2 = Arrays.asList(1, 2, 4, 5);
List<Integer> diff = list1.stream()
.filter(e -> !list2.contains(e))
.collect (Collectors.toList()); // (3)
этот ответ не манипулирует исходным списком, и если это намерение, мы можем использовать remove
. Также мы можем использовать forEach
(способ по умолчанию в Iterator
) или поток с фильтра.
Я предполагаю, что вы получаете проблему диапазона, потому что вы исключили один из элементов, который изменяет то, что ищет внутренний цикл (я знаю, что эта проблема возникает при работе с обычными списками и коллекциями).
то, что мне приходилось делать в прошлом, чтобы обойти это, - это создать список элементов, которые необходимо удалить (то есть те, которые находятся в исходном списке). Повторите этот новый список и непосредственно удалите элементы исходного списка без необходимости пусть итератор пройдет через него.
попробуйте этот ответ если
removeAll()
Не то, что вы хотите. например, если вас интересует что-то вроде вычисление разности двух списков с дубликатами
вычесть (a, b)
b.forEach((i)->a.remove(i));
a
содержит
[1, 3]
такое предложение исполнителей Guava о том, как реализовать вычитание
"создать ArrayList, содержащий a, а затем вызовите remove для каждого элемента в b."
, который ведет себя как эта реализация используется в Apache commons
разница в removeAll ()
[1,2,2,3].removeAll([1,2,3]) //is empty
[1,2,3].forEach((i)->[1,2,2,3].remove(i)); //a is [2]