Asked  7 Months ago    Answers:  5   Viewed   23 times

Here's a nice pitfall I just encountered. Consider a list of integers:

List<Integer> list = new ArrayList<Integer>();
list.add(5);
list.add(6);
list.add(7);
list.add(1);

Any educated guess on what happens when you execute list.remove(1)? What about list.remove(new Integer(1))? This can cause some nasty bugs.

What is the proper way to differentiate between remove(int index), which removes an element from given index and remove(Object o), which removes an element by reference, when dealing with lists of integers?


The main point to consider here is the one @Nikita mentioned - exact parameter matching takes precedence over auto-boxing.

 Answers

34

Java always calls the method that best suits your argument. Auto boxing and implicit upcasting is only performed if there's no method which can be called without casting / auto boxing.

The List interface specifies two remove methods (please note the naming of the arguments):

  • remove(Object o)
  • remove(int index)

That means that list.remove(1) removes the object at position 1 and remove(new Integer(1)) removes the first occurrence of the specified element from this list.

Tuesday, June 1, 2021
 
nomie
answered 7 Months ago
78

As far as I'm aware, Javascript (at least as it exists now) doesn't support operator overloading.

The best I can suggest is a class method for making new quota objects from several others. Here's a quick example of what I mean:

// define an example "class"
var NumClass = function(value){
    this.value = value;
}
NumClass.prototype.toInteger = function(){
    return this.value;
}

// Add a static method that creates a new object from several others
NumClass.createFromObjects = function(){
    var newValue = 0;
    for (var i=0; i<arguments.length; i++){
        newValue += arguments[i].toInteger();
    }
    return new this(newValue)
}

and use it like:

var n1 = new NumClass(1);
var n2 = new NumClass(2);
var n3 = new NumClass(3);

var combined = NumClass.createFromObjects(n1, n2, n3);
Tuesday, June 1, 2021
 
TecHunter
answered 7 Months ago
91

Reverse delete a, modifying it in-place:

for i in reversed(range(len(a))):
    if a[i][0] == 3:
        del a[i]

An in-place modification means that this is more efficient, since it does not create a new list (as a list comprehension would).


Since OP requests a performant solution, here's a timeit comparison between the two top voted answers here.

Setup -

a = np.random.choice(4, (100000, 2)).tolist()

print(a[:5])
[[2, 1], [2, 2], [3, 2], [3, 3], [3, 1]]

List comprehension -

%timeit [x for x in a if x[0] != b]
11.1 ms ± 685 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

Reverse delete -

%%timeit
for i in reversed(range(len(a))):
    if a[i][0] == 3:
        del a[i]

10.1 ms ± 146 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)

They're really close, but reverse delete has a 1UP on performance because it doesn't have to generate a new list in memory, as the list comprehension would.

Tuesday, July 6, 2021
 
Student
answered 5 Months ago
53

Yes, you understood it correctly. The idea is that the object returned by umodifiableCollection can't directly be changed, but could change through other means (effectively by changing the internal collection directly).

As long as something has access to the internal list, the "unmodifiable" collection could be changed.

That's why you usually construct a unmodifiable collection and make sure that nothing can ever get to the internal list:

Collection<Integer> myUmodifiableCollection = Collection.umodifiableCollection(Arrays.asList(1, 2, 3));

Since nothing ever gets a reference to the List created by asList, this is a truly unmodifiable collection.

The advantage of this approach is that you don't need to copy the original collection/list at all, which avoids using memory and computing power.

Guava provides the ImmutableCollection class (and its subclasses such as ImmutableList) which provide true immutable collections (usually by copying the source).

Sunday, August 1, 2021
 
rlanvin
answered 4 Months ago
58

newstring is of length 0, so newstring[x] where x=0 is actually illegal. You should append to the string using: newstring.append(1, fstring[i])

For the secondary question, look for atoi(), atof(), strtol(0, strtof() functions.

Friday, August 20, 2021
 
muaddhib
answered 4 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :  
Share