Collection Issue

A

adrian.bartholomew

I have 2 Collections.
One of them has only one element that I want removed from the other.
Naturally I do:

listA.removeAll(listB);

I keep getting null position pointer.
So I copy the java utils code and modify it a bit and realise that the
problem lies in the "contains()" code.
When I check for equality of the element in listB to be removed from
listA with "==", it returns "true".
But when I check with ".equals()" it returns false.
This is flabbergasting to me. To my knowledge, "==" checks to see if
the Objects are at the same address. If that is true, how on earth
could ANYTHING about them be different?
 
M

Mark Space

I have 2 Collections.
One of them has only one element that I want removed from the other.
Naturally I do:

listA.removeAll(listB);

I keep getting null position pointer.
So I copy the java utils code and modify it a bit and realise that the
problem lies in the "contains()" code.
When I check for equality of the element in listB to be removed from
listA with "==", it returns "true".
But when I check with ".equals()" it returns false.
This is flabbergasting to me. To my knowledge, "==" checks to see if
the Objects are at the same address. If that is true, how on earth
could ANYTHING about them be different?

So, "equals()" is a method that anyone can override. Obviously, someone
did override it, and botched the job. (Or your class derives from a
class that overrides the equals() method.)

What is the list element that you are dealing with here? Can we have a
look at its code?
 
A

adrian.bartholomew

So, "equals()" is a method that anyone can override. Obviously, someone
did override it, and botched the job. (Or your class derives from a
class that overrides the equals() method.)

What is the list element that you are dealing with here? Can we have a
look at its code?

sure:

public class RemoteEventListenerList<T extends RemoteEventListener>
implements
InvocationHandler {
private List<T> list = new LinkedList<T>();
private List<T> toAdd = new ArrayList<T>();
private final Class<T> type;
private T proxy = null;
private List<T> toRemove = new ArrayList<T>();

public RemoteEventListenerList(Class<T> type) {
this.type = type;
}

public Object invoke(Object o, Method method, Object[] args)
throws Throwable {
updateList();
dispatchList(list, method, args);
while (moreAdded()) {
final List<T> temp = new ArrayList<T>(toAdd);
updateList();
dispatchList(temp, method, args);
}
return null;
}

private void updateList() {
doRemove();
doAdd();
}

private boolean moreAdded() {
return !toAdd.isEmpty();
}

private void dispatchList(List<T> dispList, Method method,
Object[] args)
throws IllegalAccessException {
for (Object t : dispList.toArray()) {
dispatch(method, type.cast(t), args);
}
}

private synchronized void doRemove() {
removeAll(list, toRemove);
//removeAll(list, toRemove);
toRemove.clear();
}

private void doAdd() {
list.addAll(toAdd);
toAdd.clear();
}

public void removeAll(List<T> l, List<T> c) {
Iterator<T> e = l.iterator();
while (e.hasNext()) {
if (contains(l, e.next())) {//when it reaches the element,
it throws a null exception
e.remove(); // even though it DOES contain
it.
}
}
}

// I was experimenting here.

/*
public void removeAll(List<T> l, List<T> c) {
for (T e: l) {
if (contains(l, e)) {
l.remove(e);
}
}
}
*/

public boolean contains(List<T> c, T l) {
for (T e: c) {
if (e == l) return true;
}
return false;
}

private void dispatch(Method method, T t, Object[] args)
throws IllegalAccessException {
try {
method.invoke(t, args);
} catch (InvocationTargetException e) {
if (!(e.getTargetException() instanceof
DisconnectedException)) {
e.getTargetException().printStackTrace();
remove(t);
} else {
e.printStackTrace();
}
} catch (RuntimeException e) {
e.printStackTrace();
}
}

public T getProxy() {
if (proxy == null) {
proxy = type.cast(Proxy
.newProxyInstance(type.getClassLoader(), new
Class[]{type}, this)
);
}
return proxy;
}

public void add(T t) {
toAdd.add(t);
}

private void remove(T t) {
toRemove.add(t);
}

public void removeToAdd(T t) {
toAdd.remove(t);
remove(t); // I added this later, not sure about it
}
}

</code>
 
M

Mark Space

// I was experimenting here.

/*
public void removeAll(List<T> l, List<T> c) {
for (T e: l) {
if (contains(l, e)) {
l.remove(e);
}
}
}
*/

I think I agree with Eric. This code above seems messed up. You say
you want to remove all elements of c in l, but you never actually do
anything with c. Probably, that first for loop should be
for( T e : c ) // instead of l

public boolean contains(List<T> c, T l) {
for (T e: c) {
if (e == l) return true;
}
return false;
}

Given the error above, I think that's why only the == check is working
for you.

If you need to post that code again, please add a "main" method to drive
a simple test case so we can check it out. With out your specific test
case, it's hard to guess, as you're calling equals() on objects that you
don't show. T here must be derived from RemoteEventListenerList, so
there's still opportunity for error.
 
M

Mark Space

Lew said:
Shouldn't that be 'if ( e.equals(l) )'?
(I hope it is an "ell" there.)

I think so, but without an example or more explanation, I'm not 100%
sure what the OP is trying to accomplish. He might really mean to
compare objects with ==.
 
A

Andreas Leitgeb

That seems to indicate that the *element's* .equals() method
is broken.
sure:
public class RemoteEventListenerList<T extends RemoteEventListener>

I think you misunderstood. The question was about whatever
subclass of RemoteEventListener you have as *elements* in your list.
And especially: that element-class' .equals() (and .hashCode() )
methods.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,982
Messages
2,570,186
Members
46,744
Latest member
CortneyMcK

Latest Threads

Top