Java 枚举和泛型
枚举和泛型
一、枚举
- 枚举是 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 枚举和泛型相关推荐
- java 枚举与泛型_Java枚举和泛型
这件事让我困扰了一段时间.以前我曾问过 questions,可能是一个不好的措辞和一个太抽象的例子.所以不清楚我实际在问什么.我会再尝试.请不要跳过结论.我期待这个问题根本不容易回答! 为什么我不能在 ...
- java 注解 enum_13 Java枚举和注解
Java枚举 在某些情况下,一个类的对象是有限而且固定的.例如季节类,只能有 4 个对象. 当类的对象是有限时,就应该使用枚举,而不使用普通类.(枚举对象是单例模式) 枚举的属性 实现接口的枚举类 例 ...
- 学妹问我Java枚举类与注解,我直接用这个搞定她!
很多人问我学妹长什么样,不多说 上图吧! 学妹问我Java枚举类与注解,我直接一篇文章搞定! 一.枚举类 ① 自定义枚举类 ② enum关键字定义枚举类 ③ enum 枚举类的方法 ④ enum 枚举 ...
- java 设置两个方法互斥_分享两个操作Java枚举的实用方法
1. 前言 Java枚举在开发中是非常实用的.今天再来分析几个小技巧并且回答一些同学的的疑问.首先要说明的是我的枚举建立在以下的范式之中: 枚举统一接口范式 2. 如何把枚举值绑定的下拉列表 这种场景 ...
- [转载] java 枚举Enum源码解析
参考链接: 使用Java枚举 应用场景 枚举是单例模式中的一种.面试官系统之设计模式(单例模式) 简单来讲就是只能实例化一次,线程安全且性能高.枚举通常用来列举一个类型的有限实例集合,我们可以使用常量 ...
- java 枚举_深入理解Java枚举
所有知识体系文章,[GitHub](https://github.com/Ziphtracks/JavaLearningmanual)已收录,欢迎Star!再次感谢,愿你早日进入大厂! https:/ ...
- java 枚举类组合在一起_Java,.NET,但为什么在一起?
java 枚举类组合在一起 十二年前,Sun微系统公司大张旗鼓地宣布了一种新的编程语言和环境,用于使网页更具动态性和"活力". 当然,现在,Java编程语言是一种无处不在的工具,它 ...
- 深度学习Java枚举(enum)——枚举虽小,五脏俱全
文章目录 深入理解Java枚举 一.什么是枚举 1.1 什么是枚举? 1.2 Java中的枚举类 二.Java枚举的语法 三.Java枚举类的使用规则和应用场景 3.1 Java枚举类的使用规则 3. ...
- java 枚举 接口_java枚举接口
java中的枚举类 枚举类(enum),与class和interface关键字地位相同. 枚举类是一个特殊的类,可以有自己的成员变量.方法.构造器,可以实现一个或多个接口.一个java源文件中只能有一 ...
- Java集合、泛型 面试题
1.ArrayList和linkedList的区别 Array(数组)是基于索引(index)的数据结构,它使用索引在数组中搜索和读取数据是很快的. Array获取数据的时间复杂度是O(1),但是要删 ...
最新文章
- oracle分页的使用,oracle中分页的实现方式.rownum的使用
- 建立注册DLL和反注册DLL文件的快捷方式
- Java与C#平台通信 WCF CXF SOAP
- How to get user parameter settings
- 你发现了吗?数学还能这么美
- db2导入发生错误显示不是绝对路径_python编程常见错误总结
- 数学公式(待慢慢总结)
- ORACLE 索引失效的原因与解决
- qt 读取gif一帧_译:Unreal渲染一帧详解(Unreal Frame Breakdown)
- 【廖雪峰官方网站/Java教程】多线程(2)
- 信息安全技术—实验三—PGP邮件加密软件的使用
- html按钮功能的实现原理,触摸按键原理是什么 触摸按键原理介绍【图文详解】...
- python ipo模型是什么意思_IPO里的估值模型是什么情况?
- 交换机和路由器技术-28-OSPF的NSSA区域
- 关于验证码错误的解决办法
- 博德之门联机等待服务器响应,《博德之门》系列疑难解答
- ISACA最新白皮书助力企业了解中国《个人信息保护法》
- 计算机英文积累(一)
- Android kotlin工具类获取屏幕分辨率及宽高
- Flink系列之Flink流式计算引擎基础理论
热门文章
- 触摸精灵之keepScreen
- 关闭Tomcat报错The web application [ROOT] appears to have started a thread named [Abandoned connectio
- 电脑怎么设置定时关机?
- Deepin 系统没有 Times New Roman 等微软字体
- 【老生谈算法】matlab实现功率谱密度算法源码——功率谱密度
- ZOOMIT的使用方法
- 千人千面算法java实现_推荐算法-recommend_system
- mb是做1还是0_新手爸妈看过来:0-1岁宝宝这样做早教,省钱省心又实用
- Win7显示器颜色不正常的原因及解决方法
- 【jq练习】层次选择器