Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does lastIndexOf() method of List interface accepts Object as parameter and not E?

The lastIndexOf() method of List interface accepts a parameter which is of type Object.

However, the add() method accepts a parameter of type E (which is the generic-type of the List which is defined at the time of creating a List) Since add() accepts only E, this prevents the developer (or user) to add any incompatible object to the list at compile-time itself.

Now, Java doc says that lastIndexOf() can throw ClassCastException if the object passed is incompatible. However, when I run the following code in Eclipse Helios I don't get any Exception :-

package scjp.collection.list;

import java.util.ArrayList;
import java.util.List;

public class LastIndexOf {
public static void main(String[] args) {
    List<String> list = new ArrayList<String>();
    
    list.add("some");
    list.add("thing");
    list.add("at");
    list.add("last");
    list.add("and");
    list.add("at");
    list.add("again");
    
    
    
    System.out.println(list.lastIndexOf("at"));
    System.out.println(list.lastIndexOf(10));                    // # 1
    System.out.println(list.lastIndexOf(new LastIndexOf()));     // # 2
}
}

At Line 1 and Line 2, I have passed incompatible objects to my List which is of type String. However, the output that I get is :-

5
-1
-1

I get no ClassCastException.

Had the lastIndexOf() method been accepting objects of type E rather than objects of type Object, this would have been prevented at compile-time only. Why is this not done??

Java creators must have thought some problem that could occur if it accept E (and not Object). What harm would it be??

like image 617
whitehat Avatar asked Jan 31 '12 07:01

whitehat


People also ask

What does List of () do in Java?

The list() method of java. util. Collections class is used to return an array list containing the elements returned by the specified enumeration in the order they are returned by the enumeration.

Which method should be used if one has to use List contain employee OBJ and why?

The contains() method of List interface in Java is used for checking if the specified element exists in the given list or not. Parameters: This method accepts a single parameter obj whose presence in this list is to be tested.

Why List is an interface in Java?

List is a Java interface that describes a sequential collection of objects. ArrayList is a class that describes an array-based implementation of the List Java interface. A new instance of the ArrayList class is obtained and assigned to List variable names .


3 Answers

You don't need the E type -- remember that generics are just type-checked sugar for casts, and equals is defined on Object, so you don't need to cast the item to find out if it's equal to other items in the list. Also, consider bounded wildcard usage. If your list were defined as List<? extends Foo>, you wouldn't be able to get the lastIndexOf for any item other than null.

like image 73
yshavit Avatar answered Sep 22 '22 15:09

yshavit


For the same reasons that Collection.remove(Object o) has a similar signature. See this question for more details.

like image 22
ChrisH Avatar answered Sep 25 '22 15:09

ChrisH


In the methods, like remove, it will traverse the Array[E] and try equals() method on each object, then remove by the index if found. The lastIndexOf is the same as below.

public int lastIndexOf(Object o) {
    if (o == null) {
        for (int i = size-1; i >= 0; i--)
        if (elementData[i]==null)
            return i;
    } else {
        for (int i = size-1; i >= 0; i--)
        **if (o.equals(elementData[i]))**
            return i;
    }
    return -1;
}

So if the LastIndexOf class define its own equals function, and you make it equals to string "at", then according to the java spec the lastIndexOf(new LastIndexOf()) should be return the value as lastIndexOf("at").

Also check it out here. Why aren't Java Collections remove methods generic? Another one What are the reasons why Map.get(Object key) is not (fully) generic

like image 32
Kleenestar Avatar answered Sep 26 '22 15:09

Kleenestar