4
4
4eloBek2022-02-13 17:28:34
Java
4eloBek, 2022-02-13 17:28:34

Why does TreeSet count duplicate elements by HashSet key values ​​and not by the keys themselves?

I am new to Java. I am improving my knowledge of the language on codewars.com. Performing one of the tasks, I encountered a strange thing: I want to implement a priority queue in Dijkstra's algorithm, and for time optimization I chose such a data structure as TreeSet .

import java.util.*;

public class TestTreeSet {
  public static void main(String[] args) {
    int[][] arr = {{1, 2, 3, 4, 5, 6}, {4, 9, 1, 2, 6, 0}};
    HashMap<Integer, Integer> d = new HashMap<>();
    for (int i = 0; i < arr[0].length; i++)
      d.put(arr[0][i], arr[1][i]);
    
    TreeSet<Integer> s = new TreeSet<>(new Comparator() {
      public int compare(Object o1, Object o2) {
        return d.get((int) o1) - d.get((int) o2);
      }
    });
    for (int i = 1; i < 7; i++) s.add(i);
    System.out.println(s); // [6, 3, 4, 1, 5, 2]
    
    int k = 6;
    if (s.contains(k)) {
      s.remove(k);
      d.put(k, 2);
      System.out.println(s.add(k)); // false
    }
    System.out.println(s); // [3, 4, 1, 5, 2]
  }
}


Why (in my situation) does the TreeSet consider duplicate elements based on the key values ​​of the HashSet ?
Is it possible to do the classic prohibition on duplication of elements (keys of HashSet ), but keep sorting by key value? Thanks in advance)

Answer the question

In order to leave comments, you need to log in

1 answer(s)
M
Michael, 2022-02-13
@4eloBek

Because that's how you defined the comparator. The compare method has the following contract:
returns

  • negative value if o1 is less than o2
  • positive value if o1 is greater than o2
  • zero if o1 is equal to o2.

Actually, there is no duplication by HashSet keys here - this is the work of your comparator.
And the fact that the result of the work of the comparator contradicts the result of the work of the equals method is a programmer's mistake, from which Java cannot warn in any way.
After making the call, you yourself made it so that , that is, you yourself formulated the statement that 3 == 6. And TreeSet, of course, believes in this, why would it need to double-check you with a call to equals? This is not a hashcode, which is subject to collisions - it is a comparator, which by its nature should not allow collisions. UPD: As for your goal - the implementation of a priority queue - why did the ready-made PriorityQueue class not please you? d.put(k, 2);compare(6, 3) == 0

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question