0

I have an array list of integers and would like to delete an Integer value from it. To clarify: Let's say I have a function that takes in an ArrayList of Integers, and specified Integer value. I need to return the list with (value+1) deleted from it.

boolean deleteFromList(ArrayList<Integer> list, Integer value)

Now, if I do this:

return list.remove(value+1)

compiler will complain because it will try to invoke the delete method that takes int parameter and deletes an object from specified location, not the actual object. So what is a proper way to deal with this? Is it better to do:

list.remove((Integer)(value+1))

or

int v = value.intValue();
v++;
list.remove(new Integer(v)); 

? In the second case, can I be sure the right value will be deleted?

Maggie
  • 7,823
  • 7
  • 45
  • 66
  • sorry, the correct method name is remove, I was writing it from the top of my head. I will update my question – Maggie Nov 10 '13 at 11:38
  • @Maroun `list.remove(v+1)` doesn't work - that's the whole point. – Dawood ibn Kareem Nov 10 '13 at 11:38
  • 1
    I think this is an opinion-based question, so I have voted to close. You have already discovered that `remove((Integer)(value+1))` and `remove(new Integer(value+1))` both work. As for which is better - just pick whichever makes you happier. – Dawood ibn Kareem Nov 10 '13 at 11:40
  • are they the same in terms of autoboxing/boxing? will one take longer than the other? will it produce unnecessary objects? – Maggie Nov 10 '13 at 11:42
  • I don't know for sure, but I expect that `remove((Integer)(value+1))` and `remove(new Integer(value+1))` would probably produce identical byte code. – Dawood ibn Kareem Nov 10 '13 at 11:43
  • and after reading the answers, and some Javadocs, I realise that my last two comments were both wrong!! The byte code won't be identical for the two snippets in my last comment. This is NOT an opinion-based question at all - there is a good reason for not using `new Integer(...)`. Some of the answers explain the reason. I have retracted my close vote. – Dawood ibn Kareem Nov 10 '13 at 11:59

6 Answers6

2

list.remove(value+1) will remove at given index.

You can use list.remove(Integer.valueOf(value+1)) to remove the Integer.

Integer.valueOf(v) is recommanded instead of new Integer(v) because it allows reuse of Integer instances for special values (see javadoc).

EDIT : In term of boxing/unboxing, it is possible to completely eliminate the problem using libraries like trove4j which define an dynamic array of integer storing the primitive values instead of numeric class (see TIntArrayList). No boxing, no unboxing, lower GC use and better performance.

sebtic
  • 198
  • 1
  • 6
1
list.remove(Integer.valueOf(value+1));

should work fine.

kviiri
  • 3,282
  • 1
  • 21
  • 30
  • yes, it will work. But I am interested in a bit of analysis what happens in terms of boxing and autoboxing. which way is more efficient and elegant to use? – Maggie Nov 10 '13 at 11:41
1

In the second case, can I be sure the right value will be deleted?

Yes you can.

The remove method will use equals(Object) to identify the object to be removed from the list. Since Integer.equals compares by value (not by object identity), it doesn't matter how you created the Integer instances ... provided the wrapped int values are the same.


However ... your second version is inferior to the first version:

  • It cumbersome: 3 statements instead of 1.

  • You are using new Integer(...) rather than Integer.valueOf(...) which is always going to create a new instance. By contrast, autoboxing (or calling Integer.valueOf(...) explicitly) makes use of the Integer classes instance cache, and that will often avoid creating a new instance.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • Moreover, comparing Integer instance is inefficient since it is done with equals() which will need to test the instance class (instanceof), cast and finally access members. – sebtic Nov 10 '13 at 12:17
  • @sebtic - If you've decided to use a `java.util.Collection` class, that overhead is unavoidable. While there are other alternatives that are more efficient, they have definite drawbacks as well. Hence, I'm not prepared to recommend to the OP to switch to a 3rd party list-of-integers class. It might be a good idea ... or it might not ... depending on the circumstances. – Stephen C Nov 10 '13 at 12:38
  • @StephenC I completely agree but everyone must keep in mind that boxing/unboxing is easy and versatile but can have huge drawbacks and pitfalls. Often, a better modeling resolves the problems by itself and more efficiently but it greatly depends on what can be changed. – sebtic Nov 10 '13 at 12:52
  • @sebtic - 1) You forget that the requirement to use a Collection type often comes from the APIs you are using. 2) This is not about modelling (in the design sense, e.g. UML). It is about mapping the design model to concrete implementation types. – Stephen C Nov 10 '13 at 22:24
0

Do you looking for this one.

Collections.sort(list);
int index = list.indexOf(5);
list = list.subList(0, index-1);
System.out.println(list);
Prabhakaran Ramaswamy
  • 25,706
  • 10
  • 57
  • 64
0

You can use list.indexOf(value + 1) since that method only takes the object. Then use that index to remove the element.

    int i = list.indexOf(value + 1);
    list.remove(i);

If you need to remove all instances of value + 1 then continue until i is -1 (not found).

Or, just iterate over it and remove as you find them

    for (Iterator<Integer> iterator = list.iterator(); iterator.hasNext(); ) {
        Integer integer = iterator.next();
        if (integer == value + 1) {
            iterator.remove();
        }
    }
Andreas Wederbrand
  • 38,065
  • 11
  • 68
  • 78
0

A more effective way might be to use a TIntArrayList from Trove4j library which wraps int[] array and doesn't use wrapper types. For this reason it takes 3x times less memory and is much faster.

sebtic
  • 198
  • 1
  • 6
Andrey Chaschev
  • 16,160
  • 5
  • 51
  • 68