学习lamdba有两个结构十分关键,一个是lamdba自己,另一个是函数式接口
lamdba
函数式接口
lambda表达式示例
interface MyNumber{
double getValue();
}
public static void main(String[] args){
MyNumber myNum;
myNum = ()-> 3.1415;
System.out.println(myNum.getValue())
}
//输出
3.1415
块lambda 阶乘示例
interface MyNum{
int func(int n);
}
public void test1(){
MyNum mm = (n)->{
int result =1;
for(int i=1;i<=n;i++){
result *= i;
}
return result;
};
System.out.println(mm.func(4));
}
示例
interface SomeFunc<T>{
T func(T t);
}
public void test2(){
SomeFunc<Integer> num = (n)-> n*10;
SomeFunc<String> str = (s)-> "hello " + s;
System.out.println(num.func(10));
System.out.println(str.func("tom"));
}
interface SomeFunc<T>{
T func(T t);
}
public String getResult(SomeFunc<String> some,String str){
return some.func(str);
}
public void test3(){
String str = "hello java for lambda";
String ret = getResult((n)->{
return n.toUpperCase();
},str);
System.out.println(ret);
String ret1 = getResult((n)->{
return new StringBuffer(str).reverse().toString();
},str);
System.out.println(ret1);
}
//输出
HELLO JAVA FOR LAMBDA
adbmal rof avaj olleh
代码示例
interface DoubleNumberFun{
double fun(double[] n)throws DoubleNumberException;
}
class DoubleNumberException extends Exception{
public DoubleNumberException(){
super("array empty");
}
}
public void test4() throws DoubleNumberException {
DoubleNumberFun df = (n)->{
if(n.length == 0)
throw new DoubleNumberException();
double sm = 0.0;
for(int i=0;i<n.length;i++){
sm += n[i];
}
return sm;
};
System.out.println(df.fun(new double[]{1.0,2.0,3.0}));
System.out.println(df.fun(new double[]{}));
}
//输出
//6.0
//com.bai.lambda.DoubleNumberException: array empty
代码示例
interface MyNum{
int func(int n);
}
int variable = 10;
public void test5(){
int variable1 = 0;
MyNum m = (n)->{
int sum = 0;
for(int i=0;i<n;i++){
sum += i + variable1;
}
//此处报错
//Variable used in lambda expression should be final or effectively final
//variable1 = sum;
return sum;
};
MyNum m1 = (n)->{
int sum = 0;
for(int i=0;i<n;i++){
//Variable used in lambda expression should be final or effectively final
sum += i + this.variable;
}
this.variable = sum;
return sum;
};
}
代码示例
函数式接口
interface StringFunc{
String func(String str);
}
静态方法
public static String StrReverse(String str){
char[] chars = new char[str.length()];
for(int i=0;i<str.length();i++){
chars[i] = str.charAt(str.length()-1-i);
}
return new String(chars);
}
方法引用
public static String stringOpts(StringFunc func,String str){
return func.func(str);
}
测试方法
public static void main(String[] args) {
String result = stringOpts(MyStringOpts::StrReverse,"helllo lambda static");
System.out.println(result);
}
//输出
//citats adbmal ollleh
objRef::methodname
需要先 new 对象在进行调用
interface StringFunc{
String func(String str);
}
class ObjRef{
public String reverse(String str){
StringBuffer buf = new StringBuffer();
for(int i=0;i<str.length();i++){
buf.append(str.charAt(str.length()-1-i));
}
return buf.toString();
}
}
class MainTest1{
public static String stringOpts(StringFunc func,String str){
return func.func(str);
}
public static void main(String[] args) {
ObjRef objRef = new ObjRef();
String result = stringOpts(objRef::reverse,"你好 lambda");
System.out.println(result);
}
}
//输出
//adbmal 好你
className::methodName
具体请看代码示例:
函数式接口
注意这个函数有两个参数
interface MyFunc<T>{
boolean func(T t1,T t2);
}
实体对象
主要使用下面的equals,lessThan方法,两个方法中的参数对应函数式接口中的第二个参数
class Student{
private Integer glades;
public Student(Integer glades){
this.glades = glades;
}
public boolean equals(Student student){
return glades == student.glades;
}
public boolean lessThan(Student student){
return glades < student.glades;
}
}
方法引用
public static <T> int count(T[] val,MyFunc<T> f,T v){
int count = 0;
for(int i=0;i<val.length;i++){
if(f.func(val[i],v))
count++;
}
return count;
}
测试
Student[] arrs = new Student[]{
new Student(50),
new Student(60),
new Student(60),
new Student(80),
new Student(90)};
int ret = count(arrs,Student::equals,new Student(60));
System.out.println(ret);
//2
int ret1 = count(arrs,Student::lessThan,new Student(60));
System.out.println(ret1);
//2
接口
interface MyFunc<T>{
int func(T[] vals,T t);
}
泛型方法,非泛型类
public class FanxingLambda {
static <T> int countMath(T[] vals,T t){
int count = 0;
for(int i=0;i<vals.length;i++){
if(vals[i] == t)
count++;
}
return count;
}
}
引用方法
public static <T> int countFun(MyFunc<T> f,T[] vals,T t){
return f.func(vals,t);
}
测试方法
public static void main(String[] args) {
Integer[] arrs = new Integer[]{1,2,3,4,5,2,4,5,2,1,2,3};
int count = countFun(FanxingLambda::<Integer>countMath,arrs,2);
System.out.println(count);
}
注意
int count = countFun(FanxingLambda::<Integer>countMath,arrs,2);
FanxingLambda::countMath
因为FanxingLambda不是泛型类,但是countMath是泛型方法,所以可以在::前面指定Integer类型
也可以不写,因为类型参数会推断出类型
需要使用Collections.max方法,其中第二个参数传入一个比较器Comparator
源码
Collections : public static <T> T max(Collection<? extends T> coll, Comparator<? super T> comp)
Comparator: int compare(T o1, T o2);
测试代码
实体
class Salary{
private double val;
public Salary(double val){
this.val = val;
}
public double getVal(){
return val;
}
public static int comparaSalary(Salary s1,Salary s2){
return (int)(s1.val - s2.val);
}
}
测试方法
public static void main(String[] args) {
List<Salary> list = new ArrayList<>();
list.add(new Salary(100.1));
list.add(new Salary(2000.3));
list.add(new Salary(1000));
list.add(new Salary(3000.5));
list.add(new Salary(235));
Salary s = Collections.max(list,Salary::comparaSalary);
System.out.println(s.getVal());
}
//3000.5
classname::new
interface ClassFun<T,V>{
T func(V v);
}
class Emp{
private Integer age;
public Emp(Integer age){
this.age = age;
}
public Integer getAge(){
return age;
}
}
class People<T>{
private T t;
public People(T t){
this.t = t;
}
public T getVal(){
return t;
}
}
ClassFun<Emp,Integer> c = Emp::new;
Emp e = c.func(100);
System.out.println(e.getAge());
ClassFun<People<String>,String> c1 = People::new;
People<String> p = c1.func("zhangsan");
System.out.println(p.getVal());
//100
//zhangsan