在Java集合API中使用接口而不是具体的数据结构
我目前正在阅读Horstmann的《不耐烦的人的核心Java》(我推荐它,喜欢简洁的风格),我很难理解与集合API相关的一个练习。行动如下: 我鼓励您使用接口而不是具体的数据结构,例如在Java集合API中使用接口而不是具体的数据结构,java,collections,Java,Collections,我目前正在阅读Horstmann的《不耐烦的人的核心Java》(我推荐它,喜欢简洁的风格),我很难理解与集合API相关的一个练习。行动如下: 我鼓励您使用接口而不是具体的数据结构,例如 Map而不是TreeMap。不幸的是,这一建议仅限于此。为什么不能 您是否使用地图来表示目录? (提示:您将如何初始化它?) 尽管接口用于变量声明,但下面的代码编译和工作时没有问题。我错过了什么 Map<String, Set<Integer>> toc = new HashMap<
Map
而不是TreeMap
。不幸的是,这一建议仅限于此。为什么不能
您是否使用地图
来表示目录?
(提示:您将如何初始化它?)
尽管接口用于变量声明,但下面的代码编译和工作时没有问题。我错过了什么
Map<String, Set<Integer>> toc = new HashMap<>();
toc.put("element1", IntStream.of(1, 2, 3).boxed().collect(Collectors.toSet()));
toc.put("element2", IntStream.of (3, 4, 7).boxed().collect(Collectors.toSet()));
toc.forEach( (k, v) -> {
System.out.print(k + " ");
v.forEach(val -> System.out.print(val + " "));
System.out.println();
} );
}
Map toc=newhashmap();
toc.put(“element1”,IntStream.of(1,2,3).boxed().collect(Collectors.toSet());
toc.put(“element2”,IntStream.of(3,4,7).boxed().collect(Collectors.toSet());
toc.forEach((k,v)->{
系统输出打印(k+“”);
v、 forEach(val->System.out.print(val+);
System.out.println();
} );
}
像Map
这样的接口是继承它的所有接口和实现它的所有类的超类型。因此TreeMap
继承自Map
,并且由于您始终可以将属于子类型的任何引用指定给变量,因此将TreeMap
引用指定给Map
变量是完全可以接受的。这称为加宽参照转换
“扩展引用转换在运行时不需要特殊操作,因此在运行时也不会引发异常。它们只是以编译时可以证明正确的方式将引用视为具有其他类型。”
因此,是的,您当然可以使用映射
来表示域模型中的某些内容,但不能直接实例化接口;必须实例化实现它的具体类型(类)。这正是你申报时所做的
Map toc=newhashmap()代码>
作为这一原则的延伸,您可以同样轻松地编写
AbstractMap toc=newhashmap()代码>
因为AbstractMap
也是HashMap
的超类型
通常,您希望为变量声明最宽的类型,该类型可以容纳在您的逻辑中工作的最大可能的子类型引用集。如果您需要一个排序的地图,那么“地图”太宽;它不强制执行分类。您必须将变量声明为TreeMap
,或者更好地声明为SortedMap
通常,接口是最广泛适用的类型,但如果不是,您必须考虑它
编辑:根据评论提到了SortedMap。我与该书的作者取得了联系,他同意问题不清楚,这是为了引导读者使用通配符类型。有关工作改为:
假设您有一个类型为Map
的方法参数,有人用HashMap
调用您的方法。会发生什么?您可以改用什么参数类型
答案是,在这种情况下,应该使用通配符类型:Map
使用接口类型变量来保存对子类型的引用并不是什么新鲜事,但这是问题的主题。它从一开始就是Java的一个特性,所以书的年代不是问题。@ElliottFrisch我也很困惑,因为你可以。要回答引号中的问题,您需要使用newtreemap()
(或者newtreemap()
如果Java 7+),初始化它,并使用newtreeset()
(或者newtreeset()
)创建值。我会说Horstmann是错的,但如果没有完整的上下文,他可能会有其他的意思。我认为书中的问题是试图说明一点,即可以将变量声明为接口类型,但是你不能实例化一个接口:你必须实例化一个实现该接口的类。有一个SortedMap
接口可以用来代替TreeMap
。你知道为什么HashMap
不起作用吗?提示: