2012-05-08 1 views
13

Я пишу программу с большим количеством перечислений, и мне нужно вернуть набор ключей EnumMap. Но EnumMap.keySet()Set() возвращает, поэтому для того, чтобы получить EnumSet я хочу, я должен использовать бросок:Почему EnumMap <T> .keySet() возвращает a <T>(), а не EnumSet <T>()?

EnumMap<SomeEnum, Object> myMap = getMap(); 
EnumSet<SomeEnum> myEnum = (EnumSet<SomeEnum>) myMap.keySet(); 

Если я не отбрасывают, компилятор будет жаловаться на несоответствие типов; он не может конвертировать из Set<SomeEnum> в EnumSet<SomeEnum>. Кажется излишним придать это, поскольку ключи EnumMap всегда будут перечислением. Кто-нибудь знает, почему метод keySet() был построен таким образом? Я иногда думал, что это может быть связано с тем, что EnumSet является абстрактным классом, но, безусловно, EnumMap может просто вернуть все, что предлагает фабричный метод EnumSet.

Приветствия, все!

EDIT: Мне очень жаль, приведенный выше код выдает CastClassException. Вы можете получить EnumSet с помощью

Я действительно должен был проверить перед публикацией.

+5

Вы получаете 'Set '. Каково было бы получить «EnumSet »? –

+0

@PaulBellora Вы правы, это неправильно. Я исправлю это. Должно быть 'EnumSet myEnum = EnumSet.copyOf (myMap.keySet());' – jalopezp

+0

Также здесь есть прекрасный вид источника, с встроенным javadoc: http://grepcode.com/file/repository.grepcode.com /java/root/jdk/openjdk/6-b14/java/util/EnumMap.java#EnumMap.keySet%28%29 –

ответ

8

Я думаю, что это потому, что keySet не является EnumSet. ;)

Причина в том, что keySet - это вид на лежащую в основе карту.

myMap.keySet().removeAll(keysToRemove); // removes multiple keys. 
+0

Но так или иначе, какой смысл? –

+0

Концептуально keySet() представляет собой набор перечислений или набор перечислений. Если API был разработан по-разному, мы могли бы иметь интерфейс EnumSet, но при условии, что это будет то же самое, что и Set, практического преимущества нет.Если EnumSet может дать вам Enum специфические методы, такие как тип элемента во время выполнения, возможно, это может иметь значение. –

0

Если вы идете к источнику этого класса, то вы будете лучше понимать scenerio почему она возвращается Set. Вы можете обнаружить, что при температуре ниже URL

http://www.docjar.com/html/api/java/util/EnumMap.java.html

Надеется, что это может помочь вам.

Наслаждайтесь!

+0

Это действительно здорово, я не знал, что могу видеть источник этого! Я все время сталкивался с API. Но да, я вижу, что метод keySet() возвращает Set KeySet, который определен в суперклассе, поэтому я не мог иметь его каким-либо другим способом. Большое спасибо, мне понравится! – jalopezp

+0

@jalopezp Спасибо, приятель –

+3

Где в 800 строках кода в вашей ссылке я ожидаю найти ответ на вопрос? Пожалуйста, разместите выдержку из соответствующей части. – Gabe

3

EnumSet - это реализация Set, которая использует перечисление для представления пространства ключа. Класс EnumSet не предоставляет дополнительных нестатических методов, поэтому нет причин возвращать EnumSet только на простой Set.

+0

Лучший ответ до сих пор и простой ИМХО , Не ссылаясь на детали реализации/не относящиеся к дизайну api) или плохое предположение, что java не имеет ковариантных типов возврата (подклассы могут возвращать подклассы возвращаемого значения в методы переопределения). –

+0

+1 Лучше всего смотреть на дизайн API, чем на код внизу. –

2

Редактировать: Я ошибался, пожалуйста, игнорируйте.

EnumMap расширяет AbstractMap, который объявляет keySet. AbstractMap не может объявить, что keySet возвращает EnumSet, поскольку это неверно для других подклассов AbstractMap. Следовательно, его возвращаемым типом является Set.

+3

Ну, это не так, подкласс может иметь более конкретные возвращаемые значения. Ковариантные типы возврата с java 5. –

Смежные вопросы