Чтение онлайн

на главную

Жанры

Философия Java3

Эккель Брюс

Шрифт:

Pet.class, Dog class. Cat.class, Rodent.class, Mutt class. Pug.class. EgyptianMau.class. Manx.class. Cymric class. Rat.class. Mous'e.class.Hamster.class)); // Типы для случайного создания: private static final List<Class<? extends Pet» types = al1 Types.subLi st(al1 Types.i ndexOf(Mutt.class). allTypes.sizeO); public List<Class<? extends Pet» types { return types;

}

public static void main(String[] args) { System.out.printin(types);

}

} /* Output:

[class typeinfo pets.Mutt, class typeinfo.pets.Pug. class typeinfo.pets.EgyptianMau. class typeinfo pets Manx, class typeinfo.pets.Cymric, class typeinfo.pets.Rat, class typeinfo.pets.Mouse, class typeinfo.pets.Hamster] *///.-

В

будущем примере PetCount3.java контейнер Map заполняется всеми типами Pet (не только генерируемыми случайным образом), поэтому нам понадобился список allTypes. Список types представляет собой часть allTypes (создается вызовом List.subList) со всеми типами Pet, поэтому он используется для случайного генерирования Pet.

На этот раз при создании types блок try не нужен, так как необходимые проверки типов проводятся еще во время компиляции и исключения не возбуждаются, в отличие от метода Class.forName.

Теперь библиотека typeinfo.pets содержит две реализации PetCreator. Чтобы вторая реализация использовалась по умолчанию, мы можем создать фасад (fagade), использующий LiteralPetCreator:

//• typeinfo/pets/Pets java

// Фасад для получения PetCreator по умолчанию

package typeinfo.pets, import java util *,

public class Pets {

public static final PetCreator creator =

new LiteralPetCreator; public static Pet randomPetO {

return creator.randomPetO:

}

public static Pet[] createArray(int size) { return creator.createArray(size).

}

public static ArrayList<Pet> arrayListOnt size) { return creator arrayList(size);

}

} ///:-

При этом также обеспечиваются косвенные вызовы randomPet, createArray и arrayList.

Поскольку PetCount.countPets получает аргумент PetCreator, мы можем легко проверить работу LiteralPetCreator (через представленный фасад):

II. typeinfo/PetCount2.java import typeinfo pets *.

public class PetCount2 {

public static void main(String[] args) { PetCount.countPets(Pets creator),

}

} /* (Выполните, чтобы увидеть результат) *///:-Результат будет таким же, как у PetCount.java.

Динамический вызов instanceof

Метод Class.islnstance позволяет выполнить динамическую проверку типа объекта. Благодаря ему в примере PetCount.java наконец-то можно будет избавиться от нагромождения instanceof:

II: typeinfо/PetCount3.java

// Using isInstanceO

import typeinfo.pets.*:

import java.util.*,

import net.mindview.util *;

import static net.mindview util Print *;

public class PetCount3 {

static class PetCounter

extends LinkedHashMap<Class<? extends Pet>,Integer> { public PetCounter {

super(MapData map(LiteralPetCreator.allTypes, 0)).

}

public void count(Pet pet) {

// Class.isInstanceO

избавляет от множественных instanceof: for(Map Entry<Class<? extends Pet>.Integer> pair entrySetO) if(pair.getKey.islnstance(pet))

put(pair.getKey. pair.getValueO + 1):

продолжение &

}

public String toStringO {

StringBuilder result = new StringBuilder("{"); for(Map.Entry<Class<? extends Pet>,Integer> pair : entrySetO) {

result.append(pai r.getKey.getSi mpleName);

result.append("=");

result.append(pai r.getValue);

result.appendC, ");

}

result.delete(result.1ength0 -2, result.1ength); result.append("J"); return result.toStringO;

}

}

public static void main(String[] args) {

PetCounter petCount = new PetCounterO;

for(Pet pet : Pets.createArray(20)) {

printnbCpet.getClassO.getSimpleNameO + " "); petCount.count(pet);

}

printO;

print(petCount);

}

} /* Output:

Rat Manx Cymric Mutt Pug Cymric Pug Manx Cymric Rat EgyptianMau Hamster EgyptianMau Mutt Mutt Cymric Mouse Pug Mouse Cymric

{Pet=20, Dog=6. Cat-9. Rodent=5, Mutt-3. Pug=3. EgyptianMau=2, Manx=7, Cymric=5, Rat=2,

Mouse=2, Hamster=l}

*///:-

Для подсчета всех разновидностей Pet контейнер PetCounter Map заполняется типами из LiteralPetCreator.allTypes. При этом используется класс net.mindview. util.MapData, который получает Iterable (allTypesList) и константу (0 в данном случае) и заполняет Map ключами из allTypes со значениями 0. Без предварительного заполнения Map будут подсчитаны только случайно сгенерированные типы, но не базовые типы (такие, как Pet и Cat).

Как видите, метод islnstance избавил нас от необходимости нагромождать конструкции с instanceof. Вдобавок теперь в программу можно легко добавить новые типы Pet — для этого следует просто изменить массив LiteralPet Creator, types; остальная часть программы не потребует правки (которая была бы неизбежна с операторами instanceof).

Метод toStringO был перегружен для получения удобочитаемого вывода.

Рекурсивный подсчет

Контейнер Map в PetCount3.PetCounter был заполнен всеми классами Pet. Вместо предварительного заполнения карты мы также можем воспользоваться методом Class.isAssignableFrom и создать обобщенный инструмент подсчета, не ограниченный подсчетом Pet:

//: net/mi ndvi ew/uti1/TypeCounter.java // Подсчет экземпляров в семействе типов package net.mindview.util;

import java.util.*;

public class TypeCounter extends HashMap<Class<?>,Integer>{ private Class<?> baseType; public TypeCounter(CIass<?> baseType) { this.baseType = baseType;

Поделиться:
Популярные книги

Неучтенный элемент. Том 4

NikL
4. Антимаг. Вне системы
Фантастика:
фэнтези
5.00
рейтинг книги
Неучтенный элемент. Том 4

Вернувшийся: Первые шаги. Том II

Vector
2. Вернувшийся
Фантастика:
боевая фантастика
космическая фантастика
рпг
5.00
рейтинг книги
Вернувшийся: Первые шаги. Том II

Рассвет русского царства 3

Грехов Тимофей
3. Новая Русь
Фантастика:
историческое фэнтези
альтернативная история
5.00
рейтинг книги
Рассвет русского царства 3

Этот мир не выдержит меня. Том 2

Майнер Максим
2. Первый простолюдин в Академии
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Этот мир не выдержит меня. Том 2

Трапеция

Брэдли Мэрион Зиммер
Проза:
современная проза
5.00
рейтинг книги
Трапеция

Технарь

Муравьёв Константин Николаевич
1. Технарь
Фантастика:
космическая фантастика
попаданцы
7.13
рейтинг книги
Технарь

Прапорщик. Назад в СССР. Книга 7

Гаусс Максим
7. Второй шанс
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Прапорщик. Назад в СССР. Книга 7

Наследник

Назимов Константин Геннадьевич
3. Травник
Фантастика:
фэнтези
6.80
рейтинг книги
Наследник

На границе империй. Том 10. Часть 10

INDIGO
Вселенная EVE Online
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 10. Часть 10

Эмиссар

Листратов Валерий
8. Ушедший Род
Фантастика:
боевая фантастика
аниме
попаданцы
7.50
рейтинг книги
Эмиссар

Первый среди равных

Бор Жорж
1. Первый среди Равных
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Первый среди равных

Дважды одаренный. Том V

Тарс Элиан
5. Дважды одаренный
Фантастика:
аниме
альтернативная история
городское фэнтези
5.00
рейтинг книги
Дважды одаренный. Том V

Черный Маг Императора 14

Герда Александр
14. Черный маг императора
Фантастика:
аниме
сказочная фантастика
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Черный Маг Императора 14

Назад в СССР 5

Дамиров Рафаэль
5. Курсант
Фантастика:
попаданцы
альтернативная история
6.64
рейтинг книги
Назад в СССР 5