11.1枚举

枚举是一个被命名的整型常数的集合,用于声明一组带标识符的常数。枚举在曰常生活中很常见,例如一个人的性别只能是“男”或者“女”,一周的星期只能是 7 天中的一个等。类似这种当一个变量有几种固定可能的取值时,就可以将它定义为枚举类型。

enum WeekDay {
    Mon("Monday"),Tue("Tuesday"),Wed("Wednesday"),Thu("Thursday"),Fri("Friday"),Sat("Saturday"),Sun("Sunday");
    // 以上是枚举的成员,必须先定义,而且使用分号结束
    private final String day;
    private WeekDay(String day) {
        this.day = day;
    }
    public static void printDay(int i) {
        switch(i) {
            case 1:
                System.out.println(WeekDay.Mon);
                break;
            case 2:
                System.out.println(WeekDay.Tue);
                break;
            case 3:
                System.out.println(WeekDay.Wed);
                break;
            case 4:
                System.out.println(WeekDay.Thu);
                break;
            case 5:
                System.out.println(WeekDay.Fri);
                break;
            case 6:
                System.out.println(WeekDay.Sat);
                break;
            case 7:
                System.out.println(WeekDay.Sun);
                break;
            default:
                System.out.println("wrong number!");
        }
    }
    public String getDay() {
        return day;
    }
}

public static void main(String[] args) {
    for(WeekDay day : WeekDay.values()) {
        System.out.println(day+"====>" + day.getDay());
    }
    WeekDay.printDay(5);
}

11.1.1使用枚举类型设置常量

enum-modifiers enum enumname:enum-base {
    enum-body,
}

enum-modifiers 表示枚举的修饰符主要包括 public、private 和 internal;enumname 表示声明的枚举名称;enum-base 表示基础类型;enum-body 表示枚举的成员,它是枚举类型的命名常数。

11.1.2深入了解枚举类型

Java 中的每一个枚举都继承自 java.lang.Enum 类。当定义一个枚举类型时,每一个枚举类型成员都可以看作是 Enum 类的实例,这些枚举成员默认都被 final、public, static 修饰,当使用枚举类型成员时,直接使用枚举名称调用成员即可。

enum Signal {
    // 定义一个枚举类型
    GREEN,YELLOW,RED
}
public class TrafficLight {
    Signal color = Signal.RED;
    public void change() {
        switch(color) {
            case RED:
                color = Signal.GREEN;
                break;
            case YELLOW:
                color = Signal.RED;
                break;
            case GREEN:
                color = Signal.YELLOW;
                break;
        }
    }
}

public class TestEnum {
    public enum Sex {
        // 定义一个枚举
        male,female;
    }
    public static void main(String[] args) {
        compare(Sex.valueOf("male"));    // 比较
    }
    public static void compare(Sex s) {
        for(int i = 0;i < Sex.values().length;i++) {
            System.out.println(s + "与" + Sex.values()[i] + "的比较结果是:" + s.compareTo(Sex.values()[i]));
        }
    }
}

public class TestEnum1 {
    enum Signal {
        // 定义一个枚举类型
        GREEN,YELLOW,RED;
    }
    public static void main(String[] args) {
        for(int i = 0;i < Signal.values().length;i++) {
            System.out.println("索引" + Signal.values()[i].ordinal()+",值:" + Signal.values()[i]);
        }
    }
}

11.1.3使用枚举类型的优势

enum Signal {
    // 定义一个枚举类型
    GREEN,YELLOW,RED;
}
public static void main(String[] args) {
    for(int i = 0;i < Signal.values().length;i++) {
        System.out.println("枚举成员:"+Signal.values()[i]);
    }
}

EnumMap 与 EnumSet为了更好地支持枚举类型,java.util 中添加了两个新类:EnumMap 和 EnumSet。使用它们可以更高效地操作枚举类型。

EnumMap 类

EnumMap 是专门为枚举类型量身定做的 Map 实现。虽然使用其他的 Map(如 HashMap)实现也能完成枚举类型实例到值的映射,但是使用 EnumMap 会更加高效。

HashMap 只能接收同一枚举类型的实例作为键值,并且由于枚举类型实例的数量相对固定并且有限,所以 EnumMap 使用数组来存放与枚举类型对应的值,使得 EnumMap 的效率非常高。

numSet 类

for(Operation op:EnumSet.range(Operation.PLUS,Operation.MULTIPLY)) {
    doSomeThing(op);
}

EnumSet 是枚举类型的高性能 Set 实现,它要求放入它的枚举常量必须属于同一枚举类型。

11.2泛型

Java 集合之所以被设计成这样,是因为集合的设计者不知道我们会用集合来保存什么类型的对象,所以他们把集合设计成能保存任何类型的对象,只要求具有很好的通用性,但这样做带来如下两个问题:

集合对元素类型没有任何限制,这样可能引发一些问题。例如,想创建一个只能保存 Dog 对象的集合,但程序也可以轻易地将 Cat 对象“丢”进去,所以可能引发异常。
由于把对象“丢进”集合时,集合丢失了对象的状态信息,集合只知道它盛装的是 Object,因此取出集合元素后通常还需要进行强制类型转换。这种强制类型转换既增加了编程的复杂度,也可能引发 ClassCastException 异常。
泛型本质上是提供类型的“类型参数”,也就是参数化类型。我们可以为类、接口或方法指定一个类型参数,通过这个参数限制操作的数据类型,从而保证类型转换的绝对安全。

11.2.1回顾”向上转型“与”向下转型“

如书中

11.2.2定义泛型类

public class class_name<data_type1,data_type2,…>{}

11.2.3泛型的常规用法

public class Test14 {
    public static void main(String[] args) {
        // 创建3个Book对象
        Book book1 = new Book(1, "唐诗三百首", 8);
        Book book2 = new Book(2, "小星星", 12);
        Book book3 = new Book(3, "成语大全", 22);
        Map<Integer, Book> books = new HashMap<Integer, Book>(); // 定义泛型 Map 集合
        books.put(1001, book1); // 将第一个 Book 对象存储到 Map 中
        books.put(1002, book2); // 将第二个 Book 对象存储到 Map 中
        books.put(1003, book3); // 将第三个 Book 对象存储到 Map 中
        System.out.println("泛型Map存储的图书信息如下:");
        for (Integer id : books.keySet()) {
            // 遍历键
            System.out.print(id + "——");
            System.out.println(books.get(id)); // 不需要类型转换
        }
        List<Book> bookList = new ArrayList<Book>(); // 定义泛型的 List 集合
        bookList.add(book1);
        bookList.add(book2);
        bookList.add(book3);
        System.out.println("泛型List存储的图书信息如下:");
        for (int i = 0; i < bookList.size(); i++) {
            System.out.println(bookList.get(i)); // 这里不需要类型转换
        }
    }
}

到目前为止,我们所使用的泛型都是应用于整个类上。泛型同样可以在类中包含参数化的方法,而方法所在的类可以是泛型类,也可以不是泛型类。也就是说,是否拥有泛型方法,与其所在的类是不是泛型没有关系。

[访问权限修饰符] [static] [final] <类型参数列表> 返回值类型 方法名([形式参数列表]

public static <T> List find(Class<T> cs,int userId){}

一般来说编写 Java 泛型方法,其返回值类型至少有一个参数类型应该是泛型,而且类型应该是一致的,如果只有返回值类型或参数类型之一使用了泛型,那么这个泛型方法的使用就被限制了。

public class Test16 {
    public static <T> void List(T book) { // 定义泛型方法
        if (book != null) {

public static void main(String[] args) {
        Book stu = new Book(1, "细学 Java 编程", 28);
        List(stu); // 调用泛型方法
    }
}

11.2.4泛型的高级用法

泛型的用法非常灵活,除在集合、类和方法中使用外,本节将从三个方面介绍泛型的高级用法,包括限制泛型可用类型、使用类型通配符、继承泛型类和实现泛型接口。

1. 限制泛型可用类型

在 Java 中默认可以使用任何类型来实例化一个泛型类对象。

class 类名称<T extends anyClass>
其中,anyClass 指某个接口或类。使用泛型限制后,泛型类的类型必须实现或继承 anyClass 这个接口或类。无论 anyClass 是接口还是类,在进行泛型限制时都必须使用 extends 关键字。

// 限制ListClass的泛型类型必须实现List接口
public class ListClass<T extends List> {
    public static void main(String[] args) {
        // 实例化使用ArrayList的泛型类ListClass,正确
        ListClass<ArrayList> lc1 = new ListClass<ArrayList>();
        // 实例化使用LinkedList的泛型类LlstClass,正确
        ListClass<LinkedList> lc2 = new ListClass<LinkedList>();
        // 实例化使用HashMap的泛型类ListClass,错误,因为HasMap没有实现List接口
        // ListClass<HashMap> lc3=new ListClass<HashMap>();
    }

2. 使用类型通配符

Java 中的泛型还支持使用类型通配符,它的作用是在创建一个泛型类对象时限制这个泛型类的类型必须实现或继承某个接口或类

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

泛型类名称<? extends List>a = null;

“<? extends List>”作为一个整体表示类型未知,当需要使用泛型对象时,可以单独实例化。

A<? extends List>a = null;
a = new A<ArrayList> ();    // 正确
b = new A<LinkedList> ();    // 正确
c = new A<HashMap> ();    // 错误

3. 继承泛型类和实现泛型接口

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

public class FatherClass<T1>{}
public class SonClass<T1,T2,T3> extents FatherClass<T1>{}
如果要在 SonClass 类继承 FatherClass 类时保留父类的泛型类型,需要在继承时指定,否则直接使用 extends FatherClass 语句进行继承操作,此时 T1、T2 和 T3 都会自动变为 Object,所以一般情况下都将父类的泛型类型保留。

interface interface1<T1>{}
interface SubClass<T1,T2,T3> implements
Interface1<T2>{}

11.2.5泛型总结

泛型方法使得该方法能够独立于类而产生变化。如果使用泛型方法可以取代类泛型化,那么就应该只使用泛型方法。另外,对一个 static 的方法而言,无法访问泛型类的类型参数。因此,如果 static 方法需要使用泛型能力,就必须使其成为泛型方法。

JAVA第11章枚举与泛型总结相关推荐

  1. Thinking in java 第11章 持有对象 笔记+习题

    Thinking in java 第11章 持有对象 学习目录 11.1 泛型和类型安全的容器 1. 当你制定了某个类型作为泛型参数时,你并不仅限于只能将该确切类型的对象放置到容器中.向上转型也可一样 ...

  2. Java 第11章 常用类库

    Java 第11章 常用类库 ​ Java是一种面向对象语言,Java中的类把方法与数据连接在一起,构成了自包含式的处理单元.为了提升Java程序的开发效率,Java的类包中提供了很多常用类以方便开发 ...

  3. 第11-15章枚举|异常|常用类|集合|泛型

    文章目录 第11章 枚举和注解 11.1举例 11.2枚举的二种实现方式 11.3enum 实现接口 11.4注解的理解 11.4基本的 Annotation 介绍 第12章 异常-Exception ...

  4. Java 第十一章总结 枚举与泛型

    11.1 枚举 (1) 使用枚举类型设置常量 在项目中创建Constants接口,在接口中定义常量的常规方式. public interface Constants{ public static fi ...

  5. JavaSE_第11章 泛型

    第11章 泛型 学习目标 能够使用泛型定义类.接口.方法 能够理解泛型上限 能够阐述泛型通配符的作用 能够识别通配符的上下限 第十一章 泛型 11.1 泛型的概念 11.1.1 泛型的引入 例如:生产 ...

  6. JAVA常用基础知识点[继承,抽象,接口,静态,枚举,反射,泛型,多线程...]

    类的继承 Java只支持单继承,不允许多重继承 - 一个子类只能有一个父类 - 一个父类可以派生出多个子类 这里写图片描述 子类继承了父类,就继承了父类的方法和属性. 在子类中,可以使用父类中定义的方 ...

  7. ios 获取一个枚举的所有值_凯哥带你从零学大数据系列之Java篇---第十一章:枚举...

    温馨提示:如果想学扎实,一定要从头开始看凯哥的一系列文章(凯哥带你从零学大数据系列),千万不要从中间的某个部分开始看,知识前后是有很大关联,否则学习效果会打折扣. 系列文章第一篇是拥抱大数据:凯哥带你 ...

  8. JAVA常用基础知识点[继承,抽象,接口,静态,枚举,反射,泛型,多线程.]

    类的继承 Java只支持单继承,不允许多重继承  - 一个子类只能有一个父类  - 一个父类可以派生出多个子类    子类继承了父类,就继承了父类的方法和属性.  在子类中,可以使用父类中定义的方法和 ...

  9. 《Java编程思想》阅读笔记之第11章-持有对象

    第11章-持有对象 容器类的引入:Java需要有不同的方式来保存对象(或说是对象的引用). 如数组可以保存一组对象或一组基本类型数据,也推荐使用,但是数组必需有固定的尺寸,但在实际的情况中,可能根本不 ...

  10. Spring - Java/J2EE Application Framework 应用框架 第 11 章 使用ORM工具进行数据访问

    第 11 章 使用ORM工具进行数据访问 11.1. 简介 Spring在资源管理,DAO实现支持以及实物策略等方面提供了与Hibernate, JDO和iBATIS SQL映射的集成. 对Hiber ...

最新文章

  1. 【HTML】处理<br>换行符追加到前端换行无效的问题 --- html中渲染的字符串中包含HTML标签无效的处理方法,字符串中包含HTML标签被转义的问题 解决
  2. java 俄语 工作_工作俄语怎么说
  3. 模拟计算机 电磁,校园机房电磁模拟环境及计算机模拟.ppt
  4. 极致的线上产品设计与终极数据分析工具,两者缺一不可(下)
  5. iOS之应用偏好设置
  6. 基于JAVA+SpringMVC+Mybatis+MYSQL的养老社区管理系统
  7. Java8时间转换(LocalDateTime)代码实例
  8. 哈弗h2s车内时间怎么调_你想拥抱的品质生活,就让哈弗H4乐享版帮你实现吧
  9. msi b460m pro wifi黑苹果 efi
  10. .gpx文件转geojson
  11. 记录一次阿里云Mysql 数据库恢复 qp.xb文件恢复数据
  12. 如何解决百度识图中图片被限制百度防盗链破解方法
  13. Joint Discriminative and Generative Learning for Person Re-identification论文翻译
  14. 如何在Tomcat后台通过文件上传getshell总结(个人学习笔记思路)
  15. mps是什么意思 计算机网络,网络连接的半双工和全双工是啥意思 100MPS和10MPS又有啥区别...
  16. 论文页眉设置 奇偶页页眉均为章序及章标题 论文按章节设置页眉
  17. 备份iphoneXR手机照片
  18. C语言后缀.h文件和.c文件作用和区别
  19. 【VB与数据库】机房收费系统开发阶段之登陆
  20. 【转】30岁程序员的转型思考

热门文章

  1. 五大理由!建议你选择中国电信 CTWing 物联网平台?
  2. C# 操作word之在表格中插入新行、删除指定行
  3. android webview 设置下载文件,Android WebView使用之文件下载
  4. 关于推广个人博客的经验_博客推广
  5. CI24R1低成本国产2.4G无线收发器芯片替代XN297精简版SI24R1
  6. python画图的函数_python画图函数
  7. 怎样批量更改文件夹里的文件名称?
  8. 服务端(java)实现微信支付二次签名
  9. django+echarts数据可视化(NBA球队数据可视化02)!
  10. 异常检测的总结性介绍