栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

JAVA-API(四):Map、反射机制、注解、线程池

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

JAVA-API(四):Map、反射机制、注解、线程池

一、Map

1. Map与HashMap 

java.util.Map 查找表

Map体现的结构是一个多行两列的表格,左列称为key,右列称为value。

Map总是以key-value对的形式保存数据,并根据key提取value。

在Map中key是不允许重复的(equals判断)。

Map是一个接口,规定了Map所有功能对应的方法定义,其中常用的实现类: java.util.HashMap:散列表(哈希表),使用散列算法实现的Map,当今查询速度最快的数据结构。在缓存中被大量应用。

public class MapDemo {
    public static void main(String[] args) {
        Map map = new HashMap<>();
        
        Integer value = map.put("语文",99);//新的key不会替换元素,返回值为null
        System.out.println(value);
        map.put("数学",98);
        map.put("英语",97);
        map.put("物理",96);
        map.put("化学",99);
        System.out.println(map);

        value = map.put("数学",77);//将数学原有的98替换并返回
        System.out.println(map);
        System.out.println(value);

        
        value = map.get("英语");
        System.out.println(value);
        value = map.get("体育");
        System.out.println(value);

        int size = map.size();
        System.out.println("size:"+size);

        
        value = map.remove("英语");
        System.out.println(map);
        System.out.println(value);
        
        boolean ck = map.containsKey("语文");
        boolean cv = map.containsValue(94);
        System.out.println("包含key:"+ck);
        System.out.println("包含value:"+cv);
    }
}

2. Map的遍历

Map提供了三种遍历方式:

1:遍历所有的key

2:遍历每一组键值对

3:遍历所有的value(相对不常用) 

public class MapDemo2 {
    public static void main(String[] args) {
        Map map = new HashMap<>();
        map.put("语文",99);
        map.put("数学",98);
        map.put("英语",97);
        map.put("物理",96);
        map.put("化学",99);
        System.out.println(map);
        
        Set keySet = map.keySet();
        for(String key : keySet){
            System.out.println("key:"+key);
        }

        
        Set> entrySet = map.entrySet();
        for(Map.Entry entry : entrySet){//遍历每一组键值对
            String key = entry.getKey();
            Integer value = entry.getValue();
            System.out.println(key+":"+value);
        }

        
        Collection values = map.values();
        for(Integer value : values){
            System.out.println("value:"+value);
        }

        
        Collection c = new ArrayList<>();
        c.add("one");
        c.add("two");
        c.add("three");
        c.add("four");
        c.add("five");
        for(String s : c){
            System.out.println(s);
        }
        c.forEach( s -> System.out.println(s) );


        map.forEach((k,v)-> System.out.println(k+":"+v));

    }
}

二、反射机制 1. Java反射机制

反射机制是java的动态机制,可以在程序"运行期间"再确定实例化对象,方法调用,属性操作等。

反射机制可以提高代码的灵活度,但是会带来较多的系统开销和较低的运行效率,因此不能过度依赖。

Class类

Class类称为类的类对象。

JVM加载一个类的class文件时,就会创建一个Class实例与该类绑定。因此每个被加载的 类都有且只有一个Class实例,这个实例就是该加载的类的类对象。

通过一个类的类对象我们可以获取这个类的一切信息(类名,属性,方法,构造器等)从而在 程序运行期间进行相关的操作 因此反射第一步就是要获取操作的类的类对象。而获取方式有三种:

1:类名.class Class cls = String.class; Class cls = int.class;

2:Class.forName(String className) Class cls = Class.forName("java.lang.String");//参数需要是完全限定名:包名.类名 注意:基本类型不支持此种方式获取类对象

3:ClassLoader类加载器形式获取

public static void main(String[] args) throws ClassNotFoundException {
        //获取String的类对象
//        Class cls = String.class;
//        Class cls = ArrayList.class;

        
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入要加载的类的名字:");
        String className = scanner.nextLine();
        Class cls = Class.forName(className);


        String name = cls.getName();//获取完全限定名:包名.类名
        System.out.println(name);

        name = cls.getSimpleName();//仅获取类名
        System.out.println(name);

        String packageName = cls.getPackage().getName();
        System.out.println("包名:"+packageName);
        
        //获取String类的所有公开方法(包含从超类继承的方法)
        //获取本类自己定义的方法(包含私有方法)
        Method[] methods = cls.getDeclaredMethods();
        for(Method method : methods){
            System.out.println(method.getName());
        }
    }

2. 使用反射机制实例化对象

使用反射机制实例化对象:

public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        ArrayList list = new ArrayList();
        System.out.println(list);

        //1获取要实例化对象的类的类对象
//        Class cls = Class.forName("java.util.ArrayList");
        
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入类名:");
        String className = scanner.nextLine();
        Class cls = Class.forName(className);

        //2调用Class的newInstance()来调用无参构造器
        Object obj = cls.newInstance();
        System.out.println(obj);
    }

使用指定的构造器实例化对象:

public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        Person p = new Person("李四",33);
        System.out.println(p);

        //1加载类对象
        Class cls = Class.forName("reflect.Person");
        //2通过类对象获取指定的有参构造器:Person(String,int)
//        Constructor c = cls.getConstructor();//不传参获取的就是无参构造器
        Constructor c = cls.getConstructor(String.class,int.class);
        Object obj = c.newInstance("王五",66);//new Person("王五",66);
        System.out.println(obj);
    }

3. 利用反射机制调用方法

利用反射机制调用方法:

public static void main(String[] args) throws Exception {
        Person p = new Person();
        p.watchTV();


        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入类名:");
        String className = scanner.nextLine();
        System.out.println("请输入方法名:");
        String methodName = scanner.nextLine();

        //1实例化
        //1.1加载类对象
//        Class cls = Class.forName("reflect.Person");
        Class cls = Class.forName(className);
        //1.2实例化
        Object obj = cls.newInstance();//Object obj = new Person();

        //2调用方法
        //2.1通过类对象获取要调用的方法
//        Method method = cls.getMethod("watchTV");
        Method method = cls.getMethod(methodName);
        //2.2通过方法对象执行该方法
        method.invoke(obj);//obj.watchTV()   前提是obj表示的是一个Person对象
    }

利用反射机制调用有参方法:

public static void main(String[] args) throws Exception {
        Class cls = Class.forName("reflect.Person");
        Object obj = cls.newInstance();

        //public void say(String info){
        Method method = cls.getMethod("say",String.class);
        method.invoke(obj,"你好!");//p.say("你好!");

        //public void say(String info,int count){
        Method method2 = cls.getMethod("say",String.class,int.class);
        method2.invoke(obj,"Hello",5);//p.say("Hello",5)
    }

三、注解 1. 注解

注解被大量应用与反射中,可以辅助反射机制做更多灵活的操作。后期使用的框架基本都是使用注解进行配置的。

在注解上我们有两个常用的注解用来说明当前注解的相关特性:

@Target:用于说明我们定义的注解可以被应用到哪里。

        该注解可以传递的参数为ElementType类型,用来表示可标注的位置。

        常见的有:ElementType.TYPE:在类上用

        ElementType.METHOD:在方法上

        ElementType.FIELD:在属性上用

        如果不指定@Target,则当前注解可以被应用在任何注解可使用的位置上。

@Retention:当前注解的保留级别,有三个可选值

        RetentionPolicy.SOURCE:当前注解仅保留在源代码中,编译后的字节码文件中没有该注解

        RetentionPolicy.CLASS:保留到编译后的字节码文件中,但是反射机制不可访问

        RetentionPolicy.RUNTIME:保留到字节码中且反射机制可以访问

        不指定时,默认保留级别为CLASS

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoRunClass {
}

2. 注解中定义参数的语法

注解中定义参数的语法:

类型 参数名() [default 默认值];

注:[]中的内容可写,可不写。

如果当前注解只有一个参数时,那么参数名应当叫value。

此时当我们在外面使用该注解时,可以使用:

@AutoRunMethod(3) 进行传参。此时注解中value的值为3

如果该参数名不叫value,例如,定义时如下:

public @interface AutoRunMethod{

        int num();

}

此时当我们在外面使用该注解时,可以使用:

@AutoRunMethod(num=3)

语法要求:传参时格式为:参数名=参数值

进行传参。此时注解中num的值为3

只有参数名叫value时,传递参数才可以将参数名忽略。

以上特性仅限于只有一个参数时。

当有多个参数时,例如,定义时如下:

public @interface AutoRunMethod{

        int value(); String name();

}

使用注解传递参数时,参数名都不可以忽略,必须写为name=value的格式,且顺序无所谓。

例如:

@AutoRunMethod(value=1,name="张三")

@AutoRunMethod(name="张三",value=1)

以上都正确

参数可以使用default指定默认值,那么在使用注解时。可以不指定该参数的值,此时使用默认值

public @interface AutoRunMethod{

        int value() default 1;

}

使用该注解时:

@AutoRunMethod(3)

此时value的值为3

@AutoRunMethod

此时value的值为1(默认值)

3. 反射机制访问注解
public static void main(String[] args) throws Exception {
        Class cls = Class.forName("reflect.Person");
        
        //cls所表示的类Person是否被注解@AutoRunClass标注过
        boolean flag = cls.isAnnotationPresent(AutoRunClass.class);
        if(flag){
            System.out.println("被标注了!");
        }else{
            System.out.println("没有被标注!");
        }

    }

4.获取注解中的参数
public static void main(String[] args) throws Exception {
        Class cls = Class.forName("reflect.Person");
        Method method = cls.getMethod("sayHello");
        if(method.isAnnotationPresent(AutoRunMethod.class)){
            //获取该方法上的注解@AutoRunMethod
            AutoRunMethod arm = method.getAnnotation(AutoRunMethod.class);
            //通过注解对象获取value参数的值
            int value = arm.value();
            System.out.println(value);
        }
    }

四、线程池

线程池是线程的管理机制,主要解决两方面问题:

1:控制线程的数量

2:重用线程

public class ThreadPoolDemo {
    public static void main(String[] args) {
        //创建一个2线程的线程池
        ExecutorService threadPool = Executors.newFixedThreadPool(2);
        for(int i=0;i<5;i++){
            Runnable r = new Runnable() {
                public void run() {
                    Thread t = Thread.currentThread();
                    System.out.println(t.getName()+":正在执行任务...");
                    try {
                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(t.getName()+":执行任务完毕!");
                }
            };
            threadPool.execute(r);//将任务指派给线程池
        }
    }
}


总结

本篇的内容为Java的Map集合、Java的反射机制、注解、线程池的知识点等。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1028731.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号