Java从入门到精通 第17章 枚举类型与泛型

目录

枚举类型

泛型


枚举类型

  • 使用接口设置常量
  • 枚举类型,相当于一个类,继承于java.lang.Enum,每一个枚举类型成员是一个实例,默认被public、static、final修饰,使用时直接使用枚举类型名称调用
    • 枚举类型常用方法
    • 枚举类型中的构造方法
    • 可以在每个枚举成员内部实现接口中的方法(每个成员都要实现)

Java从入门到精通 第17章 枚举类型与泛型_第1张图片

//枚举类型的定义与使用
package ex17_enum;

interface Constants {
    public static final int Constants_A = 1;  //将常量放在接口中
    public static final int Constants_B = 12;
}

public class ConstantsTest {
    enum Constants2 {
        Constants_1, Constants_2 //将常量放在枚举类型中
    }

    //使用接口定义的常量
    public static void doit(int c) {
        switch (c) {
            case Constants.Constants_A:
                System.out.println("doit() Constants_A");
                break;
            case Constants.Constants_B:
                System.out.println("doit() Constants_B");
                break;
            default:
                System.out.println("others");
        }
    }

    //使用枚举类型定义的常量
    public static void doit2(Constants2 c) {
        switch (c) {
            case Constants_1:
                System.out.println("doit2() Constants_1");
                break;
            case Constants_2:
                System.out.println("doit2() Constants_2");
                break;
        }
    }

    public static void main(String[] args) {
        ConstantsTest.doit(Constants.Constants_A);  //使用接口中定义的常量
        ConstantsTest.doit(3);

        ConstantsTest.doit2(Constants2.Constants_1);  //使用枚举类型中的常量
        ConstantsTest.doit2(Constants2.Constants_2);
//        ConstantsTest.doit2(3);  //会报错,因为doit2()的入口参数为Constants2枚举类型

    }
}
//枚举类型中的常用方法
package ex17_enum;

public class ShowEnum {
    enum Constants2 {
        CONSTANTS_1, CONSTANTS_2, CONSTANTS_3  //将常量放在枚举类型中
    }

    public static void main(String[] args) {
//        Constants2[] x = Constants2.values();

        //.values() 打印出枚举成员变量
        //.ordinal() 获取枚举类型成员的索引位置
        for (int i = 0; i < Constants2.values().length; i++) {
            System.out.println("枚举类型成员变量:"
                    + Constants2.values()[i] +
                    "位置索引:" + Constants2.values()[i].ordinal());
        }

        //.compareTo() 比较定义顺序
        //.valueOf() 将普通字符串转化为枚举类型,必须已经定义
        for (int i = 0; i < Constants2.values().length; i++) {
            int result = Constants2.valueOf("CONSTANTS_2").compareTo(Constants2.values()[i]);
            System.out.println("Constants2.CONSTANTS_2与" + Constants2.values()[i] + "比较" + result);
        }
    }
}
//枚举类型中的构造方法
package ex17_enum;

public class EnumIndexTest {
    enum Constants2 {  //将常量放在枚举类型中
        CONSTANTS_1("我是枚举成员1"),  //定义带参数的枚举常量
        CONSTANTS_2("我是枚举成员2"),
        CONSTANTS_3("我是枚举成员3"),
        CONSTANTS_4(4);
        private String description;
        private int i = 1;

        private Constants2() {
        }  //无参数构造方法  private防止用户实例化一个枚举对象

        private Constants2(String description) {  //参数为String的构造方法
            this.description = description;
        }

        private Constants2(int i) {  //参数为int的构造方法
            this.i = i;
        }

        public String getDescription() {  //获取description的值
            return description;
        }

        public int getI() {  //获取i的值
            return i;
        }

    }

    public static void main(String[] args) {
        Constants2[] cs = Constants2.values();  //获取枚举变量数组
        for (int i = 0; i < cs.length; i++) {
            Constants2 c = cs[i];  //枚举变量
            System.out.println(c + "调用getDescription()方法:" + c.description
                    + " 调用getI()方法:" + c.getI());
        }
    }
}
//在枚举对象中实现接口中的方法
package ex17_enum;

interface d {
    String getDescription();  //默认public

    int getI();
}

public enum AnyEnum implements d {
    CONSTANTS_1 {
        public String getDescription() {
            return "我是枚举类型1";
        }

        public int getI() {
            return i;  //i必须是static,否则使用this.i调用对象的i
        }
    },
    CONSTANTS_2 {
        public String getDescription() {
            return "我是枚举类型2";
        }

        public int getI() {
            return i;  //i必须是static,否则使用this.i调用对象的i
        }
    };

    private static int i;

    public static void main(String[] args) {
        AnyEnum[] anyEnums = AnyEnum.values();  //返回枚举类型数组
        for (int i = 0; i < anyEnums.length; i++) {  //每一个枚举对象调用方法
            AnyEnum anyEnum = anyEnums[i];
            System.out.println(anyEnum + "调用getDescription()方法:" + anyEnum.getDescription()
                    + " 调用getI()方法:" + anyEnum.getI());
        }
    }
}

泛型

向上转型是安全的,但是向下转型时用错了类型或者并没有执行该操作,可以被编译器接受,但是执行时会出现ClassCastException异常。这样看来,在向下转型时通常会出现问题,使用泛型机制有效的解决这一问题,在编译时就会进行类型检查

  • 定义泛型类
  • 泛型的常规用法
    • 定义泛型类时声明多个类型 MultiOverClass; MultiOverClass x = new MultiOverClass<>();
    • 定义泛型类时声明数组类型 private T[] array;
    • 集合类声明容器的元素
      • Map: HashMap, TreeMap
      • Set: HashSet, TreeSet
      • List: ArrayList, TreeList
  • 泛型的高级用法
    • 限制泛型可用类型 没有使用限制时,默认Object类下的所有子类都可以实例化泛型对象
      • class 类名称 anyClass是任何接口或类
      • 泛型类的类型必须实现或继承了anyClass这个接口或类,使用关键字extends
    • 使用通配符
      • 主要作用是在创建一个泛型类对象时限制这个泛型类对象的类型实现继承某个接口或类的子类
      • 泛型类名称 a = null; 泛型类对象a只能被赋值对象为实现List的子类或接口
      • List list 定义的泛型类对象只能获取或删除元素,不能添加新信息(因为是?编译器不知道添加什么信息)
    • 泛型的向上限制
      • 使用super关键字
      • A a = null; 表示对象a只接受List接口或上层父类类型
    • 定义为泛型的类和接口也可以被继承和实现
      • 如果没有在继承时指明泛型的继承,在子类中都会默认为Object类型

总结:

  • 泛型的类型参数只能是类类型,不可以是简单类型
  • 泛型的类型参数可以是多个
  • 可以使用extends super关键字限制泛型的类型
  • 可以使用通配符限制泛型的类型

Java从入门到精通 第17章 枚举类型与泛型_第2张图片

//泛型的定义
package ex17_enum;

public class OverClass {  //定义泛型类
    private T over;    //定义泛型类成员变量

    public T getOver() {  //设置getXXX()方法
        return over;
    }

    public void setOver(T over) {  //设置setXXX()方法
        this.over = over;
    }


    public static void main(String[] args) {
        //实例化一个Boolean类型的对象
        OverClass over1 = new OverClass();
        over1.setOver(true);          //不需要向上转型
        Boolean b = over1.getOver();  //不需要向下转型
        System.out.println(b);

        //实例化一个Float类型的对象
        OverClass over2 = new OverClass();  //Float可以不写
        over2.setOver(12.3F);       //不需要向上转型
        Float f = over2.getOver();  //不需要向下转型
        System.out.println(f);
    }
}
//定义泛型时,声明多个类型,声明数组
package ex17_enum;

public class MultiOverClass {
    private T1 multiOver;
    private T2[] multiOver2;  //声明数组类型
//    private T2[] multiOver2 = newT[10];  //不能使用泛型建立数组实例,因为不能确定类型,无法分配内存

    public void setMultiOver(T1 multiOver, T2[] multiOver2) {
        this.multiOver = multiOver;
        this.multiOver2 = multiOver2;
    }

    public T1 getMultiOver() {
        return multiOver;
    }

    public T2[] getMultiOver2() {
        return multiOver2;
    }


    public static void main(String[] args) {
        //自动检测类型,不需要向上转型
        MultiOverClass multiOverClass = new MultiOverClass<>();
        multiOverClass.setMultiOver(true, new String[]{"成员1", "成员2"});

        //使用getXXX()方法,不需要向下转型
        Boolean b = multiOverClass.getMultiOver();
        String[] str = multiOverClass.getMultiOver2();

        //输出实例multiOverClass
        System.out.println("getMultiOver: " + b);
        for (String s : str) {
            System.out.println("getMultiOver2: " + s);
        }

    }

}
//集合类声明元素类型
package ex17_enum;

import java.util.*;

public class AnyClass {
    public static void main(String[] args) {
        //Map集合(又称为容器):
        //HashMap 添加和删除映射关系效率高 不保证顺序 允许为null
        //TreeMap 其中的映射关系存在一定顺序 效率比HashMap稍差 键不允许为null
        Map map = new HashMap<>();
        Map map1 = new TreeMap<>();
        //为容器填充键和键值
        map.put(33333, "A");
        map1.put(33333, "A");
        map.put(11111, "A");
        map1.put(11111, "A");
        map.put(22222, "B");
        map1.put(22222, "B");
        //获取键和键值--使用迭代器 map不保证顺序 map1排序
        Set keySet = map.keySet();  //利用Set构建Map集合中的key集合
        Collection valueColl = map.values();  //利用Collection构建Map中的values集合 值有可能相同
//        Set keySet = map1.keySet();  //利用Set构建Map集合中的key集合
//        Collection valueColl = map1.values();  //利用Collection构建Map中的values集合 值有可能相同
        Iterator keyIterator = keySet.iterator();
        Iterator valueIterator = valueColl.iterator();
        while (keyIterator.hasNext()) {
            System.out.println("key: " + keyIterator.next()
                    + " value: " + valueIterator.next());
        }


        //Set
        //HashSet 不保证顺序
        //TreeSet 有一定顺序 也可以按照指定比较器递增排序
        Set set = new HashSet<>();
        Set set1 = new TreeSet<>();
        set.add("33333");
        set1.add("33333");
        set.add("11111");
        set1.add("11111");
        set.add("22222");
        set1.add("22222");
        Iterator setIterator = set.iterator();
        Iterator setIterator1 = set1.iterator();
        System.out.println("--------HashSet不保证顺序---------");
        while (setIterator.hasNext()) {
            System.out.println(setIterator.next());
        }
        System.out.println("--------TreeSet增序---------");
        while (setIterator1.hasNext()) {
            System.out.println(setIterator1.next());
        }


        //List
        //ArrayList 可以根据索引位置快速访问 缺点是插入删除速度慢
        //LinkedList 随机访问比ArrayList效率低 优点是插入删除效率比ArrayList高
        List stringList = new ArrayList<>();
        List stringList1 = new LinkedList<>();

    }
}
//泛型的高级用法,限制类型,通配符
package ex17_enum;


import java.util.ArrayList;
import java.util.List;

public class debug {
    public static void main(String[] args) {
        List stringList = new ArrayList<>();
        stringList.add("成员1");
        stringList.add("成员2");
        List stringList1 = stringList;  //没有使用通配符 引用赋值 可添加新信息
        System.out.println("-------删除之前的stringList-------------");
        for (String str : stringList) {
            System.out.println(str);
        }
        stringList1.remove(0);
        System.out.println("-------删除之后的stringList-------------");
        for (String str : stringList) {
            System.out.println(str);
        }
        stringList1.add("成员3(stringList1添加的)");
        System.out.println("-------添加成员-------------");
        for (String str : stringList) {
            System.out.println(str);
        }

        System.out.println("----------------------------");
        List stringList2 = stringList;  //使用List 引用赋值 不能添加新信息 只能获取或删除
        System.out.println("获取信息:" + stringList2.get(1));
        System.out.println("删除信息:" + stringList2.remove(1));
//        stringList2.add("不可添加成员");
//        stringList2.set(0,"不可添加成员");  //不能添加新信息
        for (String str : stringList) {
            System.out.println(str);
        }
    }
}

 

 

 

 

 

 

 

你可能感兴趣的:(Java)