1. 什么是lambda?
目前已知的是,有个箭头 ->
说一大段官方话,也没有任何意义
我们直接看代码:
之前我们创建线程是这样的
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("run。。。。。。");
}
};
runnable.run();
用lambda:
Runnable run2 = () -> System.out.println("run。。。。。。");
run2.run();

是不是感觉特别离谱,看不懂
别急,还有更离谱的
很常见的一个例子,比较两个整数的大小
之前是这样写的
Comparator<Integer> myCom = new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return Integer.compare(o1, o2);
}
};
int compare = myCom.compare(12, 20);
int compare1 = myCom.compare(20, 12);
int compare2 = myCom.compare(20, 20);
System.out.println(compare);
System.out.println(compare1);
System.out.println(compare2);
}
用lambda:
Comparator<Integer> myCom = (o1, o2) -> Integer.compare(o1, o2);
int compare = myCom.compare(12, 20);
int compare1 = myCom.compare(20, 12);
int compare2 = myCom.compare(20, 20);
System.out.println(compare);
System.out.println(compare1);
System.out.println(compare2);
甚至还可以这样 (这个是方法引用)
Comparator<Integer> myCom = Integer::compare;
int compare = myCom.compare(12, 20);
int compare1 = myCom.compare(20, 12);
int compare2 = myCom.compare(20, 20);
System.out.println(compare);
System.out.println(compare1);
System.out.println(compare2);
第一个数比第二个数
大 :返回 1
小:返回 -1
相等:返回 0

刚接触是不是黑人问号,这是什么玩意
很好,到这,你认识到了lambda 一个缺点,可阅读性差 ,优点 代码简洁
小结:看到 -> lambda 看到 : : 方法引用
2. lamdba 语法
基本语法
1. 箭头操作符 -> 或者叫做lambda 操作符
2. 箭头操作符将lambda 表达式拆分成两部分
左侧:Lambda 表达式的参数列表
右侧:Lambda 表达式中所需执行的功能 , 即 Lambda 体
3. 语法格式
语法格式1:无参数,无返回值
() -> system.out.println("Hello Lambda")
前边线程的那个例子就是
语法格式2:有一个参数 无返回值
(x)-> System.out.println(x);
若只有一个参数可以省略不写
x-> System.out.println(x);
之前的写法,没有使用lambda
Consumer<String> consumer = new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println("输出的值:"+s);
}
};
consumer.accept("今天不想emo了");
使用lambda
Consumer<String> consumer = s -> System.out.println("输出的值:"+s);
consumer.accept("今天不想emo了");
语法格式3:有两个以上参数 ,并且lambda体有多条语句,有返回值
Comparator<Integer> myCom = (o1, o2) -> {
System.out.println("其他语句");
return Integer.compare(o1, o2);
};
语法格式4 lambda体中只有一条语句,return 和 大括号都可以省略不写
Comparator<Integer> com =(x,y)-> Integer.compare(x,y);
有没有发现所有的参数,都没有参数类型,之前我们写函数的时候可是要带上参数类型的
语法格式5 lambda表达式参数列表的数据类型可以省略不写,因为JVM编译器通过上下文编译推断出数据类型——类型推断
4. 函数式接口
不管上面哪一种语法格式,lambda都是需要函数式接口的支持
函数式接口:接口中只有一个抽象方法的接口 称为函数式接口
可以使用一个注解@FunctionalInterface 修饰,可以检查是否是函数式接口
我们可以看看Runnable 接口 的源码
完成的接口类代码如下
/*
* Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms
/
package java.lang;
/**
* The <code>Runnable</code> interface should be implemented by any
* class whose instances are intended to be executed by a thread. The
* class must define a method of no arguments called <code>run</code>.
* <p>
* This interface is designed to provide a common protocol for objects that
* wish to execute code while they are active. For example,
* <code>Runnable</code> is implemented by class <code>Thread</code>.
* Being active simply means that a thread has been started and has not
* yet been stopped.
* <p>
* In addition, <code>Runnable</code> provides the means for a class to be
* active while not subclassing <code>Thread</code>. A class that implements
* <code>Runnable</code> can run without subclassing <code>Thread</code>
* by instantiating a <code>Thread</code> instance and passing itself in
* as the target. In most cases, the <code>Runnable</code> interface should
* be used if you are only planning to override the <code>run()</code>
* method and no other <code>Thread</code> methods.
* This is important because classes should not be subclassed
* unless the programmer intends on modifying or enhancing the fundamental
* behavior of the class.
*
* @author Arthur van Hoff
* @see java.lang.Thread
* @see java.util.concurrent.Callable
* @since JDK1.0
*/
@FunctionalInterface
public interface Runnable {
/**
* When an object implementing interface <code>Runnable</code> is used
* to create a thread, starting the thread causes the object's
* <code>run</code> method to be called in that separately executing
* thread.
* <p>
* The general contract of the method <code>run</code> is that it may
* take any action whatsoever.
*
* @see java.lang.Thread#run()
*/
public abstract void run();
}

可以看到这里面就只有一个实现,有一个注解@FunctionalInterface ,说明它就是一个函数式接口,就可以进行lambda简写
来看 Comparator 也是一样 有@FunctionalInterface注解


这里可能就会有疑问,这边明明是有两个抽象方法,怎么是函数式接口呢?
别急 !!可以看到这边的注释, 说明这个equals 是 重写了超类 的 equals,本质上是对object 的重写,官方定义这样的抽象方法是不会被定义到 抽象接口数的 ,因此实际上只有一个抽象方法

我们自己可以试着定义 函数式接口,很简单
package com.test1.demo;
@FunctionalInterface
public interface MyFunc {
void method();
}
好了,如果,写两个抽象接口会怎样?

可以看到注解报错了,所以注解用来校验作用就在这
重申一遍,函数式接口:接口中只有一个抽象方法的接口 称为函数式接口
注解只是拿来校验的,方便我们一看就知道这是一函数式接口类,不然还得数个数,验证一下是不是只有一个
现在我也重写 equals ,可以看到并没有报错

5. java8 中内置四大核心函数式接口
Consumer<T> 消费型接口
//Consumer 消费型接口
@Test
public void testConsumer() {
cosumer(1000, (m) -> System.out.println("星期一" + m));
// 星期一1000.0
}
public void cosumer(double m, Consumer<Double> con) {
con.accept(m);
}
供给型接口 supplier<T>
@Test
public void testSupplier() {
List<Integer> numList = getNumList(10, () -> (int) (Math.random() * 100));
for (Integer integer : numList) {
System.out.println(integer); //100 以内10位随机整数
}
}
// 需求:产生指定个数的整数放入集合中
public List<Integer> getNumList(int num, Supplier<Integer> su) {
List<Integer> list = new ArrayList<>();
for (int i = 0; i < num; i++) {
Integer integer = su.get();
list.add(integer);
}
return list;
}
Function<T,R> 函数型接口
@Test
public void FunctioStr(){
String c = getFunction("sbjikss", str -> str.toUpperCase());
System.out.println(c); //SBJIKSS
String sub = getFunction("sbjikss", str -> str.substring(2, 3));
System.out.println(sub);//j
}
public String getFunction( String str, Function<String,String> f) {
return f.apply(str);
}
断言型接口 Predicate<T>
public void tetPre(){
List<String> list = Arrays.asList("Hello","sss","xxxx","sjjss");
List<String> list1 = filterStr(list, (pre) -> pre.length() > 3);
for (String s : list1) {
System.out.println(s); // Hello xxxx sjjss
}
}
//需求:将满足条件字符串放入集合中
public List<String> filterStr(List<String> old , Predicate<String> pre ){
List<String> newList = new ArrayList<>();
for (String str : old) {
if (pre.test(str)){
newList.add(str);
}
}
return newList;
}
感谢阅读!!!
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www
我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我
什么是ruby的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht
这篇文章是继上一篇文章“Observability:从零开始创建Java微服务并监控它(一)”的续篇。在上一篇文章中,我们讲述了如何创建一个Javaweb应用,并使用Filebeat来收集应用所生成的日志。在今天的文章中,我来详述如何收集应用的指标,使用APM来监控应用并监督web服务的在线情况。源码可以在地址 https://github.com/liu-xiao-guo/java_observability 进行下载。摄入指标指标被视为可以随时更改的时间点值。当前请求的数量可以改变任何毫秒。你可能有1000个请求的峰值,然后一切都回到一个请求。这也意味着这些指标可能不准确,你还想提取最小/
HashMap中为什么引入红黑树,而不是AVL树呢1.概述开始学习这个知识点之前我们需要知道,在JDK1.8以及之前,针对HashMap有什么不同。JDK1.7的时候,HashMap的底层实现是数组+链表JDK1.8的时候,HashMap的底层实现是数组+链表+红黑树我们要思考一个问题,为什么要从链表转为红黑树呢。首先先让我们了解下链表有什么不好???2.链表上述的截图其实就是链表的结构,我们来看下链表的增删改查的时间复杂度增:因为链表不是线性结构,所以每次添加的时候,只需要移动一个节点,所以可以理解为复杂度是N(1)删:算法时间复杂度跟增保持一致查:既然是非线性结构,所以查询某一个节点的时候
遍历文件夹我们通常是使用递归进行操作,这种方式比较简单,也比较容易理解。本文为大家介绍另一种不使用递归的方式,由于没有使用递归,只用到了循环和集合,所以效率更高一些!一、使用递归遍历文件夹整体思路1、使用File封装初始目录,2、打印这个目录3、获取这个目录下所有的子文件和子目录的数组。4、遍历这个数组,取出每个File对象4-1、如果File是否是一个文件,打印4-2、否则就是一个目录,递归调用代码实现publicclassSearchFile{publicstaticvoidmain(String[]args){//初始目录Filedir=newFile("d:/Dev");Datebeg
我基本上来自Java背景并且努力理解Ruby中的模运算。(5%3)(-5%3)(5%-3)(-5%-3)Java中的上述操作产生,2个-22个-2但在Ruby中,相同的表达式会产生21个-1-2.Ruby在逻辑上有多擅长这个?模块操作在Ruby中是如何实现的?如果将同一个操作定义为一个web服务,两个服务如何匹配逻辑。 最佳答案 在Java中,模运算的结果与被除数的符号相同。在Ruby中,它与除数的符号相同。remainder()在Ruby中与被除数的符号相同。您可能还想引用modulooperation.
Java的Collections.unmodifiableList和Collections.unmodifiableMap在Ruby标准API中是否有等价物? 最佳答案 使用freeze应用程序接口(interface):Preventsfurthermodificationstoobj.ARuntimeErrorwillberaisedifmodificationisattempted.Thereisnowaytounfreezeafrozenobject.SeealsoObject#frozen?.Thismethodretur
我经常将预配置的lambda插入可枚举的方法中,例如“map”、“select”等。但是“注入(inject)”的行为似乎有所不同。例如与mult4=lambda{|item|item*4}然后(5..10).map&mult4给我[20,24,28,32,36,40]但是,如果我制作一个2参数lambda用于像这样的注入(inject),multL=lambda{|product,n|product*n}我想说(5..10).inject(2)&multL因为“inject”有一个可选的单个初始值参数,但这给了我......irb(main):027:0>(5..10).inject