2016-12-01 1 views
1
  1. Я пробовал делать пользовательские заказы в моей TreeMap в зависимости от длины строки. Почему я получаю только один ключ, если длина строки такая же, несмотря на то, что она имеет разные строки.Почему я получаю только один ключ в наборе ключей при перегрузке Comparable в TreeMap в Java

  2. Как исправить это и каковы последствия для equomet meth0d, будет ли он когда-либо использоваться или будет сравнивать, чтобы занять его место.

Код:

import java.util.Comparator; 
import java.util.Map; 
import java.util.TreeMap; 

public class Student implements Comparable { 
    int RollNo; 
    String Name; 
    public Student(int RollNo, String Name) { 
     this.RollNo = RollNo; 
     this.Name = Name; 
    } 

    public int compareTo(Object arg0) { 
     Student str = (Student) arg0; 
     return Integer.valueOf(str.Name.length()).compareTo(Integer.valueOf(this.Name.length())); 
    } 

    public static void main(String[] args) { 
     Map<Student, Integer> mp = new TreeMap<Student, Integer>(); 
     mp.put(new Student(1, "Sameer"), 1); 
     mp.put(new Student(2, "Aameer"), 2); 

     for(Student st : mp.keySet()){ 
      System.out.println((st.Name)); 
     } 
    } 
} 
+0

КСТАТИ: 'compareTo' может быть wriiten как' вернуть str.Name.length() - this.Name.length(); '. – PeterMmm

ответ

2

Вашего метод compareTo сравнивает длину имени String s вместо их содержаний, так Student s, имеющие имена с одинаковой длиной считается идентичным по TreeMap.

Другими словами, Comparable или Comparator, используемый TreeMap, определяет порядок и уникальность ключей.

Вы можете решить проблему, заказав TreeMap оба длиной имени и содержание имен (когда длины равны):

public int compareTo(Object arg0) { 

    Student str = (Student) arg0; 

    int lengthComp = Integer.valueOf(str.Name.length()).compareTo(Integer.valueOf(this.Name.length())); 
    if (lengthComp == 0) { 
     // compare names if the lengths are equal 
     return str.Name.compareTo(this.Name); 
    } else { 
     return lengthComp; 
    } 
} 

Кроме того, это лучше для вашего класса для реализации Comparable<Student>, что позволит ваш метод compareTo, чтобы принять аргумент Student.

Как исправить это и каковы последствия для equomet meth0d, будет ли он когда-либо использоваться или будет сравнивать, чтобы занять его место.

equals не используется TreeMap и compareTo действительно занимает свое место.

-1

Ответ указан в TreeMap.put. При переопределении метода compareTo второй put заменяет только значение для ключа, потому что две строки имеют одинаковую длину.

1

поскольку compare() возвращает 0 для обоих ключей, они считаются равными при сортировке. См. https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html, чтобы подчеркнуть, почему строго рекомендуется сравнивать поведение, совместимое с equals(), но в нижней строке указано, что второй ключ не добавляется, так как он считается равным первому.

Решение состоит в том, чтобы сделать ваше сравнение согласованным с равным, добавив любой развязывающий выключатель. Например, если две строки не равны, но имеют такую ​​же длину, возвращают их лексикографический порядок или вычисляют хэш, основанный на действительных символах.

+0

Так что нам нужно переопределить равные здесь? ow ли этот эффект равен поведению, будет ли равен никогда не называться? – Sameer

+0

equals() ist никогда не вызывается в этом случае, но это стандартная рекомендация утверждать, что a.equals (b) == (a.compare (b) == 0), чтобы избежать противоречивого поведения. В вас overrode equals() здесь ничего не изменится, но станет более очевидным, что вы считаете два ключа равными. –

0

Длина строки для «Shameer» и «Aameer» одинакова. Таким образом, метод java compareTo будет рассматривать оба значения (учитывая длину). Таким образом, оба объекта считаются равными при сортировке.

При добавлении объекта к ключу в интерфейсе карты значение должно быть уникальным, это нарушает метод compareTo. Таким образом, не удалось добавить вышеуказанные значения.

Как вы уже знаете, что в интерфейсе карты дублирующие ключи не разрешены .

Я объяснил с помощью простого примера. Если значение ключа одинаково, вы не можете добавить значения в интерфейс карты.

import java.util.Map; 
import java.util.TreeMap; 

public class Student2 { 

public static void main(String[] args) { 

    Map<String, Integer> mp = new TreeMap<String, Integer>(); 

    mp.put("Sameer", 1); 
    mp.put("Sameer", 2); 

    for(String st : mp.keySet()){ 
     System.out.println((st)); 
    } 
} 
} 

Результат: Самир

Смежные вопросы