合规国际互联网加速 OSASE为企业客户提供高速稳定SD-WAN国际加速解决方案。 广告
### [一个动态`instanceof`函数](https://lingcoder.gitee.io/onjava8/#/book/19-Type-Information?id=%e4%b8%80%e4%b8%aa%e5%8a%a8%e6%80%81-instanceof-%e5%87%bd%e6%95%b0) `Class.isInstance()`方法提供了一种动态测试对象类型的方法。因此,所有这些繁琐的`instanceof`语句都可以从`PetCount.java`中删除: ~~~ // typeinfo/PetCount3.java // 使用 isInstance() 方法 import java.util.*; import java.util.stream.*; import onjava.*; import typeinfo.pets.*; public class PetCount3 { static class Counter extends LinkedHashMap<Class<? extends Pet>, Integer> { Counter() { super(LiteralPetCreator.ALL_TYPES.stream() .map(lpc -> Pair.make(lpc, 0)) .collect( Collectors.toMap(Pair::key, Pair::value))); } public void count(Pet pet) { // Class.isInstance() 替换 instanceof: entrySet().stream() .filter(pair -> pair.getKey().isInstance(pet)) .forEach(pair -> put(pair.getKey(), pair.getValue() + 1)); } @Override public String toString() { String result = entrySet().stream() .map(pair -> String.format("%s=%s", pair.getKey().getSimpleName(), pair.getValue())) .collect(Collectors.joining(", ")); return "{" + result + "}"; } } public static void main(String[] args) { Counter petCount = new Counter(); Pets.stream() .limit(20) .peek(petCount::count) .forEach(p -> System.out.print( p.getClass().getSimpleName() + " ")); System.out.println("n" + petCount); } } ~~~ 输出结果: ~~~ Rat Manx Cymric Mutt Pug Cymric Pug Manx Cymric Rat EgyptianMau Hamster EgyptianMau Mutt Mutt Cymric Mouse Pug Mouse Cymric {Rat=2, Pug=3, Mutt=3, Mouse=2, Cat=9, Dog=6, Cymric=5, EgyptianMau=2, Rodent=5, Hamster=1, Manx=7, Pet=20} ~~~ 为了计算所有不同类型的`Pet`,`Counter Map`预先加载了来自`LiteralPetCreator.ALL_TYPES`的类型。如果不预先加载`Map`,将只计数随机生成的类型,而不是像`Pet`和`Cat`这样的基本类型。 `isInstance()`方法消除了对`instanceof`表达式的需要。此外,这意味着你可以通过更改`LiteralPetCreator.types`数组来添加新类型的`Pet`;程序的其余部分不需要修改(就像使用`instanceof`表达式时那样)。 `toString()`方法被重载,以便更容易读取输出,该输出仍与打印`Map`时看到的典型输出匹配。