Resorting the entries after one changes

After some usage of my program I realized that my TreeSet is giving me problems. Its a sorted set with compareTo based on name. When the name of an entry changes I need to resort the set.

I know its bad for any equals or compareTo to change after the item was put into the set. So I figured I would remove and readd the item. But that does not work because of the following

Have sort based on name.

Have items: B, D, F, H

Item H changed its name to C.

ask set to remove H.

Set examines name of object requested to be removed. Sees its name as "C". set begins searching from the middle, perhaps at 'E'. With compare to E, set decides C is to the left. Unfortunately, C was inserted and sorted into the location of H which was its name at the time. Thus, entry 'C' is not found, and not removed. and now we have

B, D, F, C

Which is whack, but whats worse is when I readd the element I end up with

B, C, D, F, C

and that just aint right. Actually I seem to end up with B, C,C, D,F but minor technicality.

How do I get around this, without resorting the whole honking set? Must I be informed about the pending name change and remove the item beforehand?. Is a resort really worth worry about if the elements are already sorted, except 1? I plan to have 100s of elements.

thanks for the tips.

[1370 byte] By [_dnoyeBa] at [2007-11-27 9:56:05]
# 1
1 - remove the element;2 - change an internal attribute of that element;3 - re-insert the changed element;4 - have a beer.
prometheuzza at 2007-7-13 0:26:10 > top of Java-index,Core,Core APIs...
# 2

import java.util.*;

public class Foo {

public static void main(String[] args) {

Set<Bar> set = new TreeSet<Bar>();

Bar[] array = {new Bar('F'),new Bar('B'),new Bar('H'),new Bar('D')};

set.addAll(Arrays.asList(array));

System.out.println(set);

Bar h = array[2];

set.remove(h);// 1 - remove

h.name = 'C';// 2 - change

set.add(h); // 3 - insert

System.out.println(set);

}

}

class Bar implements Comparable<Bar> {

char name;

public Bar(char name) { this.name = name; }

public int compareTo(Bar that) { return this.name-that.name; }

public String toString() { return String.valueOf(name); }

}

prometheuzza at 2007-7-13 0:26:10 > top of Java-index,Core,Core APIs...
# 3
Should there be aBeer haveABeer()method? ;-)
OleVVa at 2007-7-13 0:26:10 > top of Java-index,Core,Core APIs...
# 4
> Should there be a> > Beer haveABeer()> > method? ;-)I thought I'd leave some work for the OP.; )
prometheuzza at 2007-7-13 0:26:10 > top of Java-index,Core,Core APIs...
# 5
Hi,In your case, before altering the attribute of the object H (from 'H' to 'C'),remove that object from Set, alter the attribute of the object and add the object again to the Set. This will resolve your problem.Regards,Loga
Loga_07a at 2007-7-13 0:26:10 > top of Java-index,Core,Core APIs...
# 6

Hi,

I have attached a sample program on that. Please have a look into it.

public class MyString implements Comparable {

private String name;

public MyString() {

//default constructor

}

public MyString(String name) {

this.name = name;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

@Override

public int hashCode() {

return this.name.hashCode();

}

@Override

public boolean equals(Object obj) {

if(obj == null) {

return false;

}

if(!(obj instanceof MyString)) {

return false;

}

MyString myString = (MyString)obj;

return this.name.equals(myString.name);

}

@Override

public String toString() {

return this.name;

}

public int compareTo(Object o) {

if(o == null || !(o instanceof MyString)) {

return -1;

}

MyString myString = (MyString) o;

return this.name.compareTo(myString.name);

}

}

import java.util.Collections;

import java.util.Iterator;

import java.util.Set;

import java.util.TreeSet;

public class TestTreeSet {

/**

* @param args

* loganathank

* void

*

*/

public static void main(String[] args) {

System.out.println("GOD IS GREAT !!!");

TreeSet<MyString> treeSet = new TreeSet<MyString>();

MyString B = new MyString("B");

MyString D = new MyString("D");

MyString F = new MyString("F");

MyString H = new MyString("H");

treeSet.add(F);

treeSet.add(H);

treeSet.add(B);

treeSet.add(D);

System.out.println("Before Altering....");

displaySet(treeSet);

treeSet.remove(H);

H.setName("C");

treeSet.add(H);

//treeSet.

//Collections

System.out.println("After Altering....");

displaySet(treeSet);

}

private static void displaySet(Set treeSet) {

Iterator treeSetIterator = treeSet.iterator();

while(treeSetIterator.hasNext()) {

Object obj = treeSetIterator.next();

System.out.println(obj);

}

}

}

Regards,

Loga

Loga_07a at 2007-7-13 0:26:10 > top of Java-index,Core,Core APIs...
# 7

> In your case, before altering the attribute of the

> object H (from 'H' to 'C'),

> remove that object from Set, alter the attribute of

> the object and add the object again to the Set. This

> will resolve your problem.

How is your answer different from reply #1?

prometheuzza at 2007-7-13 0:26:10 > top of Java-index,Core,Core APIs...
# 8

> Hi,

>

> I have attached a sample program on that. Please have

> a look into it.

>

> public class MyString implements Comparable {

Why on earth don't you just use a regular String instead of this MyString class?

> System.out.println("GOD IS GREAT !!!");

> ...

WTF?

prometheuzza at 2007-7-13 0:26:10 > top of Java-index,Core,Core APIs...
# 9
Both the answers are same only.Regards,Loga
Loga_07a at 2007-7-13 0:26:10 > top of Java-index,Core,Core APIs...
# 10
Why i used MyString is, String is immutable. Altering the attribute of String would result in a new String. So to overcome that, I used my own String (MyString class). Moreover, i didn't use arrays concept. Regards,Loga
Loga_07a at 2007-7-13 0:26:10 > top of Java-index,Core,Core APIs...
# 11
> Both the answers are same only.Then why bother posting the same answer?
prometheuzza at 2007-7-13 0:26:10 > top of Java-index,Core,Core APIs...
# 12
i given the solution with different approach (by not using arrays)Regards,Loga
Loga_07a at 2007-7-13 0:26:10 > top of Java-index,Core,Core APIs...
# 13
As stated in the OP, I am aware of removing the element before the change. This is undesirable. If there is no way to remove after the change, then I will continue to resort the whole set per change.Of course I am still violating the contract by having the change while in the
_dnoyeBa at 2007-7-13 0:26:10 > top of Java-index,Core,Core APIs...
# 14

> As stated in the OP, I am aware of removing the

> element before the change.

Oh? I only see a question if you have to do that in order to end up with a (re) sorted set. The answer is yes.

> This is undesirable.

I fail to see why you'd consider a deletion after an alteration, but not before it.

prometheuzza at 2007-7-13 0:26:10 > top of Java-index,Core,Core APIs...
# 15

I'm curious too about what design or requirements prevents you from taking the element out before the change.

Anyway, if you can afford it, you may want to sort the set by an oldName attribute. In this way any client can change name (but not oldName) without breaking any contracts. And if you can get hold of the object after the change, you can take it out of the set, copy name to oldName and re-insert.

It may not be worth bothering, though. Resorting, say, 500 elements may not be a big deal.

OleVVa at 2007-7-21 23:12:24 > top of Java-index,Core,Core APIs...
# 16

Taking the element out before the change would cause the process to be divided into pieces. Currently there is change, events fire, objects respond to events.

If I try to take item out before change, then we have a pre-change event, a change, then a post change event. If the change fails, we now need a change-failure event so those that took out the set can put back into the set in the old position.

Too complex. my program is large and these actions are not happening within a small scope.

_dnoyeBa at 2007-7-21 23:12:24 > top of Java-index,Core,Core APIs...
# 17

> > As stated in the OP, I am aware of removing the

> > element before the change.

>

> Oh? I only see a question if you have to do that in

> order to end up with a (re) sorted set. The answer is

> yes.

>

Read it again. All of it.

_dnoyeBa at 2007-7-21 23:12:24 > top of Java-index,Core,Core APIs...
# 18
Is having the containing map or set register a PropertyChangeListener on its elements an option?
jverda at 2007-7-21 23:12:24 > top of Java-index,Core,Core APIs...
# 19

> > > As stated in the OP, I am aware of removing the

> > > element before the change.

> >

> > Oh? I only see a question if you have to do that in

> > order to end up with a (re) sorted set. The answer is

> > yes.

>

> Read it again. All of it.

I did. This is what I read... again:

"Must I be informed about the pending name change and remove the item beforehand?"

prometheuzza at 2007-7-21 23:12:24 > top of Java-index,Core,Core APIs...
# 20
> Is having the containing map or set register a> PropertyChangeListener on its elements an option?There are listeners. The question is how to respond when the change notification arrives.
_dnoyeBa at 2007-7-21 23:12:24 > top of Java-index,Core,Core APIs...
# 21

> > > > As stated in the OP, I am aware of removing

> the

> > > > element before the change.

> > >

> > > Oh? I only see a question if you have to do that

> in

> > > order to end up with a (re) sorted set. The

> answer is

> > > yes.

> >

> > Read it again. All of it.

>

> I did. This is what I read... again:

> "Must I be informed about the pending name change

> and remove the item beforehand?"

So from that you should understand that I am aware of the possibility of removing the objects before hand. The question is not is that possible, but if there is another way.

_dnoyeBa at 2007-7-21 23:12:24 > top of Java-index,Core,Core APIs...
# 22

> > I did. This is what I read... again:

> > "Must I be informed about the pending name change

> > and remove the item beforehand?"

>

> So from that you should understand that I am aware of

> the possibility of removing the objects before hand.

> The question is not is that possible, but if there

> is another way.

That's all rather implicit reasoning if you ask me. I read it as a question. A question I answered with a "yes".

Well, good luck with it anyway.

prometheuzza at 2007-7-21 23:12:24 > top of Java-index,Core,Core APIs...