关于keySet()的疑问

hanhaipianzhou 2015-01-20 12:44:37
在Java中Set<T>是一个接口,但是在使用HashMap时,却有一个keySet()的方法,返回的是Set对象,而且Set<String> keySet=hm.keySet();能够通过编译,并运行,很是不理解,Set是接口,接口不是不能实例化么?以下是我的代码
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;

public class MainActivity
{

public static void main(String[] args)
{
HashMap<String, String> hm = new HashMap<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());
}
}
}
...全文
519 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
狂野的蜗牛 2015-02-14
  • 打赏
  • 举报
回复
哦,之前没注意这个问题,返回为set虽然是接口,但是在keySet中返回的是set的子类实例,可以多态下
爱摸鱼de老邪 2015-02-11
  • 打赏
  • 举报
回复
引用 3 楼 hanhaipianzhou 的回复:
这个实现Set的对象是什么类型?总得是一个什么Set的类对象吧,式HashSet还是其他的什么Set?
可以看JDK的源码,你就知道是怎么实现的了。 具体方法:http://blog.csdn.net/bruce128/article/details/6887732
百里马 2015-02-06
  • 打赏
  • 举报
回复
你debug一下,看看这个keySet(..)到底返回了什么? Set a = xxx; 这个a只是一个引用,接口的引用可以指向任何实现了接口的类的实例,这也是实现多态的前提
mina001 2015-02-06
  • 打赏
  • 举报
回复
看楼主应该是刚接触java不多久吧,这就是对Set接口赋值为实现类的对象啊,hm.keySet()你可以理解为返回的是一个Hashset对象, Set<String> s=new HashSet<String>(); 此处hm.keySet() 就是一个HashSet<String> 对象,可以这样理解。
多木多多木 2015-02-06
  • 打赏
  • 举报
回复
LZ,接口是可以实例化的。接口和接口实现类的关系,往深了说,就是子类继承父类。父类对象完全可以初始化为子类内容。 包括map也是接口,你的第一行代码:HashMap<String, String> hm = new HashMap<String, String>();,完全可以写成 Map<String, String> hm = new HashMap<String, String>();可以试试看。keySet()这个方法能让你取出HashMap集合中所有的键,还有一个方法是entrySet(),能把一个集合中的关系都取出来。
  • 打赏
  • 举报
回复
引用 1 楼 cacagege 的回复:
Set<String> keySet=hm.keySet(); 语句中hm.KeySet();返回的是一个实现Set接口的子类实例对象、 keySet=hm.keySet(); 可理解为父类引用指向子类对象即是多态。
+1
可乐罐 2015-02-05
  • 打赏
  • 举报
回复
接口的目的就是多种实现采用单一的调用方式,而调用者不需要知道各种实现的真正程序逻辑; 对调用者来说每一个接口实例只是一个可以使用的按照其生命周期存在的方法集合。
沁杰 2015-01-23
  • 打赏
  • 举报
回复
多态,同学看看相关知识
一大三千 2015-01-22
  • 打赏
  • 举报
回复
首先接口虽然不能被实例化,但可以声明该接口的变量,即 Set<String> keySet; 接口的变量必须引用实现了接口的类对象,即keySet=hm.keySet(); 剩下的就和1楼说的一样了。。。
student-ai 2015-01-21
  • 打赏
  • 举报
回复

//java8


    /**
     * 打印map.->java 8 版本.
     *
     * @param maps
     */
    private static void showMap(Map<Object, List<Grade>> maps) {
        maps.forEach((key,value) -> System.out.println(key));
    }

    /**
     * 打印map.java7版本.
     *
     * @param maps
     */
    private static void showMap7(Map<Object, List<Grade>> maps) {
        List<Grade> g = new ArrayList<Grade>();
        for (Object o : maps.keySet()) {
            g = (List<Grade>) maps.get(o);
            for (int i = 0; i < g.size(); i++) {
                System.out.println(g.get(i).getId() + "-->" + g.get(i).getName());
            }
        }
    }

// list
  private static void sortArrayList(int size){
        List<Integer> list = new ArrayList<Integer>(size+5);
        Random random = new Random();
        for (int i = 0; i <= size; i++) {
            list.add(random.nextInt(100));
        }
        list.sort((o1,o2) -> o1.compareTo(o2));
        list.forEach(System.out::println);
    }


  • 打赏
  • 举报
回复
你的接口只是一个引用,引用的对象HashSet是实例,调用的是实例中的方法。
hanhaipianzhou 2015-01-20
  • 打赏
  • 举报
回复
这个实现Set的对象是什么类型?总得是一个什么Set的类对象吧,式HashSet还是其他的什么Set?
可乐罐 2015-01-20
  • 打赏
  • 举报
回复
keySet()函数返回了一个实现了Set接口的实例,该实例的真正实现类未开放。这个很正常啊
cacagege 2015-01-20
  • 打赏
  • 举报
回复
Set<String> keySet=hm.keySet(); 语句中hm.KeySet();返回的是一个实现Set接口的子类实例对象、 keySet=hm.keySet(); 可理解为父类引用指向子类对象即是多态。
tiangao1102 2015-01-20
  • 打赏
  • 举报
回复
hashMap.keySet() 返回了一个hashSet 对象 hashSet 不就是 Set 的一个实现类么? 有类就有对象了啊
绝对想你所想,超乎想象!够详细,够给力! 目录 1. Jvm内存空间结构是什么样的? 1 程序计数器 1 Java栈 1 本地方法栈 2 堆 2 方法区 3 2. Jvm堆内存的划分结构和优化 3 2.1. 原理 6 2.1.1. 年轻代 6 2.1.2. 年老代 6 2.1.3. 持久代 7 2.2. 参数说明 8 2.3. 疑问解答 9 2.4. 垃圾回收器选择 10 2.4.1. 串行收集器 10 2.4.2. 并行收集器(吞吐量优先) 10 2.4.3. 并发收集器(响应时间优先) 11 2.4.4. 其它垃圾回收参数 11 2.5. 辅助信息参数设置 12 2.6. 关于参数名称等 13 3. JVM服务参数调优实战 14 3.1. 大型网站服务器案例 14 3.2. 内部集成构建服务器案例 15 4. 常量池在jvm的哪个空间里边? 17 5. jvm垃圾回收是什么时候触发的? 17 5.1. 那究竟GC为我们做了什么操作呢? 17 5.1.1. Jvm怎么判断对象可以回收了? 18 5.2. 下面我们来看一下几种垃圾收集算法 18 5.2.1. 在JDK1.2之前,使用的是引用计数器算法, 18 5.2.2. 根搜索算法 19 5.2.3. 引用的分类 19 5.3. 方法区也是会被回收的 20 5.4. 下面我们来逐一介绍一下每个垃圾回收器。 22 5.4.1. 1、 Serial收集器 22 5.4.2. 2、 ParNew收集器 23 5.4.3. 3、 ParallelScavenge 23 5.4.4. 4、 ParallelOld 24 5.4.5. 5、 SerialOld 24 5.4.6. 6、CMS 24 5.4.7. 7、 GarbageFirst(G1 ) 26 6. 常量池如何触发的垃圾回收? 28 7. 垃圾回收从哪里开始检测树进行回收?根节点是什么? 28 7.1. 目前java中可作为GC Root的对象有 29 8. Redis怎么判断对象可以清理了? 29 9. Redis怎么提高命中率? 29 10. Finalize中调用垃圾回收方法,再调用方法会回收么? 29 11. Int进行自增操作,如何保证线程安全? 30 12. Int a=1是原子方法,布尔类型进行赋值是原子方法么? 30 12.1. 多线程原子操作的安全性 31 13. Cas怎么实现unsafe? 32 13.1. Unsafe 32 13.2. CAS 32 13.3. 由CAS分析AtomicInteger原理 33 13.4. CAS的缺点 35 14. Map数据结构? 35 14.1. 一、定义 36 14.2. 二、构造函数 36 14.3. 三、数据结构 36 14.4. 四、存储实现:put(key,vlaue) 38 14.5. 五、读取实现:get(key) 41 15. 一百万数据放Arraylist数组,怎么放? 在哪个代? 42 15.1.1. 调整数组容量 42 16. Hashmap和 concurrentHashmap除了线程安全 还有什么区别,put的时候是怎么处理的。 43 17. 数据库组合索引,储存在一个叶子节点还是多个? 44 17.1. 索引的利弊与如何判定,是否需要索引: 44 17.1.1. 索引的好处 44 17.1.2. 索引的弊端 44 17.1.3. 如何判定是否须要创建索引 44 17.2. 复合索引优化 45 17.3. 下面是一些常见的索引限制问题 45 17.3.1. 使用不等于操作符(<>, !=) 45 17.3.2. 使用 is null 或 is not null 45 17.3.3. 使用函数 45 17.3.4. 比较不匹配的数据类型 46 17.4. 关于索引的排序 46 18. 数据库没有orderby默认如何排序。 46 19. 分布式事务如何实现。 46 19.1. 1 事务/分布式事务 47 19.1.1. 1.1 事务 47 19.1.2. 1.2 分布式事务与 XA 规范 47 19.2. 2 两阶段提交协议 47 19.2.1. 2.1 预提交阶段 48 19.2.2. 2.2 提交阶段 48 19.3. 3 分布式事务应用框架 48 19.3.1. 3.1 角色 48 19.3.2. 3.2 交互时序 49 19.3.3. 3.3 关键点 50 19.3.4. 参考 50 20. Jvm底层源码 51 21. 二叉树怎么实现的? 51 22. Executourservice 数据结构。哪种只能执行一个线程。 Cache怎么实现的 fixed线程如果中断,线程回自己销毁么? 51 23. 栅栏的原理和实现。 51 23.1. 1. CyclicBarrier简介 51 23.2. 2. CyclicBarrier数据结构 52 23.3. 3. CyclicBarrier源码分析(基于JDK1.7.0_40) 52 23.3.1. 3.1 构造函数 52 23.3.2. 3.2 等待函数 53 23.4. 4. CyclicBarrier的使用示例 57 23.4.1. 示例1 57 23.4.2. 示例2 59 24. Blockingqueue有几种形式?各自的编码方式。 72 24.1. Queue接口 72 24.2. BlockingQueue接口 73 24.2.1. ArrayBlockingQueue 74 24.2.2. LinkedBlockingQueue 78 24.2.3. LinkedBlockingDeque(双向并发阻塞队列) 84 24.2.4. PriorityBlockingQueue(优先阻塞队列) 85 24.2.5. 总结一下阻塞队列 90 25. Tomcat 如何管理servlet? 90 26. Servlet生命周期 90 27. 没有缓存,如何实现领券并发操作? 92

62,623

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧