Как использовать java.Set - PullRequest
       7

Как использовать java.Set

15 голосов
/ 22 марта 2010

Я пытаюсь заставить его работать какое-то время, но просто не могу этого понять. У меня есть объект Башня, построенная из блоков. Я уже заставил это работать, используя массивы, но я хотел изучить Set. Я хотел бы получить подобную функциональность к этому:

public class Tower {


public Tower(){
}

public Tower add(Block k1){

    //(...)
    //if block already in tower, return "Block already in tower"
}

public Tower delete(Block k1){

    //(...)
    //if block already dleted, show "No such block in tower"
}

}

Кто-то дал мне код, но я постоянно получаю ошибки при попытке его использовать:

Set<Block> tower = new HashSet<Block>();

boolean added = tower.add( k1 );
if( added ) {
System.out.println("Added 1 block.");
} else {
System.out.println("Tower already contains this block.");
}

Как это реализовать?

Ответы [ 4 ]

54 голосов
/ 22 марта 2010

Первое, что вам нужно изучить, это java.util.Set API .

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

    Set<Integer> numbers = new TreeSet<Integer>();

    numbers.add(2);
    numbers.add(5);

    System.out.println(numbers); // "[2, 5]"
    System.out.println(numbers.contains(7)); // "false"

    System.out.println(numbers.add(5)); // "false"
    System.out.println(numbers.size()); // "2"

    int sum = 0;
    for (int n : numbers) {
        sum += n;
    }
    System.out.println("Sum = " + sum); // "Sum = 7"

    numbers.addAll(Arrays.asList(1,2,3,4,5));
    System.out.println(numbers); // "[1, 2, 3, 4, 5]"

    numbers.removeAll(Arrays.asList(4,5,6,7));
    System.out.println(numbers); // "[1, 2, 3]"

    numbers.retainAll(Arrays.asList(2,3,4,5));
    System.out.println(numbers); // "[2, 3]"

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

В двух словах:

  • @Override оба или нет;никогда не один. (очень важно, потому что он должен удовлетворять свойству: a.equals(b) == true --> a.hashCode() == b.hashCode()
    • Будьте осторожны с написанием boolean equals(Thing other) вместо этого; это не является правильным @Override.
  • Для ненулевых ссылок x, y, z, equals должно быть:
    • рефлексивно: x.equals(x).
    • симметрично: x.equals(y) тогда и только тогда, когда y.equals(x)
    • переходный: если x.equals(y) && y.equals(z), то x.equals(z)
    • непротиворечивый: x.equals(y) не должен изменяться, если объекты не мутировали
    • x.equals(null) == false
  • Общий контракт для hashCode следующий:
    • непротиворечивый: возвращает то же число, если только не произошла мутация
    • в соответствии с equals: если x.equals(y), тоx.hashCode() == y.hashCode()
      • Строго говоря, неравенство объектов не требует неравенства хеш-кода
      • , но неравенство хеш-кода обязательно требует неравенства объектов
  • То, что считается мутацией, должно быть согласовано между equals и hashCode.

Далее, вы можете наложить порядок ваших объекты.Вы можете сделать это, сделав тип вашего инструмента Comparable или предоставив отдельный Comparator.

Наличие любого из них облегчает сортировку ваших объектов (Arrays.sort, Collections.sort(List)).Он также позволяет использовать SortedSet, например, TreeSet.


Дополнительные показания по стеку:

2 голосов
/ 22 марта 2010

Вы переопределили равно и hashCode в классе блоков?

EDIT:

Я предполагал, что вы имеете в виду, что это не работает во время выполнения ... Вы имели в виду это или во время компиляции? Если время компиляции, что сообщение об ошибке? Если происходит сбой во время выполнения, что такое трассировка стека? Если он компилируется и запускается, но не работает правильно, то вероятны проблемы с равными и hashCode.

1 голос
/ 22 марта 2010

Трудно ответить на этот вопрос с предоставленной информацией. Ничто не выглядит особенно неправильно с тем, как вы используете HashSet.

Хорошо, я рискну предположить, что это не проблема компиляции, и когда вы говорите «получать ошибки», вы имеете в виду «не получить поведение, которое [вам] нужно».

Я также выйду на конечность и предположу, что, возможно, методы вашего блока, равные hashCode, не переопределены должным образом.

0 голосов
/ 20 мая 2014

Поскольку это HashSet, вам нужно переопределить hashCode и равно методам. http://preciselyconcise.com/java/collections/d_set.php содержит пример, объясняющий, как реализовать hashCode и методы equals

...