黑马程序员_5_利用反射验证TreeSet集合只是一个包装
2014-04-01 13:05
295 查看
利用反射验证TreeSet集合只是一个包装
--------------------------------android培训、java培训、期待与您交流!
-----------------------------------
TreeSet集合,二叉树数据结构,存储有序,不可以存放相同对象。
TreeMap集合,二叉树数据结构,key存储有序,不同存放相同key,值没有要求,只要是Object的子类或Object类都可以。
两个都是二叉树,那不成SUN公司写了两种二叉树结构的代码?还是其中有一个只是个包装而已??不多说,先验证一下~
import java.lang.reflect.Field;
import java.util.*;
import java.util.TreeSet;
public class Demo12 {
public static void main(String[] args)throws Exception
{
TreeSet ts=new TreeSet();
ts.add(1);
ts.add(2);
ts.add(3);
先弄个TreeSet集合出来,然后几个值进去,具有比较性才能行,1,2,3是包装类,自动包装成Integer对象,而Integer对象又实现过Comparable,所以可以存进去。
1>弄个反射,看看TreeSet的内部成员变量是哪些??
Field[] field=ts.getClass().getDeclaredFields();
for(Field i:field)
System.out.println(i);
第一个是个Map集合的子接口,
第二个是个 常量 Object类型的。
第三个不知道是个什么······· -_-#
看样子只有这个Map集合的子接口像一个容器,那就拿它来做文章。
NavigableMap是一个接口,接口是不可以实例化的,估计是用多态的形式接收这个实例化对象的,既然知道是个Map的子接口话,子接口都可以接收,难道Map就不能接收??
2>用Map来接收TreeSet里面的成员NavigableMap。
首先必须实施暴力。(SUN公司写的代码,肯定很谨慎,不给你访问内部的成员)
field[0].setAccessible(true);
Map map =(Map)field[0].get(ts);
//这里要强转,jvm也不知道你取出来的是什么,所以必不可少
System.out.println(map);
拿到东西了,当然先打印一下再说,看看到底是什么。(好奇心害死猫呀~~~~~)
运行结果:
{1=java.lang.Object@dea6bc,
2=java.lang.Object@dea6bc,
3=java.lang.Object@dea6bc}
这不是刚刚存进去的值么?怎么作为Key存在Map里面?而且每个Key都对应了一个Object对象,貌似地址值都是相等的??眼睛看到的,不如亲自验证。
3>用map集合,取出每个Key对应的value。然后比较是否是同一个。
既然不知道取出来的是什么,那就用父类引用来接收。(上帝出马了)
Object obj1=map.get(1);
Object obj2=map.get(2);
Object obj3=map.get(3);
System.out.println(obj1.equals(obj2));
System.out.println(obj1.equals(obj3));
<
ce3c
/div>
运行结果:
true
True
结果出来了,证明了TreeSet真的只是个包装类,里面包装了一个Map集合,TreeSet存进去的value作为该Map集合的key存进了该Map集合里,而且TreeSet里的每个value都隐式的对应着同一个value。
验证TreeSet里的Object是否每个key对应的value.
field[1].setAccessible(true);
System.out.println(obj1.equals(field[1].get(ts)));
运行结果:
True
原来这个Object是TreeSet自动存进去的,而且始终是TreeSet.PRESENT。
那么帮TreeSet完成存储功能的Map集合跟TreeMap是什么关系呢??继承?实现?还是·······
三句代码,便出真相!
System.out.println(map.getClass()==Map.class);
System.out.println(map.getClass()==NavigableMap.class);
System.out.println(map.getClass()==TreeMap.class);
在反射中,比较两个对象的字节码是最真实可靠,这样就可以断定TreeSet到底是谁的包装。
运行结果:
false
false
True
显然这个帮助TreeSet完成存储的Map是TreeMap,也就是TreeSet是TreeMap的包装,而TreeMap实现存储的是内部类TreeMap.Entry,双重包装。
···
![](https://img-blog.csdn.net/20140401122907453?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMzc1NzU1NQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
最后献上一个草图~!
--------------------------------android培训、java培训、期待与您交流!
-----------------------------------
--------------------------------android培训、java培训、期待与您交流!
-----------------------------------
TreeSet集合,二叉树数据结构,存储有序,不可以存放相同对象。
TreeMap集合,二叉树数据结构,key存储有序,不同存放相同key,值没有要求,只要是Object的子类或Object类都可以。
两个都是二叉树,那不成SUN公司写了两种二叉树结构的代码?还是其中有一个只是个包装而已??不多说,先验证一下~
import java.lang.reflect.Field;
import java.util.*;
import java.util.TreeSet;
public class Demo12 {
public static void main(String[] args)throws Exception
{
TreeSet ts=new TreeSet();
ts.add(1);
ts.add(2);
ts.add(3);
先弄个TreeSet集合出来,然后几个值进去,具有比较性才能行,1,2,3是包装类,自动包装成Integer对象,而Integer对象又实现过Comparable,所以可以存进去。
1>弄个反射,看看TreeSet的内部成员变量是哪些??
Field[] field=ts.getClass().getDeclaredFields();
for(Field i:field)
System.out.println(i);
运行结果:
private transient java.util.NavigableMap java.util.TreeSet.m
private static final java.lang.Object java.util.TreeSet.PRESENT
private static final long java.util.TreeSet.serialVersionUID
第一个是个Map集合的子接口,
第二个是个 常量 Object类型的。
第三个不知道是个什么······· -_-#
看样子只有这个Map集合的子接口像一个容器,那就拿它来做文章。
NavigableMap是一个接口,接口是不可以实例化的,估计是用多态的形式接收这个实例化对象的,既然知道是个Map的子接口话,子接口都可以接收,难道Map就不能接收??
2>用Map来接收TreeSet里面的成员NavigableMap。
首先必须实施暴力。(SUN公司写的代码,肯定很谨慎,不给你访问内部的成员)
field[0].setAccessible(true);
Map map =(Map)field[0].get(ts);
//这里要强转,jvm也不知道你取出来的是什么,所以必不可少
System.out.println(map);
拿到东西了,当然先打印一下再说,看看到底是什么。(好奇心害死猫呀~~~~~)
运行结果:
{1=java.lang.Object@dea6bc,
2=java.lang.Object@dea6bc,
3=java.lang.Object@dea6bc}
这不是刚刚存进去的值么?怎么作为Key存在Map里面?而且每个Key都对应了一个Object对象,貌似地址值都是相等的??眼睛看到的,不如亲自验证。
3>用map集合,取出每个Key对应的value。然后比较是否是同一个。
既然不知道取出来的是什么,那就用父类引用来接收。(上帝出马了)
Object obj1=map.get(1);
Object obj2=map.get(2);
Object obj3=map.get(3);
System.out.println(obj1.equals(obj2));
System.out.println(obj1.equals(obj3));
<
ce3c
/div>
运行结果:
true
True
结果出来了,证明了TreeSet真的只是个包装类,里面包装了一个Map集合,TreeSet存进去的value作为该Map集合的key存进了该Map集合里,而且TreeSet里的每个value都隐式的对应着同一个value。
验证TreeSet里的Object是否每个key对应的value.
field[1].setAccessible(true);
System.out.println(obj1.equals(field[1].get(ts)));
运行结果:
True
原来这个Object是TreeSet自动存进去的,而且始终是TreeSet.PRESENT。
那么帮TreeSet完成存储功能的Map集合跟TreeMap是什么关系呢??继承?实现?还是·······
三句代码,便出真相!
System.out.println(map.getClass()==Map.class);
System.out.println(map.getClass()==NavigableMap.class);
System.out.println(map.getClass()==TreeMap.class);
在反射中,比较两个对象的字节码是最真实可靠,这样就可以断定TreeSet到底是谁的包装。
运行结果:
false
false
True
显然这个帮助TreeSet完成存储的Map是TreeMap,也就是TreeSet是TreeMap的包装,而TreeMap实现存储的是内部类TreeMap.Entry,双重包装。
···
最后献上一个草图~!
--------------------------------android培训、java培训、期待与您交流!
-----------------------------------
相关文章推荐
- 黑马程序员 :(反射应用 )通过反射讲<Integer>类型的集合中添加一个<String>类型的数据
- .NET----在用户控件利用包装属性+反射,使用引用页的ViewState
- C# 利用反射,遍历获得一个类的所有属性名,方法名,成员名.
- java利用反射来调用一个类的私有方法和成员变量
- java 利用注释和反射写一个简单的SQL语句拼接程序,很简单初学者
- 反射中的一个问题点:利用Method执行main方法特殊的地方
- 利用反射模仿JUnit写一个自己的测试驱动类
- 黑马程序员--Java基础加强--13.利用反射操作泛型II【TypeVariable】【GenericArrayType】【WildcardType】【Type及其子接口的来历】【个人总结】
- 利用反射模仿JUnit写一个自己的测试驱动类
- (原创)利用扩展方法,给 IEnumerable<T> 增加一个生成 Html 的 CheckBox 标签的方法,不用 C# 中的反射技术
- Java中的反射机制(二) 一个利用反射进行对象拷贝的例子
- 如何利用博客实现一个简陋的网络验证
- 利用反射生成一个没有Nullary Constructor的类的对象
- 利用反射写一个简单的错误日志插件
- C#控制台基础 activator与invoke,利用反射调用一个类的有参数方法
- 将任意一个对象中的所有String类型 的成员变量所对应字符串中的“b”改成“a”(利用反射)
- 利用ASIHttpRequest实现一个简单的登录验证
- Java中的反射机制 一个利用反射进行对象拷贝的例子
- 【IOS】利用ASIHTTPRequest 实现一个简单的登陆验证
- 黑马程序员--Java基础加强--15.利用反射操作泛型IV【通过反射Method解析泛型方法思路】【通过Method对四种Type子接口类型进行解剖】【使用递归对任意复合泛型类型进行彻底解剖】【个人