枚举和泛型


一、枚举

  • 枚举是 JDK 1.5 后出现的,枚举是一种数据类型,,是一系列具有名称的常量的集合;如数学中的集合:A={1,2,3},当使用这个集合时,只能使用集合中的1、2、3这3个元素,不是这 3 个元素的值就无法使用。

1、使用枚举类型设置常量

//将常量放置在接口中
interface Constants {public static final int Constants_A = 1;public static final int Constants_B = 12;
}public class ContantsTest {//将常量放置在枚举类型中enum Constants2 {Constants_A, Constants_B}//使用接口定义常量//定义一个方法,参数为 int 型,根据常量的值得不同做不同操作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;}}//定义一个参数对象是枚举类型的方法,根据枚举类型对象的不同做不同操作public static void doit2(Constants2 c){switch(c){case Constants_A:System.out.println("doit2() Constants_A");break;case Constants_B:System.out.println("doit2() Constants_B");break;}}public static void main(String[] args) {ContantsTest.doit(Constants.Constants_A);  //使用接口中定义的常量ContantsTest.doit2(Constants2.Constants_A);  //使用枚举类型中的常量ContantsTest.doit2(Constants2.Constants_B);  //使用枚举类型中的常量ContantsTest.doit(3);}
}
//输出:
doit() Constants_A
doit2() Constants_A
doit2() Constants_B

2、深入了解枚举类型

2.1、枚举类型成员的方法

  • 枚举类型对象继承于 java.lang.Enum 类,所以该类的一些操作枚举类型的方法都可以应用到枚举类型中。

  • 常用枚举类型方法如下表:

    方法名称 具体含义 使用方法
    values() 该方法将枚举成员以数组的形式返回 枚举类型名称.values()
    valueOf() 该方法可以实现将普通字符串转为枚举实例 枚举类型名称.valueOf(“abc”)
    compareTo() 该方法用于比较两个枚举对象在定义时的顺序 枚举对象.compareTo()
    ordinal() 该方法用于得到枚举成员的位置索引 枚举对象.ordinal()
  • 实例:

    //(1)values:
    public class ShowEnum {enum Constants{Constants_A,Constants_B,Constants_C,Constants_D}public static void main(String[] args){Constants enumArray[] = Constants.values();  //values() 方法返回枚举数组for(int i=0;i<enumArray.length;i++){//将枚举成员打印System.out.println("枚举类型成员变量:"+enumArray[i]);}}
    }
    //输出:
    /*
    枚举类型成员变量:Constants_A
    枚举类型成员变量:Constants_B
    枚举类型成员变量:Constants_C
    枚举类型成员变量:Constants_D
    */
    //valueOf() 和 compareTo()
    public class ShowEnum {enum Constants {Constants_A, Constants_B, Constants_C, Constants_D}public static void compare(Constants c) {Constants arrays[] = Constants.values();for (int i = 0; i < arrays.length; i++) {System.out.println(c + "与" + arrays[i] + "的比较结果为:" + c.compareTo(arrays[i]));}}public static void main(String[] args) {compare(Constants.valueOf("Constants_B"));}
    }
    //输出结果
    /*
    Constants_B与Constants_A的比较结果为:1
    Constants_B与Constants_B的比较结果为:0
    Constants_B与Constants_C的比较结果为:-1
    Constants_B与Constants_D的比较结果为:-2
    */
    //(3)ordinal()
    public class ShowEnum {enum Constants {Constants_A, Constants_B, Constants_C, Constants_D}public static void main(String[] args) {for(int i=0;i<Constants.values().length;i++){System.out.println(Constants.values()[i]+"在枚举类型中的位置索引值"+Constants.values()[i].ordinal());}}
    }
    //输出:
    /*
    Constants_A在枚举类型中的位置索引值0
    Constants_B在枚举类型中的位置索引值1
    Constants_C在枚举类型中的位置索引值2
    Constants_D在枚举类型中的位置索引值3
    */
    

2.2、枚举类型中的构造方法

  • 在枚举类型中可以添加构造方法,但规定这个构造方法必须修饰为 private 或其他默认修饰符。

  • 实例:

    public class EnumConTest {enum Constants {Constants_A("我是枚举成员A"),Constants_B("我是枚举成员B"),Constants_C("我是枚举成员C"),Constants_D(3);private String description;private int i = 4;//定义String类型构造方法private Constants(String description) {this.description = description;}//定义int型构造方法private Constants(int i) {this.i = this.i + i;}//获取descriptionpublic String getDescription() {return description;}//获取i值public int getI(){return i;}}public static void main(String[] args) {Constants array[] = Constants.values();  //获取枚举成员数组for(int i=0;i<array.length;i++){System.out.println(array[i]+"调用getDescription()方法为:"+array[i].getDescription());}Constants c2 = Constants.valueOf("Constants_D");System.out.println(c2+"调用getI()方法为:"+c2.getI());}
    }
    //输出:
    Constants_A调用getDescription()方法为:我是枚举成员A
    Constants_B调用getDescription()方法为:我是枚举成员B
    Constants_C调用getDescription()方法为:我是枚举成员C
    Constants_D调用getDescription()方法为:null
    Constants_D调用getI()方法为:7
    
  • 实例

    interface EnumInterface {public String getDescription();public int getI();
    }public enum AnyEnum implements EnumInterface {Constants_A {public String getDescription() {return ("我是枚举成员A");}public int getI() {return i;}},Constants_B{public String getDescription() {return ("我是枚举成员B");}public int getI() {return i;}},Constants_C{public String getDescription() {return ("我是枚举成员C");}public int getI() {return i;}},Constants_D{public String getDescription() {return ("我是枚举成员D");}public int getI() {return i;}};private static int i = 5;public static void main(String[] args) {AnyEnum array[] = AnyEnum.values();for(int i=0;i<array.length;i++){System.out.println(array[i]+"调用getDescription()方法为:"+array[i].getDescription());System.out.println(array[i]+"调用getI()方法为:"+array[i].getI());}}}
    //输出:
    /*
    Constants_A调用getDescription()方法为:我是枚举成员A
    Constants_A调用getI()方法为:5
    Constants_B调用getDescription()方法为:我是枚举成员B
    Constants_B调用getI()方法为:5
    Constants_C调用getDescription()方法为:我是枚举成员C
    Constants_C调用getI()方法为:5
    Constants_D调用getDescription()方法为:我是枚举成员D
    Constants_D调用getI()方法为:5
    */
    

3、使用枚举类型的优势

  • 枚举类型声明提供了一个用户友好的变量定义方式,枚举了某种数据类型所有可能出现的值。

  • 枚举类型有以下特点:

    1)类型安全

    2)紧凑有效的数据定义

    3)可以和程序的其他部分完美交互。

    4)运行效率高

二、泛型

  • JDK1.5版本以上的java提出了泛型机制,类似于 C++的模板类。

1、定义泛型类

  • 定义泛型类的语法如下:

    类名<T>
    //T 代表一个类型的名称
    //例子:
    public class OverClass<T> {private T over;  //定义泛型成员变量public T getOver() {return over;}public void setOver(T over) {this.over = over;}public static void main(String[] args) {OverClass<Boolean> over1 = new OverClass<Boolean>();  //实例化Boolean型对象OverClass<Float> over2 = new OverClass<Float>();  //实例化Float型对象over1.setOver(true);  //不需要进行向上转型over2.setOver(12.45f);Boolean b = over1.getOver();  //不需要进行向下转型Float f = over2.getOver();System.out.println("Boolean over1:"+b);System.out.println("Float over2:"+f);}
    }
    //输出
    /*
    Boolean over1:true
    Float over2:12.45
    */
    

2、泛型的常规用法

2.1、定义泛型类时声明多个类型

  • 定义泛型类时,可以声明多个类型,语法如下:

    MutiOverClass<T1,T2>
    MutiOverClass: 泛型类名称
    //例子:
    MutiOverClass<Boolean,Float> = new MutiOverClass<Boolean,Float>();
    

2.2、定义泛型类时声明数组类型

public class ArrayClass<T> {private T[] array;  //定义泛型类数组public T[] getArray() {   //获取成员数组return array;}public void setArray(T[] array) {this.array = array;}public static void main(String[] args) {ArrayClass<String> a = new ArrayClass<String>();String[] array = {"Hello", "World", "I", "am", "trying"};a.setArray(array);for(int i=0;i<a.getArray().length;i++){System.out.print(a.getArray()[i]+" ");}System.out.println();}
}
//输出:
/*
Hello World I am trying
*/

注意!不可以用泛型来建立数组实例,例如:private T[] array = new T[];这种写法是错误的!

  • JDK1.7以后的版本添加了自动推断实例化类型的泛型,例如:

    ArrayClass<String> a = new ArrayClass<>();
    等价于
    ArrayClass<String> a = new ArrayClass<String>();
    

2.3、集合类声明容器的元素

import java.util.HashMap;
import java.util.Map;public class MutiOverClass<K, V> {public Map<K, V> m = new HashMap<K, V>();public void put(K k, V v) {m.put(k, v);}public V get(K k) {return m.get(k);}public static void main(String[] args) {MutiOverClass<Integer, String> mu = new MutiOverClass<>();for (int i = 0; i < 5; i++) {char temp = (char) ('A'+i);mu.put(i, "我是集合成员" + temp);}for (int i = 0; i < mu.m.size(); i++) {System.out.println(mu.get(i));}}
}
//输出:
/*
我是集合成员A
我是集合成员B
我是集合成员C
我是集合成员D
我是集合成员E
*/
  • 常用的被泛型化的集合类,如下表:

    集合类 泛型定义
    ArrayList ArrayList
    HashMap HashMap<K,V>
    HashSet HashSet
    Vector Vector
  • 示例:

    import java.util.*;public class ListClass {public static void main(String[] args) {//定义List容器,设置容器内的值类型为 IntegerList<Integer> a = new ArrayList<Integer>();a.add(520);  //为容器添加新值for (int i = 0; i < a.size(); i++) {System.out.println("获取ArrayList容器内的值:" + a.get(i));}//定义Map容器,设置容器内的键名和键值为Integer和StringMap<Integer, String> m = new HashMap<>();for (int i = 0; i < 5; i++) {m.put(i, "成员" + i);  //为容器添加键值对}for (int i = 0; i < m.size(); i++) {System.out.println("获取Map容器的值:" + m.get(i));}//定义Set容器,设置值类型为CharcterSet<Character> set = new HashSet<>();set.add('一');set.add('二');//使用 foreach循环,将Set中的元素按照Character类型进行循环遍历for(Character c : set){System.out.println("获取Set容器的值:"+c);}}
    }
    //输出
    /*
    获取ArrayList容器内的值:520
    获取Map容器的值:成员0
    获取Map容器的值:成员1
    获取Map容器的值:成员2
    获取Map容器的值:成员3
    获取Map容器的值:成员4
    获取Set容器的值:一
    获取Set容器的值:二
    */
    

3、泛型的高级用法

  • 泛型的高级用法主要通过类型参数 T 的继承和类型通配符的继承来限制泛型类型。

3.1、通过类型参数 T 的继承限制泛型类型

  • 语法如下:

    class 类名称<T extends anyclass>
    // anyclass 是接口或者类
    //例子
    import java.util.*;public class LimitClass<T extends List> {public static void main(String[] args) {//可以实例化已经实现的 List 接口类LimitClass<ArrayList> l1 = new LimitClass<>();LimitClass<LinkedList> l2 = new LimitClass<>();//下面这句是错误的
    //        LimitClass<HashMap> l3 = new LimitClass<HashMap>();}
    }
    

3.2、通过类型通配符的继承限制泛型类型

  • 类型通配符,其作用是在创建一个泛型类对象时,限制这个泛型类的类型,或者限制这个泛型类型必须继承某个接口或某个类(或其子类);要声明这样一个对象可以通过通配符“?”。

  • 通过对类型参数T实现继承限制泛型类型时,在声明时就进行了限制,而通过对类型通配符实现继承限制泛型类型时,则在实例化时进行限制。

  • 使用泛型类型通配符的语法如下:

    泛型类型名称<? extends List> a=null;
    //例子
    A<? extends List> a = null;
    a = new A<ArrayList>();
    a = new A<LinkedList>();
    
  • 除了可以实例化一个限制泛型类型的实例之外,还可以将该实例放置在方法的参数中。

    public void dosomething(A<? extends List> a){}
    
  • 示例:

    import java.util.*;public class WildClass {public static void main(String[] args) {List<String> l1 = new ArrayList<>();  //创建一个ArrayList对象l1.add("成员");List<?> l2 = l1; //使用通配符List<?> l3 = new  LinkedList<Integer>();System.out.println("l1:"+l1.get(0));  // 获取l1集合的第一个值System.out.println("l2:"+l2.get(0));  //获取l2集合的第一个值l1.set(0,"成员改变");
    //        l2.add("添加");  //使用通配符的对象不能使用 add 方法
    //        l2.set(0,"成员改变");  //使用通配符的对象不能使用 set 方法
    //        l3.add(1);
    //        l3.set(0,1);System.out.println("l1:"+l1.get(0));}
    }
    //输出
    /*
    l1:成员
    l2:成员
    l1:成员改变
    */
    
  • 泛型类型限制除了可以向下限制,还可以向上限制,只要在定义时使用 super 关键字;例如:A<? super List> a = null;这样定以后,对象 a 只接受 List 接口或上层父类类型,如 a = new A();

3.3、继承泛型类与实现泛型接口

  • 定义为泛型的类和接口也可以被继承与实现。

    public class ExtendClass<T1>{}
    class SubClass<T1, T2, T3> extends ExtendClass<T1>{}interface TestInterface<T1>{}
    class SubClass2<T1,T2,T3> implements TestInterface<T1>{}
    

4、泛型总结

  • 使用泛型需要遵循以下原则:

    1)泛型的类型参数只能是类类型,不可以是简单类型,如 int

    2)泛型的类型个数可以是多个

    3)可以使用 extends 关键字限制泛型的类型

    4)可以使用通配符限制泛型的类型

Java 枚举和泛型相关推荐

  1. java 枚举与泛型_Java枚举和泛型

    这件事让我困扰了一段时间.以前我曾问过 questions,可能是一个不好的措辞和一个太抽象的例子.所以不清楚我实际在问什么.我会再尝试.请不要跳过结论.我期待这个问题根本不容易回答! 为什么我不能在 ...

  2. java 注解 enum_13 Java枚举和注解

    Java枚举 在某些情况下,一个类的对象是有限而且固定的.例如季节类,只能有 4 个对象. 当类的对象是有限时,就应该使用枚举,而不使用普通类.(枚举对象是单例模式) 枚举的属性 实现接口的枚举类 例 ...

  3. 学妹问我Java枚举类与注解,我直接用这个搞定她!

    很多人问我学妹长什么样,不多说 上图吧! 学妹问我Java枚举类与注解,我直接一篇文章搞定! 一.枚举类 ① 自定义枚举类 ② enum关键字定义枚举类 ③ enum 枚举类的方法 ④ enum 枚举 ...

  4. java 设置两个方法互斥_分享两个操作Java枚举的实用方法

    1. 前言 Java枚举在开发中是非常实用的.今天再来分析几个小技巧并且回答一些同学的的疑问.首先要说明的是我的枚举建立在以下的范式之中: 枚举统一接口范式 2. 如何把枚举值绑定的下拉列表 这种场景 ...

  5. [转载] java 枚举Enum源码解析

    参考链接: 使用Java枚举 应用场景 枚举是单例模式中的一种.面试官系统之设计模式(单例模式) 简单来讲就是只能实例化一次,线程安全且性能高.枚举通常用来列举一个类型的有限实例集合,我们可以使用常量 ...

  6. java 枚举_深入理解Java枚举

    所有知识体系文章,[GitHub](https://github.com/Ziphtracks/JavaLearningmanual)已收录,欢迎Star!再次感谢,愿你早日进入大厂! https:/ ...

  7. java 枚举类组合在一起_Java,.NET,但为什么在一起?

    java 枚举类组合在一起 十二年前,Sun微系统公司大张旗鼓地宣布了一种新的编程语言和环境,用于使网页更具动态性和"活力". 当然,现在,Java编程语言是一种无处不在的工具,它 ...

  8. 深度学习Java枚举(enum)——枚举虽小,五脏俱全

    文章目录 深入理解Java枚举 一.什么是枚举 1.1 什么是枚举? 1.2 Java中的枚举类 二.Java枚举的语法 三.Java枚举类的使用规则和应用场景 3.1 Java枚举类的使用规则 3. ...

  9. java 枚举 接口_java枚举接口

    java中的枚举类 枚举类(enum),与class和interface关键字地位相同. 枚举类是一个特殊的类,可以有自己的成员变量.方法.构造器,可以实现一个或多个接口.一个java源文件中只能有一 ...

  10. Java集合、泛型 面试题

    1.ArrayList和linkedList的区别 Array(数组)是基于索引(index)的数据结构,它使用索引在数组中搜索和读取数据是很快的. Array获取数据的时间复杂度是O(1),但是要删 ...

最新文章

  1. oracle分页的使用,oracle中分页的实现方式.rownum的使用
  2. 建立注册DLL和反注册DLL文件的快捷方式
  3. Java与C#平台通信 WCF CXF SOAP
  4. How to get user parameter settings
  5. 你发现了吗?数学还能这么美
  6. db2导入发生错误显示不是绝对路径_python编程常见错误总结
  7. 数学公式(待慢慢总结)
  8. ORACLE 索引失效的原因与解决
  9. qt 读取gif一帧_译:Unreal渲染一帧详解(Unreal Frame Breakdown)
  10. 【廖雪峰官方网站/Java教程】多线程(2)
  11. 信息安全技术—实验三—PGP邮件加密软件的使用
  12. html按钮功能的实现原理,触摸按键原理是什么 触摸按键原理介绍【图文详解】...
  13. python ipo模型是什么意思_IPO里的估值模型是什么情况?
  14. 交换机和路由器技术-28-OSPF的NSSA区域
  15. 关于验证码错误的解决办法
  16. 博德之门联机等待服务器响应,《博德之门》系列疑难解答
  17. ISACA最新白皮书助力企业了解中国《个人信息保护法》
  18. 计算机英文积累(一)
  19. Android kotlin工具类获取屏幕分辨率及宽高
  20. Flink系列之Flink流式计算引擎基础理论

热门文章

  1. 触摸精灵之keepScreen
  2. 关闭Tomcat报错The web application [ROOT] appears to have started a thread named [Abandoned connectio
  3. 电脑怎么设置定时关机?
  4. Deepin 系统没有 Times New Roman 等微软字体
  5. 【老生谈算法】matlab实现功率谱密度算法源码——功率谱密度
  6. ZOOMIT的使用方法
  7. 千人千面算法java实现_推荐算法-recommend_system
  8. mb是做1还是0_新手爸妈看过来:0-1岁宝宝这样做早教,省钱省心又实用
  9. Win7显示器颜色不正常的原因及解决方法
  10. 【jq练习】层次选择器