黑马程序员-java学习笔记-Collection

hasCode方法与HashSet类
  用哈希算法来提高从集合中查找元素的效率,这种方式将集合分成若干个存储区域,每隔对象可以计算出一个哈希码,可以将哈希码分组,魅族分别对应某个存储区域,根据一个对象的哈希码就可以确定该对象应该存储在哪个区域。
只有类的实例对象要被采用哈希算法进行存储和检索时,这个类才需要按要求覆盖hashCode方法,即使长须可能暂时不会on感到当前类的hashCode方法,但是为它提供一个hashCode方法也不会有什么不好,没准以后什么时候有用到这个方法了,所以,通常要求hashCode方法和equals方法一并被同事覆盖。
通常来说,一个类的两个实例对象用equals()方法来比较的结果相等时,他们的哈希码也必须相等,但反之则不成立,即equals方法比较结果不想等的对象可以有相同的哈希码。或者说哈希码相同的两个对象的equals方法比较的结果可以不等,例如,字符串“BB”和“Aa”的equals方法比较结果可定不想等,但它们的hasCode方法返回值却相等。
当一个对象被存储进HashSet集合中以后,就不能修改这个对象中的那些参与计算哈细致的自断了,否则,对象在contains方法使用该对象的当前引用作为的参数去HashSet集合中检索对象,也将返回找不到对象的结果,这回导致无法从HashSet集合中单独删除当前对象,从而造成内存泄漏。
反射的作用 -- > 实现框架的功能
框架与框架要解决的核心问题
我做房子卖给用户住,由用户自己安装门窗和空调,我做的房子就是框架,用户需要使用我的框架,把门窗插入进我提供的框架中。框架与工具类有区别。工具类被用户的类调用,而框架则是调用用户提供的类。
框架要解决的核心问题
我在写框架(房子)时,你这个用户可能还在上小学,还不会写程序呢,我写的框架程序怎样能调用到你以后写的类(门窗)呢
因为在写程序时无法知道要被调用的类名,所以,在程序中无法直接new某个类的实例对象了,而是要用反射方式来做。
配置文件要用绝对路径去读取
给用户设置配置文件路径的方法
一定要记住要用完整的路径,但完整的路径不是硬编码,而是运算出来的
用getRealPath获取程序根目录 + 相对路径也可以读取配置文件
类加载器将.class文件加载到内存中
内省 ---> 了解JavaBean
内省:IntroSpector
主要用于对JavaBean进行操作
JavaBean是一个特殊的Java类,主要用于传递数据信息,这种类中的方法主要用于访问私有的字段,方法的名称遵守某种特定的规则
如果要在两个模块之间传递多个信息,可以将这些信息封装到一个JavaBean中,这种JavaBean的实例对象通常称之为值对象(Value Object,简称VO)。这些信息在类中用私有字段来存储,如果读取或设置这些字段的值,则需要通过一些相应的方法来访问。JavaBean的属性是根据其中的setter和getter方法来确定的,而不是根据其中的成员变量。如果芳芳名为setId,中问意思即为设置id,至于你把它存到哪个变量上,不用管。
去掉set前缀,剩余部分就是属性名,如果剩余部分的第二个字母是小写的,则把剩余部分的首字母改成小的。
总之,一个类被当作JavaBean使用时,JavaBean的属性是根据方法名推断出来的,它根本看不到java类内部的成员变量
一个符合JavaBean特点的类可以当作普通类一样进行使用,但把它当作JavaBean用肯定是要带来一定额外的好处,我们才会去了解和应用JavaBean
好处:
在Java EE开发中,经常要使用到JavaBean,很多环境就要求被JavaBean方式进行操作,别人都这么用和要求这么做,那你就没什么挑选的余地。
JDK中提供了对JavaBean进行操作的一些API,这套API就成为内省。如果你自己通过get方法飞来访问私有的x,用内省这套api操作JavaBean比用普通类的方式更方便
Beanutils工具包
BeanUtils.getProperty(obj, "x");
BeanUtils.setProperty(obj,"x", value);    
java7的新特性
Mapmap = (name:"zxx", age:18)
PropertyUtils.setProperty(obj, "x", x);
PropertyUtils.getProperty(obj, "x");
**************************************
**************************************
了解注解及java提供的几个基本注解
非常重要
Annotation 注解
@SuppressWarnings
指示应该在注释元素(以及包含在该注释元素中的所有程序元素)中取消显示指定的编译警告
@Deprecated
在使用不被赞成的程序元素或在不被赞成的代码中执行重写时,编译器会发出警告
@Override
表示一个方法声明打算重写超类中的另一个方法声明。如果方法利用此注释类型进行注释但没有重写超类方法,则编译器会生成一条错误信息。
注解相当于一种标记,在程序中加了注解就等于为程序打上了某种标记。没加,则等于没有某种标记,以后,javac编译器,开发工具和其他程序可以用反射来了解你的类及各种元素上有无何种标记,看你有什么标记,就去干相应的事。标记可以加在包,类,字段,方法,方法的参数以及局部变量上
看java.lang包,可以看到JDK中提供的最基本的annotiation
注解的应用结构图
注解类---->应用了“注解类”的类----->对“应用了注解类的类”进行反射操作的类
注解类就相当于一个你的源程序中要调用的一个类,要在源程序中应用某个注解,得先准备好了这个注解类。就想你要调用某个类,得先有开发好这个类。
@Retention元注解 标注注解的生命周期
RetetionPolicy.SOURCE,RetetionPolicy.CLASS,RetetionPolicy.RUNTIME分别对应源文件,class文件,内存中的字节码
@Target 表示注解的作用域
Interface Type 1.5 新东西
注解的属性
数组类型的属性
int[] arrayAttr() default{1,2,3};
@MyAnnotation(arrayAttr={2,3,4});
如果数组属性中只有一个元素,这时属性值部分可以声落大括号
枚举类型的属性
EnumTest.TrafficLamp lamp();
@MyAnnotation(lamp=EnumTest.TrafficLamp.GREEN);
注解类型的属性
MetaAnnotation annotationAttr() default @MetaAnnotation("xxxx");
@MyAnnotation(annotationAttr=@MetaAbbotation("yyy"));
可以认为上面这个@MyAnnotation是MyAnnotation类的一个实例对象,同样的道理,可以认为上面这个@MetaAnnotation是MetaAnnotation类的一个实例对象。
泛型 Generic
JDK1.5之前集合类中可以存放任何类型的数据,所以取出数据时要进行强制类型转换,且,运行时容易出错。
JDK1.5的集合类希望你在定义集合时,明确表示你要向集合中装哪种类型的数据,无法加入指定类型以外的数据。这样再取值的时候就不需要进行类型转换。
泛型是提供给javac编译器使用的,可以限定几个中的输入类型,让编译器挡住源程序中的非法输入,编译器编译带类型说明的集合时会去除掉“类型”信息,使程序运行效率不受影响,对于参数化的泛型类型,getClass()方法的返回值和原始类型完全一样。由于编译生成的字节码会去掉泛型的类型信息,只要能跳过编译器,就可以往某个泛型集合中加入其他类型的数据,例如,哟规范涉得到集合,再调用其add方法即可。
没有使用泛型时,只要是对象,不管是什么类型的对象,都可以存储进同一个集合中。使用泛型集合,可将一个集合中的元素限定为一个特定类型,集合中只能存储同一个类型的对象,这样更安全,并且当从集合获取一个对象时,编译器也可以知道这个对象的类型,不需要对对象进行强制类型转换,这样更方便。
在JDK1.5中,还可以按原来的方式将各种不同类型的数据装到一个集合中但编译器会报告unchecked警告。
例:在Integer类型的集合中存入String
ArrayList<Integer> arr = new ArrayList<Integer>();
        arr.getClass().getMethod("add", Object.class).invoke(arr, "abc");
        System.out.println(arr.get(0));
了解泛型
ArrayList<E>类定义和ArrayList<Integer>类引用中涉及如下术语:
整个成为ArrayList<E>泛型类型
ArrayList<E>中的E成为类型变量或类型参数
ArrayList<Integer>中的Integer成为类型参数的实例或世纪类型参数
ArrayList<Integer>中的<>念typeOf
ArrayList成为原始类型
参数化类型与原始类型的兼容性
参数化类型可以引用一个原始类型的对象,编译报告警告,例如:
Collection<String> c = new Vector();
原始类型可以引用一个参数化类型的对象,编译报告警告,例如:
Collection c = new Vector<String>();
参数化类型不考虑类型参数的继承关系
Vector<String> v = new Vector<Object>();//错误
Vector<Object> v = new Vector<String>();//错误
在创建数组实例时,数组元素不能使用参数化的类型,例如,下面语句有错误
Vector<Integer> vectorList[] = new Vector<Integer>[10];
下面的程序会报错吗?
Vector v1 = new Vector<String>();//将参数化类型赋给原始类型,不抱错。
Vector<Object> v = v1;//将原始类型赋给参数化类型 不抱错
泛型中的?通配符
使用?通配符可以掉应其他各种参数化的类型,?通配符定义的变量主要用做引用,可以调用与参数无关的方法,不能调用与参数化有关的方法。
泛型中的?通配符的扩展
限定通配符的上边界
正确:Vector<? extends Number> x = new Vector<Integer>();
错误:Vector<? extends Number> x = new Vector<String>();
限定通配符的下边界
正确:Vector<? super Integer> x = new Vector<Number>();
错误:Vector<? super Integer> x = new Vector<Byte>();
限定通配符总是包括自己
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值