Поиск записи в TreeSet на лету - PullRequest
4 голосов
/ 29 августа 2011

Я пишу приложение для контактов в Java, используя библиотеки Swing и AWT.Приложение состоит из JList, который использует TreeSet в качестве abstractListModel.

TreeSet предназначен для класса Contact, который имеет класс закрытого компаратора, который сортирует контакты по их имени.метод private boolean equals(Object o) возвращает true, если у Contact тот же мобильныйNumber, что и у O (после приведения, конечно).

Я хочу добавить функцию поиска в это приложение.Я выполнил поиск JTextField и добавил keyListener, и я хочу сделать так, чтобы после нажатия каждой клавиши в списке отображался узкий набор результатов, который содержит условия поиска.Есть ли способ для этого в TreeSet или любой другой коллекции?Я хочу, чтобы он был похож на то, что есть в приложении «Музыка» на iPod, где, например, когда вы набираете букву «f», в нем перечислены все песни, содержащие букву F, но это только при вводе «пятьдесят центов».что песни певца, которого вы хотите, появляются.

Спасибо за вашу помощь.

Ответы [ 2 ]

11 голосов
/ 29 августа 2011

Если вы хотите найти все записи, начинающиеся с текста (например, "f"), вы можете использовать метод subSet(from, to), например:

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]

Поскольку параметр to для subset(from, to) является эксклюзивным, вам нужно что-то, что будет явно лучше. В моем примере я просто добавил Character.MAX_VALUE, но вы можете получить лучшую верхнюю границу. Обратите внимание, что это зависит от вашего компаратора, например, как он обрабатывает различия в регистре и т. д.

Если вы хотите фильтровать с использованием подстановочных знаков, как и все тексты , содержащие текст (например, f будет переводиться в *f*), вам придется все равно повторить и проверить все записи. В этом случае вы не получите никакого преимущества, используя отсортированный набор.

Редактировать: обновил пример с вашими данными (добавив и меня :)).

1 голос
/ 29 августа 2011

Вы можете использовать метод boolean startsWith(String prefix) класса java.lang.String, чтобы проверить, какие значения в наборе начинаются со строки ввода.

Пример:

public void getName(Set<String> t, String s)
    {
        for(String str : t) 
        {
            if(str.toLowerCase().startsWith(s.toLowerCase()))
                System.out.println(str);
        }
    }

ввод:

Set<String> test = new TreeSet<String>();

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

если вы вызываете метод:

getName(test, "eri");

вывод будет:

Erica
Erich
Erin
...