黑马程序员_Java基础加强_注释的使用,哈希算法补充

一,注释

注释就相当于一个标记,加上了标记就是给自己的程序加上了某种标记,标记可以加在
包,类,方法,字段,方法参数,局部变量上面。在java.lang中有最基本的注释类型。
在myEclipse中编写Java程序时方法的重写的注释是:@override,一旦添加这个注释,如果重写方法
是不下心写错一点,编译器是会报错的。

比如:当某个方法不建议使用,我们就可以加注释让这个方法称为一个过时方法。
@Deprecated  //该注释告诉使用者这个方法已经过时了(过时了还是可以用的,API中过时的方法的原理)。
public static void sayHello() {
System.out.println(“hello,黑马”);
}

一个注释其实是一个类,有些过时的方法如果想取消过时的提示,可以通过@SuppressWarnings(“deprecation”)
取消。
@SuppressWarnings(“deprecation”)  //这是一个注释,这个注释告诉编译器,不要提示我使用的方法过期了。

1,自定义注释:
自定义一个最简单的注释:

package cn.itheima.myday02;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
//源注释
@Retention(RetentionPolicy.RUNTIME)//源注释,这是interface的注释,告诉编译器该注释生命周期是运行时,否则则是默认编译时期
@Target({ElementType.METHOD,ElementType.TYPE}) //告诉使用该注释的程序,这个接口注释可以放在类上也可以放在方法上
public @interface MyAnnotation {
}
package cn.itheima.myday02;
@MyAnnotation//注释也是一个类
public class AnnotationTest {
    public static void main(String[] args) {
        //判断MyAnnotation这个注释是否存在,存在则打印出来,如果不设置MyAnnotation的源注释,那么运行时则看不到结果,因为注释默认生命周期是编译时
        if(AnnotationTest.class.isAnnotationPresent(MyAnnotation.class)) {
            MyAnnotation myAnnotation = (MyAnnotation)AnnotationTest.class.getAnnotation(MyAnnotation.class);
            System.out.println(myAnnotation);//@cn.itheima.myday02.MyAnnotation()
        }
    }
}

2,源注释:
@Retention的取值有三种,分别是:RetentionPolicy.SOURCE,RetentionPolicy.CLASS,RetentionPolicy.RUNTIME.分别对应的是Java源文件,Class文件,
运行时内存中的字节码。

@Target:设置账户是应该加在哪里,注释的位置可以使包,类,方法,字段,方法参数,局部变量。
Target的值等于ElementType.METHOD是告诉注释只可以加在方法上,如果想加在类上,可以使用数组。
{ElementType.METHOD,ElementType.TYPE} ,告诉使用该注释的程序,这个接口注释可以放在类上也可以放在方法上。

注意:使用源注释以及枚举属性值都不用死记,只要会查看API下的帮助文档,就可以了。 在java.lang.annotation包下面的类。

注释的高级应用:
因为自定义注释是在interface前面加一个@符号,然后通过@Retention和@Target设置注释的生命周期和
注释位置。注释内部的定义也是有规则的,必须是类型属性名加小括号,可以通过default关键字设置属性
的默认值。比如:String value() default “abc”;在类中调用该注释的时候,需要设置属性值,然后通过
反射使用该属性的值。

注释的返回值类型可以是八种基本数据类型,Class类型,注解类型,枚举类型,以及上述这些类型的
数组类型。(参看:Java language specification)

应用示例:
1,创建的注释类
 



@Retention(RetentionPolicy.RUNTIME) //RetentionPolicy.RUNTIME说明一个注解的生命周期
@Target({ElementType.METHOD,ElementType.TYPE}) //告诉使用该注释的程序,这个接口注释可以放在类上也可以放在方法上
public @interface ItcastAnnotation {
    String color() default "Blue";  //注释的默认值是Blue   
                //在注解中添加了属性,在使用这个属性的时候要为注释设置属性--->@ItcastAnnotation(color="RED")
    String value();
    int[] array() default {5,8,6};//返回值类型是数组类型
    EnumTest.TrafficLight light() default EnumTest.TrafficLight.RED;//返回值类型是枚举类型
    
    //添加一个返回值类型是注解类型的注解,MetaAnnotation在下面
    MetaAnnotation metaAnnotation() default @MetaAnnotation("lhm");
}
//被调用的注解类
public @interface MetaAnnotation {
    String value();
}

2,使用反射调用注解



@ItcastAnnotation(metaAnnotation = @MetaAnnotation("flx"),color="Red",value="abc",array={1,2,5})//数组中如果只有一个元素而已直接写数组名等于哪一个值
public class AnnotationTest {
    public static void main(String[] args) {
        if(AnnotationTest.class.isAnnotationPresent(ItcastAnnotation.class)) {//检查ItcastAnnotation注释是否存在
            //通过反射回去自定义的注解类字节码
            ItcastAnnotation annotation = (ItcastAnnotation)AnnotationTest.class.getAnnotation(ItcastAnnotation.class);
            System.out.println(annotation);//@cn.itcast.day2.ItcastAnnotation(metaAnnotation=@cn.itcast.day2.MetaAnnotation(value=flx), 
                                        //color=Red, light=RED, array=[1, 2, 5], value=abc)
            
            //对注解的属性值的使用
            System.out.println(annotation.color());//RED
            System.out.println(annotation.value());//abc
            System.out.println(annotation.array().length);//3
            System.out.println(annotation.light().nextLight());//GREEN   默认值是RED
            System.out.println(annotation.metaAnnotation().value());//flx
        }
    }
}

二,哈希算法补充
        集合框架ArrayList和HashSet集合的比较以及hashCode()方法
ArrayList底层的数据结构是数组,可以有重复的元素,因为ArrayList集合的每个元素是有索引的,存储顺序就是按照索引顺序 存储的。HashSet集合的底层数据结构是哈希表,里面不能有重复的元素,它比较元素是不是重复的原理是通过equals方法和hashCode
方法对元素进行比较,每次添加元素时,都会查看集合中是否有这个元素,如果有就不添加,否则才添加。HashSet集合的添加元素顺序
和取出顺序是不同的。

对于下列程序:



class Point
{
    public int s;
    public int y;
    public Point(int x,int y) {
        this.x = x;
        this.y = y;
    }   
    //重写hashCode方法
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + x;
        result = prime * result + y;
        return result;
    } 
    //重写equals方法
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        ReflectPoint other = (ReflectPoint) obj;
        if (x != other.x)
            return false;
        if (y != other.y)
            return false;
        return true;
    }
}
class ReflectTest
{
    public static void main(String[] args) {
        Collection collection = new HashSet();
        ReflectPoint pt1 = new ReflectPoint(2,5);
        ReflectPoint pt2 = new ReflectPoint(6,8);
        ReflectPoint pt3 = new ReflectPoint(7,5);
        ReflectPoint pt4 = new ReflectPoint(2,5);
        
        collection.add(pt1);
        collection.add(pt2);
        collection.add(pt3);
        collection.add(pt4);
        System.out.println(collection.size());
    }
}



哈希算法:当你想查找集合中是否存在某个元素的时候,通常是将这个元素与集合中的每个元素进行equals比较,如过相等 就返回结果,不相等则继续比较。但是如果有上万个元素,使用这种方法比效率就会相当低,所以有人就发明了一种哈希算法, 该算法来提高从集合中查找元素的方法,这种算法将集合分成若干个存储区域,每个对象可以算出一个哈希码,可以将哈希码 分组,每一组对别对应一个存储区域,根据哈希码就可以确定对象应该在哪个存储区域。

如果在Point类中没有重写hashCode方法,那么结果就是4,因为pt1和pt4虽然参数相同,但是属于不同的对象, 哈希值在内存中是不同的。

java中存在内存泄漏吗?存在。当我们使用的某个对象,使用完之后,程序继续往下运行,但是这个对象占用的内存空间却一直 没有被释放,这种情况就属于内存泄漏。

 
    原文作者:哈希算法
    原文地址: https://blog.csdn.net/u013432047/article/details/26485713
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞