#java #casting #iterator
#java #Кастинг #итератор
Вопрос:
У меня есть ArrayList, и у меня есть коллекция этих разных объектов
Тогда у меня есть итератор для него
for(Iterator i = results.iterator(); i.hasNext();) {
Object row = i.next();
Проблема в том, что у меня есть несколько классов, использующих это. Например User.class . Как мне убедиться, что я приведу этот объект
User u = (User) row?
Комментарии:
1. Вы не используете raw
ArrayList
или необработанныйIterator
. Вы объявляете, что ваш список содержит определенный тип, напримерArrayList<User>
. Вы не используете один и тот же список для нескольких типов, если нет веской причины.2. Вы могли бы , но не должны
instanceof
использовать оператор3. Это плохой дизайн. Ваш список должен содержать один тип или подклассы того же типа, а не произвольные объекты.
4. Если у вас есть код, измените дизайн.
5. @S.Iqbal Не пытайтесь расширять неработающий код, исправьте это!
Ответ №1:
используйте instanceof!
for(Iterator i = results.iterator(); i.hasNext();) {
Object row = i.next();
if (row instanceof User) {
User u = (User) row; // this is safe
// ...
}
}
с несколькими типами
for(Iterator i = results.iterator(); i.hasNext();) {
Object row = i.next();
if (row instanceof User) {
User u = (User) row; // this is safe
// ...
} else if (row instanceof Stuff) {
Stuff u = (Stuff) row; // this is safe
// ...
}
}
с несколькими типами в общем списке
Collection<? extends Human> results = ... ;
for(Human h : results) {
if (h instanceof User) {
User u = (User) h; // this is safe
// ...
} else if (h instanceof Man) {
Man m = (Man) h; // this is safe
// ...
} else if (row instanceof Woman) {
Woman w = (Woman) h; // this is safe
// ...
}
}
для каждого варианта
for (Object row : results) {
if (row instanceof User) {
User u = (User) row; // this is safe
// ...
}
}
вариант java 8
results.stream().filter(row -> row instanceof User).map(row -> (User) row).forEach(user -> {...});
HTH!
Комментарии:
1. Это плохой дизайн с использованием необработанных типов. Никоим образом не рекомендуется.
2. @RealSkeptic оператор говорит, что у него есть несколько типов в коллекции.
3. @Highbrainer по крайней мере, используйте подстановочный знак, такой как
Collection<?>
4. @Lino У меня нет проблем с дженериками, мой пример кода не включал определения! Обратите внимание, что наличие объявленного предка в типе списка не означает, что у вас должно быть точно такое же поведение для всех реальных дочерних экземпляров в вашей коллекции. Я обновил свой ответ, чтобы сделать это (немного?) надеюсь, более полезный.