泛型
- 什么是泛型:将类型参数化,也就是数据类型是参数形式存在的,使得数据类型可以变化。
- 泛型是jdk1.5新增的特性。
不使用泛型,数据类型被固定
public class Student {
/*
* 分析:name的类型是固定的getName的返回值也是固定的。
*/
String name;
public String getName() {
return this.name;
}
}
如果开发中数据的类型要求是可以变化的,可以使用泛型实现。
泛型接口
需求:接口中方法的返回值类型由子类确定
public interface Teacher<T> {
T get();
}
public class Teacher_child implements Teacher<Teacher_child>{
@Override
public Teacher_child get() {
return null;
}
}
泛型的类型是由子类或者调用时,由子类或者调用者传入实际类型。
泛型类
类中方法参数和返回值类型是由调用者确定()
public abstract class Worker<T> {
public abstract T get(T t);
}
public class Worker_child extends Worker<String>{
@Override
public String get(String t) {
// TODO Auto-generated method stub
return null;
}
}
泛型方法
public class Student {
/*
* 参数为T类型,返回值类型为E
*
*/
public <T,E> E get(T t) {
return null;
}
public <T> void get1(T t){
}
public static void main(String[] args) {
Student s=new Student();
/*
* 传进去一个字符串类型,返回一个Integer类型
* T:String E:Integer
*/
Integer s1=s.<String,Integer>get("asd");
/*
* 传进去一个字符串,无返回值(以下两句等价)T:String
*/
s.<String>get1("wer");
s.get1("e");
}
}
方法参数与返回值由调用者确定。
方法可变参数
public class VariablepParameters {
/*
* ...a表示参数a是可变化的,(变化的是个数),相当于一个数组
* 方法可变参数规则
* (1)一个方法参数中只能有一个可变参数
* (2)可变参数应该放在最后面
*/
public void ex(int ...is) {
if(is!=null) {
for(int i=0;i<is.length;i++) {
System.out.println(is[i]);
}
}
}
public void exe(String a, int ...w) {
if(w!=null) {
for(int i=0;i<w.length;i++) {
System.out.println(w[i]);
}
}
}
public static void main(String[] args) {
//将1、2、3、4传入到可变参数中,相当于传入到一个数组中
VariablepParameters s=new VariablepParameters();
s.ex(1,2,3,4);
//第一个参数传给String ,其余的传给了可变参数
VariablepParameters s1=new VariablepParameters();
s1.exe("p", 1,2,3);
//方法可变参数可以不传入值,如果没有传入值默认为null
s1.exe("aa");
//也可以传入null
s1.exe("aa", null);
}
}
静态导入
普通导入
public class StaticImport {
public static final String URl="asd";
}
public class User {
public void get() {
System.out.println(StaticImport.URl);
}
}
//静态导入
import static staticdao.StaticImport.URl;;
public class User {
public void get() {
System.out.println(URl);
}
}
Lambda表达式
- 为什么使用lambda表达式
- lambda是接口的一种实现方式,是JDK1.8的新特性。
- 接口的使用过程
- 定义接口
- 实现接口
- 接口使用
- 接口实现的第一层次:命名类
- 接口定义
public interface IMathOper {
int add(int x,int y);
}
- 接口实现
public class MathI implements IMathOper{
@Override
public int add(int x, int y) {
return x+y;
}
}
- 接口使用
public class Test {
public static void main(String[] args) {
IMathOper math=new MathI();
System.out.println(math.add(1, 1));
}
}
- 接口实现的第二层次:匿名类
- 接口定义
public interface IMathOper {
int add(int x,int y);
}
- 接口的实现以及使用
public class Test {
public static void main(String[] args) {
/*
* 匿名类(接口没有被实例化,jvm提供了一个匿名类,让匿名类来实现这个接口)
*
*/
IMathOper math=new IMathOper() {
@Override
public int add(int x, int y) {
return x+y;
}
};
System.out.println(math.add(1, 1));
}
}
- 接口实现的第三层次:lambda表达式
- 接口的定义
public interface IMathOper {
int add(int x,int y);
}
- 接口的实现以及使用
public class Test {
public static void main(String[] args) {
//接口的实现lambda实现的
IMathOper iMathOper=(x,y)->{
return x+y;
};
System.out.println(iMathOper.add(1, 2));
}
}
lambda表达式的写法
- (参数)->{方法体}
- 一个参数(只有一个参数时,()可以省略,不推荐省略)
-方法实现只有一行代码时,可以省略
x->System.out.println(x);
- 没有参数
()->System.out.println("hello");
- 函数体有多条语句
(a,b)->{
a++;
b++;
}
空函数
()->{}
Lambda表达式具有以下特征
- 可选的类型声明:不需要声明函数类型,编译器可以自动识别参数类型
- 可选的参数圆括号:一个参数无须使用圆括号,但多个参数则需要使用圆括号
- 可选的花括号:如果函数体只有一条语句,则补血药使用花括号
- 可选的返回关键字:如果函数体只有一条语句,则编译器会自动返回该语句执行的结果;如果有多条语句且有返回值,那么在花括号中需要使用return语句来返回结果。
Lambda的限制条件
- Lambda表达式在实现接口时,接口中只允许有且只有一个抽象方法
- 这种限制可以使用函数式接口来定义
函数式接口
- lambda表达式对接口中的方法给出了实现,如果接口中声明了多个抽象方法,那么表达式实现的方法无法确定,因此要求只能有一个抽象方法,这样的接口称为函数式接口
为了避免接口中出现多个抽象方法,可以使用@FunctionalInterface注解,声明该接口是一个函数式接口
如果加了注解后,在接口中还有其他的抽象方法,那么编译时,会提示错误。
@FunctionalInterface
public interface IMathOper {
int add(int x,int y);
}
方法引用
- 接口实现
- 如果一个类中的实现方法,其参数列表和返回值类型与某个函数式接口中的方法一致,那么可以使用方法引用的方式来代替Lambda表达式。Java编译器会利用函数式接口中方法的参数来调用引用的方法,并将该方法的返回值(如果有的话)作为接口方法的返回值。
-方法引用使用操作符"::"将对象或者类的名字与方法名分隔开。主要有以下三种形式:- 对象名::实例方法
- 类名::静态方法
public class MyMath {
public int increment(int num) {
return ++num;
}
public static int decrement(int num) {
return --num;
}
}
import java.util.function.Function;
public class Test {
public static void main(String[] args) {
//lambda表达式
Function<Integer, Integer> function=(num)->{
return ++num;
};
System.out.println(function.apply(10));
/*
* 使用方法引用(类名::静态方法)
*/
Function<Integer, Integer> fun=MyMath::decrement;
System.out.println(fun.apply(12));
/*
* 方法引用(对象名::实例方法)
*/
MyMath math=new MyMath();
Function<Integer, Integer> funu=math::increment;
System.out.println(funu.apply(12));
}
}
枚举
是java中一种数据类型,用enum定义。枚举与类,接口是并列关系/
为什么使用枚举
枚举能够非常好的表现出一组值固定且有限个数的数据。
public enum Gender {
男,女
}
package enum1;
public class Student {
private String no;
private Gender gender;
/*
* 性别使用String表示的缺点是
* 无法限定值的内容,输入啥都可以
* 使用枚举的好处是:性别的值被固定了
*/
public String getNo() {
return no;
}
public void setNo(String no) {
this.no = no;
}
public Gender getGender() {
return gender;
}
public void setGender(Gender gender) {
this.gender = gender;
}
@Override
public String toString() {
return "Student [no=" + no + ", gender=" + gender + "]";
}
}
public class Test {
public static void main(String[] args) {
Student a=new Student();
a.setNo("110");
a.setGender(Gender.男);
System.out.println(a);
}
}