Я хочу создавать коллекции, которые могут содержать повторяющиеся значения, в определенном порядке.Какая коллекция Java считает перестановки равными?
Другими словами:
{ 1, 1, 2 } == { 2, 1, 1 } == { 1, 2, 1 }
На самом деле, я хочу, чтобы иметь набор этих коллекций, так что если я пытаюсь добавить как { 1, 1, 2 }
и { 2, 1, 1 }
, второй .add()
не делает ничего.
Есть ли стандартная коллекция, которая уже ведет себя таким образом?
Если я правильно понимаю:
- ArrayList позволяет дублирующие значения, но имеет фиксированный порядок
- HashSet позволяет для того, чтобы быть произвольным, но дубликат не дорожит
- TreeSet гарантирует, что заказ константа, но не допускает повторяющихся значений
Есть ли коллекция, которую я упустил, которая допускает как повторяющиеся значения, так и произвольные или фиксированные порядок, так что две коллекции с одинаковыми элементами считаются равными?
@asteri спросил о моем прецеденте. В игре у меня есть блоки разной длины, которые можно уложить от конца до конца, чтобы заполнить определенное расстояние. Например, если расстояние равно 10, оно может быть заполнено 2-3-5 или 5-2-3 или 3-3-4 или 3-4-3 или любое количество других перестановок. В зависимости от того, какие блоки доступны, я хочу составить список всех возможных коллекций, которые помогут заполнить пробел.
CUSTOM РЕШЕНИЕ
@sprinter предложил создать подкласс ArrayList. @dasblinkenlight и @Dici предложили использовать карту для хранения { Element : Count }
записей. Я решил объединить эти два предложения. Ниже представлен подкласс TreeMap. Клавиши всегда сохраняются в том же порядке, чтобы гарантировать, что метод hashCode() производит одно и то же значение, например, с теми же ключами и значениями.
Я использовал метод increment
, чтобы упростить добавление нового вхождения определенного целочисленного значения.
package com.example.treematch;
import java.util.Map;
import java.util.TreeMap;
public class TreeMatch<K> extends TreeMap<K, Integer> {
@Override
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (!(other instanceof TreeMatch)) {
return false;
}
TreeMatch otherMatch = (TreeMatch) other;
if (size() != otherMatch.size()) {
return false;
}
for (Object key : this.keySet()) {
if (!otherMatch.containsKey(key)) {
return false;
}
}
for (Object key : otherMatch.keySet()) {
if (!this.containsKey(key)) {
return false;
}
if (this.get(key) != otherMatch.get(key)) {
return false;
}
}
return true;
}
public void increment(K key) {
Integer value;
if (this.containsKey(key)) {
value = (this.get(key)) + 1;
} else {
value = 1;
}
this.put(key, value);
}
@Override
public int hashCode() {
int hashCode = 0;
for (Map.Entry entry : this.entrySet()) {
hashCode += entry.getKey().hashCode();
hashCode = hashCode << 1;
hashCode += entry.getValue().hashCode();
hashCode = hashCode << 1;
}
return hashCode;
}
}
Mmm ... интересующийся вопрос. Не то, о чем я могу думать, хотя может быть что-то, что помогает в Apache Commons или Guava. Могу ли я попросить ваш случай использования для этого, из любопытства? – asteri
Не ответ на ваш вопрос, но легким обходным путем было бы иметь их в виде списков, а затем сортировать их и сравнивать. – asteri
Интересно: [Есть ли способ проверить, содержат ли две коллекции одни и те же элементы независимо от порядка?] (Http://stackoverflow.com/a/1565262/1762224) '->' 'HashMultiset.create (c1). equals (HashMultiset.create (c2)); ' –