java高级特性(泛型、lambda、枚举、方法可变参数、静态导入)

泛型

  • 什么是泛型:将类型参数化,也就是数据类型是参数形式存在的,使得数据类型可以变化。
  • 泛型是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的新特性。
  1. 接口的使用过程
  • 定义接口
  • 实现接口
  • 接口使用
  1. 接口实现的第一层次:命名类
  • 接口定义
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));
	}
}
  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));
	}
}
  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);
	}
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值