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

на главную - закладки

Жанры

Философия 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;

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

Моров. Том 7

Кощеев Владимир
6. Моров
Фантастика:
альтернативная история
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Моров. Том 7

Старый, но крепкий 4

Крынов Макс
4. Культивация без насилия
Фантастика:
уся
фэнтези
5.00
рейтинг книги
Старый, но крепкий 4

Я князь. Книга XVIII

Дрейк Сириус
18. Дорогой барон!
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я князь. Книга XVIII

Камень. Книга вторая

Минин Станислав
2. Камень
Фантастика:
фэнтези
8.52
рейтинг книги
Камень. Книга вторая

Чужак из ниоткуда 5

Евтушенко Алексей Анатольевич
5. Чужак из ниоткуда
Фантастика:
попаданцы
альтернативная история
фантастика: прочее
фэнтези
5.00
рейтинг книги
Чужак из ниоткуда 5

Газлайтер. Том 8

Володин Григорий
8. История Телепата
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Газлайтер. Том 8

Князь Андер Арес 2

Грехов Тимофей
2. Андер Арес
Фантастика:
рпг
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Князь Андер Арес 2

Кодекс Охотника. Книга VI

Винокуров Юрий
6. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга VI

Последний Паладин. Том 6

Саваровский Роман
6. Путь Паладина
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Последний Паладин. Том 6

Последний наследник

Тарс Элиан
11. Десять Принцев Российской Империи
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Последний наследник

Князь Андер Арес 4

Грехов Тимофей
4. Андер Арес
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
попаданцы
5.00
рейтинг книги
Князь Андер Арес 4

Газлайтер. Том 12

Володин Григорий Григорьевич
12. История Телепата
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Газлайтер. Том 12

Газлайтер. Том 39

Володин Григорий Григорьевич
39. История Телепата
Фантастика:
боевая фантастика
юмористическая фантастика
аниме
попаданцы
5.00
рейтинг книги
Газлайтер. Том 39

Иной. Том 5. Адская работа

Amazerak
5. Иной в голове
Фантастика:
боевая фантастика
городское фэнтези
технофэнтези
рпг
5.00
рейтинг книги
Иной. Том 5. Адская работа