Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Searching for a record in a TreeSet on the fly

I'm writing a contact book application in Java using the swing and awt libraries. The Application consists of a JList which uses a TreeSet as an abstractListModel.

The TreeSet is for a class called Contact, which has private comparator class that sorts contacts based on their first name. the private boolean equals(Object o) method returns true if the Contact has the same mobileNumber as that of O (after casting, of course).

I want to add a search functionality into this application. I've made a search JTextField and added a keyListener and what I want to do is that after each key is pressed, the list displays a narrow down set of results which contains the search terms. Is there a method for this in TreeSet or any other Collection? I want it to be similar to what you have in the Music Application in iPods, where when you type the letter 'f', for example, it lists all the songs that contain the letter F but it's only when you type 'fifty cent' that the songs by the singer you want appear.

Thanks for your help.

like image 542
W.K.S Avatar asked Dec 17 '22 10:12

W.K.S


1 Answers

If you want to find all entries that start with the text (e.g. "f"), you can use the subSet(from, to) method, like this:

SortedSet<String> s = new TreeSet<String>(new Comparator<String>() {
  public int compare( String s1, String s2 ) {
    return s1.compareToIgnoreCase( s2 );
  }

});


s.add( "Erich" );
s.add( "Erica" );
s.add( "Erin" );
s.add( "Dave" );
s.add( "Thomas" );

SortedSet<String> result = s.subSet( "e", "e" + Character.MAX_VALUE ); //"e" represents the user input
System.out.println(result);//prints [Erica, Erich, Erin]

result = s.subSet( "Eric", "Eric" + Character.MAX_VALUE );
System.out.println(result); //prints [Erica, Erich]

result = s.subSet( "Erich", "Erich" + Character.MAX_VALUE );
System.out.println(result); //prints [Erich]

Since the toparameter to subset(from, to) is exclusive, you need something that will clearly be greater. In my example I simply added Character.MAX_VALUE but you might want to get some better upper bound. Note that this depends on your comparator, e.g. how it handles case differences etc.

If you want to filter using wildcards, like all texts containing the text (e.g. f would translate to *f*), you'd have to iterate over and check all the entries anyways. In that case you don't get any advantage using a sorted set.

Edit: updated the example to your data (adding me as well :) ).

like image 168
Thomas Avatar answered Dec 27 '22 15:12

Thomas