Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性。
Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。
Lambda表达式是一种匿名函数,它没有声明的方法,即没有访问修饰符,返回值声明和名字
一个Lambda表达式可以有零个或多个参数
参数的类型既可以明确声明,也可以根据上下文推断,例如:(int a)和(a)效果相同
所有参数需要包含在圆括号内,参数之间用逗号相隔。例如:(a,b)或(int a,int b)
空圆括号代表参数集为空。() -> 42
当只有一个参数,且其类型可以推导时,圆括号可以省略a -> return a*a
Lambda表达式的主体可包含零条或多条语句
如果Lambda表达式的主体只有一条语句,花括号可省略。匿名函数的返回类型与该主体表达式一致
如果Lambda表达式的主体包含一条以上语句,则表达式必须包含在花括号中。匿名函数的返回类型与代码块的返回类型一致,若没有返回则为空
特征:
可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定明表达式返回了一个数值。
Lambda 表达式需要注意以下两点:
Lambda 表达式主要用来定义行内执行的方法类型接口
Lambda 表达式免去了使用匿名方法的麻烦
(parameters) -> expression
或
(parameters) ->{ statements; }
// 1. 不需要参数,返回值为 5
() -> 5
// 2. 接收一个参数(数字类型),返回其2倍的值
x -> 2 * x
// 3. 接受2个参数(数字),并返回他们的差值
(x, y) -> x – y
// 4. 接收2个int型整数,返回他们的和
(int x, int y) -> x + y
// 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void)
(String s) -> System.out.print(s)
public class Java8Tester {
public static void main(String args[]){
Java8Tester tester = new Java8Tester();
// 类型声明
MathOperation addition = (int a, int b) -> a + b;
// 不用类型声明
MathOperation subtraction = (a, b) -> a - b;
// 大括号中的返回语句
MathOperation multiplication = (int a, int b) -> { return a * b; };
// 没有大括号及返回语句
MathOperation division = (int a, int b) -> a / b;
System.out.println("10 + 5 = " + tester.operate(10, 5, addition));
System.out.println("10 - 5 = " + tester.operate(10, 5, subtraction));
System.out.println("10 x 5 = " + tester.operate(10, 5, multiplication));
System.out.println("10 / 5 = " + tester.operate(10, 5, division));
// 不用括号
GreetingService greetService1 = message ->
System.out.println("Hello " + message);
// 用括号
GreetingService greetService2 = (message) ->
System.out.println("Hello " + message);
greetService1.sayMessage("Runoob");
greetService2.sayMessage("Google");
}
interface MathOperation {
int operation(int a, int b);
}
interface GreetingService {
void sayMessage(String message);
}
private int operate(int a, int b, MathOperation mathOperation){
return mathOperation.operation(a, b);
}
}
/*
10 + 5 = 15
10 - 5 = 5
10 x 5 = 50
10 / 5 = 2
Hello Runoob
Hello Google
*/
如果某个接口只有一个抽象方法,但我们并没有给该接口声明FunctionalInterface注解,那么编译器依旧会将该接口看做是函数式接口
//遍历集合
List<Integer> list = Arrays.asList(1,2,3,4,5);
list.forEach(i -> {
System.out.println(i);
});
//方法引用:method reference
list.forEach(System.out::println);
//-------------------------------------------
List<String> list2 = Arrays.asList("str","hello");
//存放list中元素转换为大写后的集合
List<String> res = new ArrayList<>();
list2.forEach((item) -> {res.add(item.toUpperCase())});
//使用stream流操作
list.stream().map(item -> item.toUpperCase()).forEach(item ->System.out.println(item));
//使用方法引用
list.stream().map(String::toUpperCase()).forEach(item ->System.out.println(item));
//排序
Collections.sort(list2, (o1,o2) -> 02.compateTo(o1));
//建立线程
new Thread(() -> {System.out.println("run方法实现");}).start();
//原始方法
public int method1(int a){
//2*a其实就是一种行为
return 2*a;
}
public int method2(int a) {
return 5+a;
}
System.out.println(method1(2))//结果为:4
System.out.println(method2(2))//结果为:7
//使用Lambda方式传递行为
//Function<Integer,Integer>表示传入一个Integer类型,返回一个Integer类型
public int compute(int a,Function<Integer,Integer>function){
int result = function.apply(a);
return result;
}
//Function传入一个Integer类型,返回一个String类型
public String conver(int a, Function<Integer,String>function){
return function.apply(a);
}
//传递的行为是:2*value
System.out.println(compute(2,value -> {2*value}));//结果:4
//传递的行为是:value + " hello"
System.out.println(conver(2,value -> {String.valueOf(value + " hello")}));
public int compute(int a, Function<Integer,Integer> fun1,Function<Integer,Integer> fun2)
{
//compose方法先执行参数的function中的apply,然后再执行自己的apply方法
return fun1.compose(fun2).apply(a);
}
public int compute2(int a, Function<Integer,Integer> fun1,Function<Integer,Integer> fun2)
{
//andThen方法先执行自己的apply方法,然后执行参数中的function的apply方法
return fun1.andThen(fun2).apply(a);
}
//结果为:12。先执行参数function的行为2*2=4,然后执行自己的行为4*3=12
System.out.println(comupute(2, value -> value * 3, value -> value * value))
//结果为:36,先执行自己的行为2*3=6,然后执行参数function的行为6*6=36
System.out.println(comupute2(2, value -> value * 3, value -> value * value))
public int compute(int a,int b,Function<Integer,Integer,Integer>function){
int result = function.apply(a,b);
return result;
}
System.out.println(compute(2,3,(value1,value2) -> {value1*value2}));//结果:6
public int compute2(int a,int b,BiFunction<Integer,Integer,Integer>bifun,
Function<Integer,Integer> fun){
return bifun.andThen(fun).apply(a,b);
}
//结果:25
System.out.println(compute2(2,3,(value1,value2) -> {value1+value2},val -> val*val));
public List<Person> getPersonByUsername(String username,List<Person> persons)
{
return persons.stream().filter(person -> person.getUsername().equals(username)).
collect(Collections.toList());
}
public List<Person> getPersonByAge(int age,List<Person> persons)
{
BiFunction<Integer,List<Person>,List<Person>> bi = (ageOfPerson,personList) ->
return personList.stream().filter(person -> person.getAge() > ageOfPerson).collect(Collections.toList());
return bi.apply(age,persons);
}
//更加灵活,由调用者根据参数制定行为
public List<Person> getPersonByAge2(int age,List<Person> persons,BiFunction<Integer,List<person>> biFunction)
{
return biFunction.apply(age,persons);
}
Person person1 = new Person("zhangsan",22);
Person person2= new Person("lisi",25);
Person person3 = new Person("wangwu",33);
List<Person> persons = Arrays.asList(person1,person2,person3);
//从list集合中查找名字匹配的对象重新封装为一个集合
List<Person> personResult = xxx.getPersonByUsername("zhagnsan",persons);
personResult.forEach(person -> System.out.println(person.getUsername()));
//从list集合中查找年龄在范围内的对象重新封装为一个集合
List<Person> personResult2 = xxx.getPersonByAge(20,persons);
personResult.forEach(person -> System.out.println(person.getAge()));
//由调用者制定行为
List<Person> personResult3 = xxx.getgetPersonByAge2(20,persons,(age,personList) -> {
return personList.stream().filter(person -> person.getAge() >= age).collect(Collections.toList());
});
public void condition(List<Integer> list, Predicate<Integer> pre) {
for(Integer integer : list) {
if(pre.test(integer))
Syetem.out.println(integer);
}
}
List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9);
//找出大于3的数
xxx.condition(list,item -> item > 3);
//打印全部
xxx.condition(list,item -> true);
public void condition(List<Integer> list, Predicate<Integer> pre1,Predicate<Integer> pre2) {
for(Integer integer : list) {
if(pre1.and(pre2).test(integer))
Syetem.out.println(integer);
}
}
List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9);
//输出大于5并且是偶数的数
xxx.condition(list,item -> item > 5,item -> item % 2 == 0);
//不传入参数,返回一个Student类型,调用无参构造方法
Supplier<Student> supplier = Student :: new;
System.out.println(supplier.get().getName());
//比较方法
public String getSort(String a,String b,Comparator<String> comparator){
return BinaryOperator.maxBy(comparator).apply(a,b);
}
xxx.getSort("hello","world",(a,b) -> a.length() - b.length());
@FunctionalInterface
public interface Supplier<T> {
T get();
}
class Car {
//Supplier是jdk1.8的接口,这里和lamda一起使用了
public static Car create(final Supplier<Car> supplier) {
return supplier.get();
}
public static void collide(final Car car) {
System.out.println("Collided " + car.toString());
}
public void follow(final Car another) {
System.out.println("Following the " + another.toString());
}
public void repair() {
System.out.println("Repaired " + this.toString());
}
}
//构造器引用:它的语法是Class::new,或者更一般的Class< T >::new实例如下:
final Car car = Car.create( Car::new );
final List< Car > cars = Arrays.asList( car );
//静态方法引用:它的语法是Class::static_method,实例如下:
cars.forEach( Car::collide );
//特定类的任意对象的方法引用:它的语法是Class::method实例如下:
cars.forEach( Car::repair );
//特定对象的方法引用:它的语法是instance::method实例如下:
final Car police = Car.create( Car::new );
cars.forEach( police::follow );
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.imooc.security</groupId>
<artifactId>imooc-security</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
<imooc.security.version>1.0.0-SNAPSHOT</imooc.security.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.spring.platform</groupId>
<artifactId>platform-bom</artifactId>
<version>Brussels-SR4</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Dalston.SR2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
<modules>
<module>../imooc-security-app</module>
<module>../imooc-security-browser</module>
<module>../imooc-security-core</module>
<module>../imooc-security-demo</module>
</modules>
</project>
数组 int[] arr={5,2,8,4,9,1};
第一趟排序: 原始数据:5 2 8 4 9 1
最小数据1,把1放在首位,也就是1和5互换位置,
排序结果:1 2 8 4 9 5
第二趟排序:
第1以外的数据{2 8 4 9 5}进行比较,2最小,
排序结果:1 2 8 4 9 5
每一趟排序获得最小数的方法:for循环进行比较,定义一个第三个变量temp,首先前两个数比较,把较小的数放在temp中,然后用temp再去跟剩下的数据比较,如果出现比temp小的数据,就用它代替temp中原有的数据
//选择排序
public class SelectionSort {
public static void main(String[] args) {
int[] arr={1,3,2,45,65,33,12};
System.out.println("交换之前:");
for(int num:arr){
System.out.print(num+" ");
}
//选择排序的优化
for(int i = 0; i < arr.length - 1; i++) {// 做第i趟排序
int k = i;
for(int j = k + 1; j < arr.length; j++){// 选最小的记录
if(arr[j] < arr[k]){
k = j; //记下目前找到的最小值所在的位置
}
}
//在内层循环结束,也就是找到本轮循环的最小的数以后,再进行交换
if(i != k){ //交换a[i]和a[k]
int temp = arr[i];
arr[i] = arr[k];
arr[k] = temp;
}
}
System.out.println();
System.out.println("交换后:");
for(int num:arr){
System.out.print(num+" ");
}
}
}