问题描述
在Java中Set<T>是一个接口,但是在使用HashMap时,却有一个keySet()的方法,返回的是Set对象,而且Set<String>keySet=hm.keySet();能够通过编译,并运行,很是不理解,Set是接口,接口不是不能实例化么?以下是我的代码importjava.util.HashMap;importjava.util.Iterator;importjava.util.Set;publicclassMainActivity{publicstaticvoidmain(String[]args){HashMap<String,String>hm=newHashMap<String,String>();hm.put("张三","北京");hm.put("李四","天津");hm.put("王五","上海");Set<String>keySet=hm.keySet();Iterator<String>it=keySet.iterator();while(it.hasNext()){System.out.println(it.next());}}}
解决方案
解决方案二:
Set<String>keySet=hm.keySet();语句中hm.KeySet();返回的是一个实现Set接口的子类实例对象、keySet=hm.keySet();可理解为父类引用指向子类对象即是多态。
解决方案三:
keySet()函数返回了一个实现了Set接口的实例,该实例的真正实现类未开放。这个很正常啊
解决方案四:
这个实现Set的对象是什么类型?总得是一个什么Set的类对象吧,式HashSet还是其他的什么Set?
解决方案五:
hashMap.keySet()返回了一个hashSet对象hashSet不就是Set的一个实现类么?有类就有对象了啊
解决方案六:
你的接口只是一个引用,引用的对象HashSet是实例,调用的是实例中的方法。
解决方案七:
//java8/***打印map.->java8版本.**@parammaps*/privatestaticvoidshowMap(Map<Object,List<Grade>>maps){maps.forEach((key,value)->System.out.println(key));}/***打印map.java7版本.**@parammaps*/privatestaticvoidshowMap7(Map<Object,List<Grade>>maps){List<Grade>g=newArrayList<Grade>();for(Objecto:maps.keySet()){g=(List<Grade>)maps.get(o);for(inti=0;i<g.size();i++){System.out.println(g.get(i).getId()+"-->"+g.get(i).getName());}}}//listprivatestaticvoidsortArrayList(intsize){List<Integer>list=newArrayList<Integer>(size+5);Randomrandom=newRandom();for(inti=0;i<=size;i++){list.add(random.nextInt(100));}list.sort((o1,o2)->o1.compareTo(o2));list.forEach(System.out::println);}
解决方案八:
首先接口虽然不能被实例化,但可以声明该接口的变量,即Set<String>keySet;接口的变量必须引用实现了接口的类对象,即keySet=hm.keySet();剩下的就和1楼说的一样了。。。
解决方案九:
多态,同学看看相关知识
解决方案十:
接口的目的就是多种实现采用单一的调用方式,而调用者不需要知道各种实现的真正程序逻辑;对调用者来说每一个接口实例只是一个可以使用的按照其生命周期存在的方法集合。
解决方案十一:
解决方案十二:
引用1楼cacagege的回复:
Set<String>keySet=hm.keySet();语句中hm.KeySet();返回的是一个实现Set接口的子类实例对象、keySet=hm.keySet();可理解为父类引用指向子类对象即是多态。
+1
解决方案十三:
看楼主应该是刚接触java不多久吧,这就是对Set接口赋值为实现类的对象啊,hm.keySet()你可以理解为返回的是一个Hashset对象,Set<String>s=newHashSet<String>();此处hm.keySet()就是一个HashSet<String>对象,可以这样理解。
解决方案十四:
你debug一下,看看这个keySet(..)到底返回了什么?Seta=xxx;这个a只是一个引用,接口的引用可以指向任何实现了接口的类的实例,这也是实现多态的前提
解决方案十五:
LZ,接口是可以实例化的。接口和接口实现类的关系,往深了说,就是子类继承父类。父类对象完全可以初始化为子类内容。包括map也是接口,你的第一行代码:HashMap<String,String>hm=newHashMap<String,String>();,完全可以写成Map<String,String>hm=newHashMap<String,String>();可以试试看。keySet()这个方法能让你取出HashMap集合中所有的键,还有一个方法是entrySet(),能把一个集合中的关系都取出来。
解决方案:
引用3楼hanhaipianzhou的回复:
这个实现Set的对象是什么类型?总得是一个什么Set的类对象吧,式HashSet还是其他的什么Set?
可以看JDK的源码,你就知道是怎么实现的了。具体方法:
解决方案:
哦,之前没注意这个问题,返回为set虽然是接口,但是在keySet中返回的是set的子类实例,可以多态下