views:

116

answers:

5

If I run this operation on List<Integer> for example, it works as expected (removes first 5 elements), but when I run it on a list of my objects, nothing happens (list stays the same).

list.subList(0, 5).clear();

My class is a pojo that doesn't implement equals or hashCode, if that matters.

UPDATE: The implementation I am using is ArrayList, which is returned from Hibernate query. There is nothing to show, really. Sublist doesn't return an empty list.

Here is an example for those who don't beleive it works on a list of Integers:

    List<Integer> testList = new ArrayList<Integer>();
    for(int i=0;i<10;i++) {
        testList.add(i);
    }
    testList.subList(0, 5).clear();
    for(int i=0;i<testList.size();i++) {
        System.out.print(testList.get(i)+" ");
    }

The result is 5 6 7 8 9

UPDATE2: Actually everything is working as expected, don't know how I couldn't see that (got confused by numbers of results). Sorry for false alarm :) This question could be deleted.

+3  A: 

edit - Looks like I was wrong, but leaving my original answer here anyway:

Are you sure that it works with a List<Integer>? It shouldn't.

The method subList() returns a separate List. If you remove elements from that list, it shouldn't affect the original list. The API docs for List.subList() say this:

Returns a view of the portion of this list between the specified fromIndex, inclusive, and toIndex, exclusive. (If fromIndex and toIndex are equal, the returned list is empty.) The returned list is backed by this list, so non-structural changes in the returned list are reflected in this list, and vice-versa.

Clearing a list is not a non-structural change; only changing the elements in the list are non-structural changes.

This has nothing to do with whether your POJO has equals or hashCode methods or not.

edit - I just tried it out with an ArrayList and it does work (not only with Integer, but also with my own object as a list element).

Jesper
I thought that at first, but the very next section of the javadoc gives a specific example: "This method eliminates the need for explicit range operations (of the sort that commonly exist for arrays). Any operation that expects a list can be used as a range operation by passing a subList view instead of a whole list. For example, the following idiom removes a range of elements from a list: `list.subList(from, to).clear();`". It says non-structural changes there because structural changes don't work vice-versa; if you modify the backed structure, the copy doesn't change, but the reverse works
Michael Mrozek
Hmm, you're right. Now I'm not sure if this is supposed to work properly with any kind of `List` or not.
Jesper
It's in the doc for the List class, so it should; it shouldn't matter whether the generic is Integer or SomeRandomObject
Michael Mrozek
It also surprise me, I would expect different from java.
OscarRyz
It amuses me that you got an upvote after you edited your answer to mention it's wrong. You should leave this answer around as an experiment to see how many people upvote it without actually reading it
Michael Mrozek
+1 I'm upvoting it, but for because I thought the same as Jasper at the beginning and this answer showed me we both were wrong. :P +1 for the lesson learned.
OscarRyz
@Oscar Upvotes have nothing to do with "lessons learned" though, the point is to upvote good answers and downvote bad ones. The highest voted answer on this post currently leads off with "Looks like I was wrong" -- that's not a particularly good state to be in
Michael Mrozek
@Michael: Strictly speaking the votes are for "useful/notuseful" ( see the tooltip ) so, in this case, this answer was useful for me. To make the difference between highly voted answers vs. correct ( by OP decision ) answers there is the check mark. But, let me tell you something, in the rest of the questions out there in SO I agree with you, but in this particular unique question, strangely generated, 30 april created, numbered 2746744 question... , I think my upvote is correct :)
OscarRyz
A: 

Two things I can think of are:

  1. list.sublist(0, 5) returns an empty list, therefore .clear() does nothing.

  2. Not sure of the inner workings of the List implementation you're using (ArrayList, LinkedList, etc), but having the equals and hashCode implemented may be important. I had a simiarl issue with Maps, where HashMap definitely needs the hashCode implementation.

Joao
Hash-based collections such as `HashMap` and `HashSet` need a proper `equals` and `hashCode` method, but `ArrayList`, `LinkedList` etc. do not use those methods.
Jesper
+3  A: 

It works on my machinetm

import java.util.*;
import static java.lang.System.out;

class SubListExample {
    public static void main( String [] args ) {
        List<RandomObject> testList = new ArrayList<RandomObject>();
        for(int i=0;i<10;i++) {
            testList.add( new RandomObject() );
        }

        System.out.println( "Before: " + testList );
        testList.subList(0, 5).clear();
        System.out.println( "After: "+ testList );
    }
}
class RandomObject {
    static Random generator = new Random();
    int id = generator.nextInt(100);
    public String toString(){
        return "ro("+id+")";
    }
}

Produces:

$ java SubListExample
Before: [ro(68), ro(97), ro(48), ro(45), ro(43), ro(69), ro(45), ro(8), ro(88), ro(40)]
After: [ro(69), ro(45), ro(8), ro(88), ro(40)]

So, the problem is not in ArrayList nor in your objects.

I don't think Hibernate returns a plain old ArrayList ( may be it does )

Try printing

 System.out.println( "That hibernate list.class.name = "
        + listReturnedByHibernate.getClass().getName() );

And let us know if it is in fact an ArrayList

OscarRyz
A: 

Have you tried creating a List of your objects manually and doing the same thing (without Hibernate)? It seems possible to me that this has to do with Hibernate's lazy loading of data... if you haven't read the data in the returned List, it may not have been loaded yet (since sublists themselves are just views). In that case, it's possible clear would do nothing.

ColinD
A: 

Is it possible that the List returned from Hibernate is not modifiable? i.e. wrapped by Collections.unmodifiableList()

highlycaffeinated
But then it should throw a java.lang.UnsupportedOperationException
leonbloy