Заказал вставку в connectedHashSet, любым быстрым способом?

Так что у меня есть LinkedHashSet, со значениями, скажем, a1, a2,, b, c1, c2

Я хочу заменить b на x так, чтобы порядок x был таким же, как порядок b.

Один очевидный способ будет

 private LinkedHashSet<String> orderedSubstitution(final Set<String> originalOrderedSet, final String oldItem,
            final String newItem) {
        final LinkedHashSet<String> newOrderedSet = new LinkedHashSet<String>();
        // Things we do to maintain order in a linkedHashSet
        for (final String stringItem : originalOrderedSet) {
            if (stringItem.equals(oldItem)) {
                newOrderedSet.add(newItem);
            } else {
                newOrderedSet.add(stringItem);
            }
        }
        return newOrderedSet;
    }

не только это O(N) я также чувствую, что это не самый быстрый способ. Есть лучшее решение? Примечание: я должен использовать связанный HashMap.

2 ответа

Решение
  1. Создать структуру Карта
  2. Вставьте всю строку с помощью
  3. Выполните вставку новой строки, добавив небольшую дельту после текущей строки OrderOfTheString.
  4. Конвертировать карту в LikedHashSet

Я знаю, что это сложно, но определенно лучше, когда мы связали хэш-карту из ~1000000 элементов и нужно вставить около 1000 элементов.

Один из способов сделать это - использовать подкласс LinkedHashSet со встроенной заменой, например:

public class ReplacingLinkedHashSet extends LinkedHashSet<String> {
    private final String what;
    private final String with;

    public ReplacingLinkedHashSet(String what, String with) {
        this.what = what;
        this.with = with;
    }

    @Override
    public Iterator<String> iterator() {
        final Iterator<String> iterator = super.iterator();
        return new Iterator<String>() {
            @Override
            public boolean hasNext() {
                return iterator.hasNext();
            }

            @Override
            public String next() {
                String next = iterator.next();
                return what.equals(next) ? with : next;
            }

            @Override
            public void remove() {
                iterator.remove();
            }
        };
    }
}

Но это означает, что замена должна быть известна до того, как вы заполните набор. (Конечно, вы могли бы легко повернуть это <String> версия в общую.


Отвечая на комментарии:

Хорошо, тогда нет способа решить это без полной итерации. Однако вы можете просто оставить LinkedHashSet нетронутым и украсить итератор при получении значений.

Другие вопросы по тегам