1

I need to remove only one occurence of an integer in a ArrayList of integers. My code right now removes all integers with a specific value.

list.removeIf(s -> s.equals(data));

If I have for example:

ArrayList<Integer> i = new ArrayList<Integer>();

i.add(1);
i.add(1);
i.add(3);
i.add(5);

and I want to remove only the first 1 or the second 1. Not both.

Doerad
  • 69
  • 1
  • 7
  • Questions asking for *homework help* **must** include a summary of the work you've done so far to solve the problem, and a description of the difficulty you are having solving it ([help], [ask]). – Zabuzard Feb 14 '19 at 21:01
  • 1
    What did you expect from `removeIf`? Of course it removes all elements for which this predicate resolves to `true` (as explained in its documentation). – Zabuzard Feb 14 '19 at 21:02
  • @Zabuza Eh, this is what I've done so far? Its a lambda expression. – Doerad Feb 14 '19 at 21:02
  • Possible duplicate: https://stackoverflow.com/questions/4534146/properly-removing-an-integer-from-a-listinteger – SedJ601 Feb 14 '19 at 21:03
  • Then you might precise your question and explain that you are searching for a way to achieve it and this was your attempt. Because at the moment, at least to me, it sounds more that you are confused why this code yields the observed result instead of the expected. – Zabuzard Feb 14 '19 at 21:03
  • 2
    Did you find any other methods that start with "remove" in the `List` interface that remove only one occurrence? – rgettman Feb 14 '19 at 21:04

2 Answers2

6

Solution

Use the List#remove method. That is exactly what it was made for, from the documentation:

Removes the first occurrence of the specified element from this list, if it is present (optional operation). If this list does not contain the element, it is unchanged. [...]

boolean wasRemoved = list.remove(data);

Removing ints

However, you might have a minor issue here. Your data type is Integer and data is probably of type int. And there is already a method with the signature List#remove(int) (documentation) which will remove the element at the given index, not the element itself.

You can bypass this by explicitly boxing your data to an Integer, which is what you actually have stored in the list:

boolean wasRemoved = list.remove((Integer) data);

Or directly make the data variable of type Integer instead of int.

Zabuzard
  • 25,064
  • 8
  • 58
  • 82
  • 1
    Since it's an Int, the OP needs to Cast the value or it will remove by index. – SedJ601 Feb 14 '19 at 21:08
  • 3
    @Sedrick True. Unfortunately this information was added afterwards to the question. I will update my answer. – Zabuzard Feb 14 '19 at 21:08
  • 1
    Is casting to `Integer` equivalent to `Integer.valueOf`? I'm just curious if the `Integer` value *might* be cached after casting. – Jacob G. Feb 14 '19 at 21:25
  • 1
    @JacobG. Good question. `Integer.valueOf` clearly uses the cache (see [zgrepcode](https://zgrepcode.com/java/openjdk/10.0.2/java.base/java/lang/integer.java#L-1046)). Boxing to `Integer` does too (see [JLS§5.1.7](https://docs.oracle.com/javase/specs/jls/se11/html/jls-5.html#jls-5.1.7)) "*If the value p being boxed is [...] an integer in the range -128 to 127 inclusive [...]. It is always the case that a == b"*. Also see [Weird Integer boxing in Java](https://stackoverflow.com/questions/3130311/weird-integer-boxing-in-java). – Zabuzard Feb 14 '19 at 21:30
4

Just use remove method from the list.remove(new Integer(data)), by the implementation you can see that it removes the first element then exits:

for (int index = 0; index < size; index++)
    if (o.equals(elementData[index])) {
         fastRemove(index);
         return true;
    }
Schidu Luca
  • 3,897
  • 1
  • 12
  • 27