Почему Наборы Java не, удаляют универсальные методы?

Если не наложить два элемента так, чтобы указатель находился над ними обоими одновременно, вы не можете… по определению.

Вы могли бы написать селектор, который соответствует некоторому другому элементу, когда первый перемещается с помощью комбинаторов, но специфика будет зависеть от взаимосвязи между элементами в DOM.

См. комбинаторы в спецификации .

Например:

div div {
  margin-left: 1em;
}

div:hover {
  outline: solid red 1px;
}

div:hover~div>div {
  background: orange;
}
First
Second
Third
Child of third
Fourth

140
задан Chris Mazzola 19 September 2008 в 19:26
поделиться

7 ответов

Josh Bloch и Bill Pugh обращаются к этой проблеме в Трудные вопросы Java IV: Фантомная Ссылочная Угроза, Нападение Клона и Месть Сдвига .

Josh Bloch говорит (6:41), что они делали попытку к generify получить метода Карты, удалите метод и некоторого другого, но "это просто не работало".

существует слишком много разумных программ, которые не могли быть generified, если Вы только позволяете универсальный тип набора как тип параметра. Примером, данным им, является пересечение List из Number с и List из Long с.

70
ответ дан 23 November 2019 в 23:16
поделиться

Поскольку, если Ваш параметр типа является подстановочным знаком, Вы не можете использовать дженерик, удаляют метод.

я, кажется, вспоминаю, что столкновение с этим вопросом с Картой получает (Объектный) метод. Получить метод в этом случае не является общим, хотя он должен обоснованно ожидать быть переданным объект того же типа как первый параметр типа. Я понял, что, если Вы раздаете Карты с подстановочным знаком как первый параметр типа, затем нет никакого способа вытащить элемент из Карты с тем методом, если тот аргумент был универсален. Подстановочные аргументы не могут действительно быть удовлетворены, потому что компилятор не может гарантировать, что тип корректен. Я размышляю, что причина добавляет, универсально, то, что Вы, как ожидают, гарантируете, что тип корректен прежде, чем добавить его к набору. Однако при удалении объекта, если тип является неправильным затем, он ничему не будет соответствовать так или иначе. Если бы аргументом был подстановочный знак, то метод просто был бы неприменим, даже при том, что у Вас может быть объект, который можно ГАРАНТИРОВАТЬ, принадлежит тому набору, потому что Вы просто получили ссылку на него в предыдущей строке....

я, вероятно, не объяснил это очень хорошо, но это кажется достаточно логичным мне.

11
ответ дан 23 November 2019 в 23:16
поделиться

В дополнение к другим ответам существует другая причина, почему метод должен принять Object, который является предикатами. Рассмотрите следующий образец:

class Person {
    public String name;
    // override equals()
}
class Employee extends Person {
    public String company;
    // override equals()
}
class Developer extends Employee {
    public int yearsOfExperience;
    // override equals()
}

class Test {
    public static void main(String[] args) {
        Collection<? extends Person> people = new ArrayList<Employee>();
        // ...

        // to remove the first employee with a specific name:
        people.remove(new Person(someName1));

        // to remove the first developer that matches some criteria:
        people.remove(new Developer(someName2, someCompany, 10));

        // to remove the first employee who is either
        // a developer or an employee of someCompany:
        people.remove(new Object() {
            public boolean equals(Object employee) {
                return employee instanceof Developer
                    || ((Employee) employee).company.equals(someCompany);
        }});
    }
}

Дело в том, что объект, передаваемый remove метод, ответственен за определение equals метод. Создание предикатов становится очень простым этот путь.

6
ответ дан 23 November 2019 в 23:16
поделиться

Я всегда полагал, что это было то, потому что удаляют (), не имеет никакой причины заботиться, какой объект Вы даете ему. Достаточно легко, независимо, проверить, является ли тот объект одним из тех, Набор содержит, так как это может звонить, равняется () на чем-либо. Необходимо начать работу, тип добавляют (), чтобы гарантировать, что это только содержит объекты того типа.

4
ответ дан 23 November 2019 в 23:16
поделиться

Удалите не общий метод так, чтобы существующий код с помощью неуниверсального набора все еще скомпилировал и все еще имел то же поведение.

См. http://www.ibm.com/developerworks/java/library/j-jtp01255.html для деталей.

Редактирование: комментатор спрашивает, почему добавить метод является общим. [... удаленный мое объяснение...] Второй комментатор ответил на вопрос от firebird84 намного лучше, чем я.

-1
ответ дан 23 November 2019 в 23:16
поделиться

Поскольку это повредилось бы существующий (pre-Java5) код. например,

Set stringSet = new HashSet();
// do some stuff...
Object o = "foobar";
stringSet.remove(o);

Теперь Вы могли бы сказать, что вышеупомянутый код является неверным, но предположите, что o прибыл из неоднородного набора объектов (т.е. он содержал строки, число, объекты, и т.д.). Вы хотите удалить все соответствия, который был законен, потому что удаляют, просто проигнорировал бы нестроки, потому что они были неравны. Но если Вы заставляете его удалить (Представьте o в виде строки), который больше не работает.

-3
ответ дан 23 November 2019 в 23:16
поделиться

remove () Map , а также в Collection ) не является универсальным, поскольку вы должны иметь возможность передавать любой тип объекта remove () . Удаленный объект не обязательно должен быть того же типа, что и объект, который вы передаете в remove () ; это только требует, чтобы они были равны. Из спецификации remove () , remove (o) удаляет объект e так, что (o == null? E == null: o.equals (e)) является истинным . Обратите внимание, что нет ничего требующего, чтобы o и e были одного типа. Это следует из того факта, что метод equals () принимает в качестве параметра объект , а не только тот же тип, что и объект.

Хотя, обычно верно, что многие классы имеют equals () , определенные таким образом, что его объекты могут быть равны только объектам своего собственного класса, что, безусловно, не всегда так. Например, в спецификации для List.equals () говорится, что два объекта List равны, если они оба являются списками и имеют одинаковое содержимое, даже если они являются разными реализациями List List . Итак, возвращаясь к примеру в этом вопросе, можно иметь Map и для меня вызвать remove () с LinkedList в качестве аргумента, и он должен удалить ключ, представляющий собой список с тем же содержимым. Это было бы невозможно, если бы remove () были универсальными и ограничивали тип аргумента.

Например, в спецификации для List.equals () говорится, что два объекта List равны, если они оба являются списками и имеют одинаковое содержимое, даже если они являются разными реализациями List List . Итак, возвращаясь к примеру в этом вопросе, можно иметь Map и для меня вызвать remove () с LinkedList в качестве аргумента, и он должен удалить ключ, представляющий собой список с тем же содержимым. Это было бы невозможно, если бы remove () были универсальными и ограничивали тип аргумента.

Например, в спецификации для List.equals () говорится, что два объекта List равны, если они оба являются списками и имеют одинаковое содержимое, даже если они являются разными реализациями List List . Итак, возвращаясь к примеру в этом вопросе, можно иметь Map и для меня вызвать remove () с LinkedList в качестве аргумента, и он должен удалить ключ, представляющий собой список с тем же содержимым. Это было бы невозможно, если бы remove () были универсальными и ограничивали тип аргумента.

Итак, возвращаясь к примеру в этом вопросе, можно иметь Map и для меня вызвать remove () с LinkedList в качестве аргумента, и он должен удалить ключ, представляющий собой список с тем же содержимым. Это было бы невозможно, если бы remove () были универсальными и ограничивали тип аргумента.

Итак, возвращаясь к примеру в этом вопросе, можно иметь Map и для меня вызвать remove () с LinkedList в качестве аргумента, и он должен удалить ключ, представляющий собой список с тем же содержимым. Это было бы невозможно, если бы remove () были универсальными и ограничивали тип аргумента.

73
ответ дан 23 November 2019 в 23:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: