2010-08-20 2 views
11

В моем приложении Java мне нужно сравнить два элемента списка, похоже ли это или нет.Сделать элемент ArrayList нечувствительным к регистру

Короче предположим, что у меня есть два списка объявлены как показано ниже

List<String> a = new ArrayList<String>(); 
    a.add("one"); 
    a.add("three"); 
    a.add("two"); 
Collections.sort(a); 


List<String> a1 = new ArrayList<String>(); 
    a1.add("ONE"); 
    a1.add("two"); 
    a1.add("THREE"); 
Collections.sort(a); 

Если я пишу условие равенства он терпит неудачу, поскольку некоторые из элементов списка находится в другом случае как

if(a.equals(a1)){ 
    System.out.println("equal"); 
} else{ 
    System.out.println("not equal"); 
} 

Это будет результат отображения «Не равно»

Так что, пожалуйста, расскажите, как я могу сделать элемент списка без учета регистра на языке Java.

Спасибо и считают

+2

equalsIgnoreCase() - http://download-llnw.oracle.com/javase/6/docs/api/java/lang/String. HTML # equalsIgnoreCase (java.lang.String) –

+1

Решение состоит не в том, чтобы сделать * элементы * нечувствительными к регистру (что технически означало бы повторное выполнение String - нельзя продлить его, поскольку он является окончательным - с классом-оболочкой, чьи методы * equals * и * compareTo * -чувствительный), а скорее сделать сравнение * без учета регистра. – user359996

ответ

20

Почему бы не использовать вместо этого SortedSet с нечувствительным к регистру компаратором? С String.CASE_INSENSITIVE_ORDER компаратора

Вашего кодом сводятся к

Set<String> a = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER); 
    a.add("one"); 
    a.add("three"); 
    a.add("two"); 


Set<String> a1 = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER); 
    a1.add("ONE"); 
    a1.add("two"); 
    a1.add("THREE"); 

И ваши РАВНО условия должны работать без какого-либо вопроса

EDIT модифицированного в соответствии с комментариями. Спасибо всем вам, чтобы поправить меня.

+1

(вы должны использовать другой конструктор TreeSet для использования пользовательского компаратора) –

+2

Вы должны фактически использовать * 'Компаратор', который вы определили в своем примере кода ;-) –

+3

Также см. Статический компаратор String.CASE_INSENSITIVE_ORDER' в классе String –

7

Вы должны были бы сделать это вручную:

public boolean equalsIgnoreCase(List<String> l1, List<String> l2) { 
    if (l1.size() != l2.size()) { 
    return false; 
    } 
    Iterator<String> i1=l1.iterator(); 
    Iterator<String> i2=l2.iterator(); 
    while(i1.hasNext()) { 
    if (!i1.next().equalsIgnoreCase(i2.next()) { 
     return false; 
    } 
    } 
    return true; 
} 
+0

oops, stupid typo, thanks gizmo ;-) –

14

Вы должны использовать

Collections.sort(a, String.CASE_INSENSITIVE_ORDER); 

для того, чтобы разобраться, игнорируя регистр, вы можете использовать equalsIgnoreCase метод на String для сравнения со значениями

Вы можете, конечно, создать свой собственный CaseIns ensitiveList, у нас есть CaseInsensitiveSet & CaseInsensitiveMap в нашей кодовой базе

+1

Это не полное решение (ни мое сообщение ниже ;-)). –

+0

Как говорит Йоахим, это будет ** не ** сделать 'a.equals (a1)' return true. –

+0

Да, я отправил немного слишком рано, я отредактировал свой оригинальный ответ. –

0

Вам нужно будет переопределить метод equals() в списке, чтобы он делал то, что вы хотите. Посмотрите на текущий ArrayList.equals() и адаптируйте его, чтобы он сравнивался с equalsIgnoreCase вместо equals().

+0

Или вы заставляете его использовать компаратор как аргумент конструктора. Но проблема в том, что оба они нарушают контракт для 'Collection', и это может привести к тому, что все будет работать не так, как ожидалось. –

6

Вы также можете обернуть строку в вспомогательный класс и реализовать равна & сравнить методы для этого.

public class StringWrapper implements Comparable<StringWrapper> { 
    private String value; 

    StringWrapper(Strig value) { 
     this.value = value; 
    } 

    @Override boolean equals(Object o) { 
     returns String.CASE_INSENSITIVE_ORDER.equals(
      (StringWrapper) o).value 
      this.value); 
    } 

    @Override int compareTo(StringWrapper sw) { 
     returns String.CASE_INSENSITIVE_ORDER.compare(
      this.value 
      sw.value);   
    } 

    @Override String toString() { 
     return this.value; 
    } 

    @Override int hashCode() { 
     return this.value.toLowerCase.hashCode(); 
    } 
} 

And then : 

List<StringWrapper> a = new ArrayList<StringWrapper>(); 
    a.add(StringWrapper("one")); 
    a.add(StringWrapper("TWO")); 
    a.add(StringWrapper("three")); 
Collections.sort(a); 
+0

Вы должны реализовать 'Comparable ' и изменить метод 'compare (Object)' compareTo (StringWrapper) '. Вы также должны реализовать 'hashCode()', что может оказаться сложным. –

+0

(StringWrapper должен реализовать интерфейс 'Comparable', иначе' Collections.sort' вызывает ошибку времени компиляции) –

+0

это, безусловно, способ пойти (+1) –

0

Как насчет написания класса Wrapper в списке, который вы используете, это позволит избежать несогласованного хранения элементов.

public class CaseInsensitiveStringList extends ArrayList<String> { 

    @Override 
    public void add(final int index, final String element) { 
     super.add(index, element.toLowerCase()); 
    } 

    @Override 
    public boolean add(final String o) { 
     return super.add(o.toLowerCase()); 
    } 

    @Override 
    public boolean addAll(final Collection<? extends String> c) { 
     final ArrayList<String> temp = new ArrayList<String>(c.size()); 
     for (final String s : c) { 
      temp.add(s.toLowerCase()); 
     } 
     return super.addAll(temp); 
    } 

    @Override 
    public boolean addAll(final int index, final Collection<? extends String> c) { 
     final ArrayList<String> temp = new ArrayList<String>(c.size()); 
     for (final String s : c) { 
      temp.add(s.toLowerCase()); 
     } 
     return super.addAll(index, temp); 
    } 
} 
0

Чтобы отсортировать список строк без учета регистра

Arrays.sort(myArray, Collator.getInstance()); 
Смежные вопросы