枚举的使用
枚举是在JDK1.5以后引入的。主要用途是:将一组常量组织起来,在这之前表示一组常量通常使用定义常量的方
式
public static final int RED = 1;
public static final int GREEN = 2;
public static final int BLACK = 3;
但是常量举例有不好的地方,例如:可能碰巧有个数字1,但是他有可能误会为是RED,现在我们可以直接用枚举
来进行组织,这样一来,就拥有了类型,枚举类型。而不是普通的整形1
public enum TestEnum {
RED,BLACK,GREEN;
}
使用场景
switch语句
public static void main(String[] args) {
TestEnum[] ne=TestEnum.values();
TestEnum pe=null;
for(int i=0;i<3;i++){
pe=ne[i/2];
switch (pe){
case RED:
System.out.println("Red");
break;
case BLACK:
System.out.println("BLACK");
break;
case GREEN:
System.out.println("GREEN");
break;
default:
System.out.println("ERROR");
}
}
在我们未来如果要写日志的话那么使用枚举类和switch语句进行配合是非常方便的
常用方法
方法 | 作用 |
---|---|
values() | 以数组的形式返回枚举类型的所有成员 |
ordia() | 获取枚举成员的索引位置 |
valueOf() | 将普通字符串转换为枚举实例 |
compareTo() | 比较两个枚举成员在定义时的顺序 |
那么用代码给大家来进行一下代码示例吧
public static void main(String[] args) {
TestEnum[] ne=TestEnum.values();
for(int i=0;i<ne.length;i++){
System.out.printf("%s ",ne[i]);
System.out.println(ne[i].ordinal());
}
}
从这个代码可以看出values这个方法可以使其以数组形式返回因为我们发现我们可以用数组的形式去遍历,其次我们也可以看出ordinal可以打印出该元素所代表的下标是多少
那么有些同学可能会疑惑几个地方,首先就是为什么枚举类型我们没有实现方法,但是却可以调用这些方法呢?答案只有一个那就是这些方法不是枚举实现的,那么是谁呢?是他的父类,也就是object类实现的。
然后有些同学可能还有一个疑惑那就是发现自己的枚举类型不能去new一个对象,这让人搞不懂为什么不能new呢?因为枚举中的构造函数默认是私有的,这时候有些同学可能就有歪点子了会想既然枚举的构造是私有的不能调用那我就用反射去搞,这样可不可以呢?答案是不行的java做的有特殊处理枚举是不能通过反射去调用构造函数的,因此我们未来用java实现一个单列模式其实用的就是枚举
那么我们知道了这些后也就是说枚举是不可继承的并且还无法扩展
lambda
Lambda表达式是Java SE 8中一个重要的新特性。lambda表达式允许你通过表达式来代替功能接口。 lambda表达式就和方法一样,它提供了一个正常的参数列表和一个使用这些参数的主体(body,可以是一个表达式或一个代码块)。 Lambda 表达式(Lambda expression),基于数学中的λ演算得名,也可称为闭包(Closure) 。
lambda的前置知识
什么是函数式接口
首先我们要明白什么是函数式接口呢?函数式接口意思就是这个接口中有且只有一个抽象方法 。
注意:
- 如果一个接口只有一个抽象方法,那么该接口就是一个函数式接口
- 如果我们在某个接口上声明了 @FunctionalInterface 注解,那么编译器就会按照函数式接口的定义来要求该接
口,这样如果有两个抽象方法,程序编译就会报错的。所以,从某种意义上来说,只要你保证你的接口中只
有一个抽象方法,你可以不加这个注解。加上就会自动进行检测的。
定义方式
@FunctionalInterface
interface NoParameterNoReturn {
//注意:只能有一个方法
void test();
}
但是下面这种方式也是可以的
interface NoParameterNoReturn {
void test();
default void test2() {
System.out.println("JDK1.8新特性,default默认方法可以有具体的实现");
}
}
lambda的基本语法
首先我们定义以下几个函数式接口
//无返回值无参数
@FunctionalInterface
interface NoParameterNoReturn {
void test();
}
//无返回值一个参数
@FunctionalInterface
interface OneParameterNoReturn {
void test(int a);
}
//无返回值多个参数
@FunctionalInterface
interface MoreParameterNoReturn {
void test(int a,int b);
}
//有返回值无参数
@FunctionalInterface
interface NoParameterReturn {
int test();
}
//有返回值一个参数
@FunctionalInterface
interface OneParameterReturn {
int test(int a);
}
//有返回值多参数
@FunctionalInterface
interface MoreParameterReturn {
int test(int a,int b);
}
首先我们先来看一下不适用lambda表达式这个函数式接口应该怎么实例化呢
public static void main(String[] args) {
NoParameterNoReturn ne1=new NoParameterNoReturn() {
@Override
public void test() {
System.out.println("NoParameterNoReturn");
}
};
ne1.test();
}
那么使用lambda之后呢?
public static void main(String[] args) {
NoParameterNoReturn ne1=()->{System.out.println("NoParameterNoReturn");};
ne1.test();
}
我们可以很清楚的看到使用了lambda之后我们的代码量减少了很多
那么我们来解析一下首先lambda表达式中的这个括号表示的其实就是你要写的这个方法中的参数没有参数就不写这个是无参无返回值的写法我们来写一下有参有返回值的写法
public static void main(String[] args) {
NoParameterNoReturn ne1=()->{System.out.println("NoParameterNoReturn");};
ne1.test();
OneParameterReturn ne2=(int a)->{return a;};
int b=ne2.test(10);
System.out.println(b);
}
这个是有一个参数有返回值的写法,其实写道这里我们应该会想起来一个东西那就是我们的优先级队列
public static void main(String[] args) {
PriorityQueue<Integer>ne=new PriorityQueue<>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1.compareTo(o2);
}
});
}
我们的优先级队列在传入比较器的时候是不是也特别像是可以写成一个lambda的形式呢?我们来试试
public static void main(String[] args) {
PriorityQueue<Integer>ne=new PriorityQueue<>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1.compareTo(o2);
}
});
//lambda写法
PriorityQueue<Integer>ne2=new PriorityQueue<>((o1,o2)->{return o1.compareTo(o2);});
}
那么很明显确实如此。由此我们可以知道lambda的用法了
lambda注意事项
我们的lambda可以使用外面定义的参数吗?答案是可以的例如下面的代码
public static void main(String[] args) {
int a=10;
OneParameterReturn ne=(int b)->{
System.out.println(a);
return 10;
};
ne.test(20);
}
这个代码的运行我们可以看到lambda是可以使用外面定义的变量的但是这里有个地方需要注意就是你要保证你使用的这个变量的值没有被修改过
public static void main(String[] args) {
int a=10;
a=20;
OneParameterReturn ne=(int b)->{
System.out.println(a);
return 10;
};
ne.test(20);
}
列如这样的代码就是报错的
public static void main(String[] args) {
int a=10;
OneParameterReturn ne=(int b)->{
a=30;
System.out.println(a);
return 10;
};
ne.test(20);
}
这样也是不行的。
开开心心的和你在一起生活哈哈哈