java-day25

Day25 1.8 新特性

1.lambda

1.1 概述

lambda表达式 是一种没有名字的函数,也可以称为闭包,是java8的新特性

本质就是一个匿名内部类,还有叫箭头函数的

1.2 为什么使用lambda

Lambda 是一个匿名函数,我们可以把Lambda 表达式理解为是一段可以传递的代码(将代码像数据一样进行传递)。使用它可以写出更简洁、更灵活的代码。作为一种更紧凑的代码风格,使Java的语言表达能力得到了提升。

1.3 与匿名内部类对比

在这里插入图片描述
在这里插入图片描述

1.4 特点

允许把方法作为一个参数,进行传递
使用Lambda表达式可以使代码变的更加简洁紧凑

1.5 语法结构

1.5.1 结构图

Lambda 表达式:在Java 8 语言中引入的一种新的语法元素和操作符。这个操作符为“->” ,该操作符被称为Lambda 操作符或箭头操作符。它将Lambda 分为两个部分:
左侧:指定了Lambda 表达式需要的参数列表
右侧:指定了Lambda 体,是抽象方法的实现逻辑,也即Lambda 表达式要执行的功能。
在这里插入图片描述

1.5.2 语法特点

可选类型声明 : 不需要声明数据类型,编译器可以识别参数值
可选的参数()括号 : 一个参数无需定义括号,但是多个参数必须要定义括号
可选的大括号 : 如果主体内包含一个语句,就不需要大括号
可选的返回关键字 : 如果主体中只有一个表达式,并且是返回值语句的话,大括号中需要指明表达式返回的一个数据

如果只有一条语句,并且是返回值语句的话,return和{} 都可以不写
如果写上{} 那么 return和; 必须要写
如果有多条语句,必须写{} 和return;

1.5.3 语法案例

1 不需要参数,返回值为5
() -> 5
2 接收一个参数(数字类型),返回该数的2倍值
x -> 2x
3 接收2个参数(数字),返回差值
(x,y) -> x-y
4 接收2个int整数,返回他们的和
(int x , int y) -> x+y
5 接收一个String类型,并把该字符串打印到控制台,不需要返回值(void)
(String str) -> System.out.println(str)

1.6 练习

1.6.1 集合遍历

**1.6.1.1 1.7写法1 **

	// 创建数组
	String[] arr = { "one", "two", "three" };
	// 转换为集合
	List<String> list = Arrays.asList(arr);
	// 遍历集合 1.7含之前的写法
	for (String string : list) {
		System.out.println(string);
	}

1.6.1.2 1.7写法2

// 匿名内部类写法
// 在forEach中 会自动调用 这个匿名内部类对象的accept方法,并把集合中每个数据传递进去
list.forEach(new Consumer<String>() {
	@Override
	public void accept(String t) {
		System.out.println(t);
	}
});

在这里插入图片描述

本质 就是传递一个对象,然后forEach方法自动遍历集合,并且把集合中每个元素依次调用该对象中的accept方法,并把值传递进去

1.6.1.3 1.8写法

// 1.8新写法
// 类型可以不指定
// 一个参数 括号可以不加()
// 一条语句,大括号也可以不加{}
// 不加大括号, ; 分号也不用加
list.forEach(x -> System.out.println(x));

简化了匿名内部类,和匿名内部类是等价的

x -> System.out.println(x)
就等于
new Consumer() {
@Override
public void accept(String t) {
System.out.println(t);
}
}

而这个表达式 就是在描述 该匿名内部类中这个方法的,返回值,参数,方法体
只不过是这个方法的一种简单写法
不过该接口 只能有一个抽象方法

1.6.2 集合排序

1.6.2.1 1.7写法

// 创建数组
Integer[] arr = { 2, 6, 8, 1, 3, 9, 5 };
// 转换为集合
List<Integer> list = Arrays.asList(arr);

// 1.8之前的写法
// 降序
list.sort(new Comparator<Integer>() {
	@Override
	public int compare(Integer o1, Integer o2) {
		// o1-o2 是升序
		return o2 - o1;
	}
});
System.out.println(list);

1.6.2.2 1.8写法

// 1.8 写法 使用箭头函数
// 升序
// 多个参数 要加()  逗号隔开
// 只有一条返回值语句,{} 和 return ; 都可以不加
list.sort((x,y)->x-y);
System.out.println(list);

2. 函数式接口

2.1 概述

英文 : Functional Interface
本质就是一个只有一个抽象方法,但是可以有多个非抽象方法的接口
核心目标就是为Lambda表达式的使用提供更好的支持,进一步达到函数式编程的目标,提高开发效率

2.2 特点

特点 :
函数式接口是仅指定一个抽象方法的接口
可以保护多个静态方法和默认方法
专用注解 @FunctionalInterface ,检查是否是一个函数式接口,也可以不写该注解
如果有两个或以上个抽象方法,就不能当做函数式接口去使用,同时也不能添加 @FunctionalInterface 这个注解

2.3 回调函数

简单来说,就是方法需要传入一个参数也是方法,并且在该方法中对这个传入的方法进行调用

2.4 自定义函数式接口

2.4.1 无参情况

package com.demo._FunInterface;

/**
 * 英文 : Functional Interface
 * 本质就是一个只有一个抽象方法,但是可以有多个非抽象方法的接口
 * 核心目标就是为Lambda表达式的使用提供更好的支持,进一步达到函数式编程的目标,提高开发效率
 * 
 * 特点 : 
 * 		函数式接口是仅指定一个抽象方法的接口
 * 		可以保护多个静态方法和默认方法
 * 		专用注解 @FunctionalInterface ,检查是否是一个函数式接口,也可以不写该注解
 * 		如果有两个或以上个抽象方法,就不能当做函数式接口去使用,同时也不能添加 @FunctionalInterface 这个注解
 */
public class _01_FunInterface {
	public static void main(String[] args) {
		// 1 实现类的方式
		Test test = new Test();
		call(test);

		// 2 匿名内部类实现方式
		call(new MyFunctionInter() {
			@Override
			public void printMessage() {
				System.out.println("匿名内部类的实现方式");
			}
		});

		// 3 1.8新写法 Lambda
		call(() -> System.out.println("Lambda表达式的实现方式"));
		
		// 4 1.8新写法,先创建函数对象,类似于实现类
		MyFunctionInter inter = () ->System.out.println("创建函数对象的实现方式");
		call(inter);
	}
	public static void call(MyFunctionInter func){
		func.printMessage();
	}
}
@FunctionalInterface
interface MyFunctionInter {
	void printMessage();
}

// 实现类
class Test implements MyFunctionInter{

	@Override
	public void printMessage() {
			System.out.println("实现类的方式");
	}
}

2.4.2 有参情况

package com.demo._FunInterface;

/**
 * 有参情况

 */
public class _02_FunInterface {
	public static void main(String[] args) {
		String str = "有参函数式接口调用";
		// 1 匿名内部类
		call(new MyFunctionInter2(){
			@Override
			public void printMessage(String str) {
				System.out.println(str);
			}
		}, str);
		// 2 lambda
		call(s -> System.out.println(s), str);
		
		// 3 创建函数对象
		MyFunctionInter2 inter2 = s -> System.out.println(s);
		call(inter2, str);
	}

	// str为 printMessage方法的参数
	public static void call(MyFunctionInter2 func,String str) {
		// 调用func对象 的printMessage方法 并传入 str
		func.printMessage(str);
	}
}

@FunctionalInterface
interface MyFunctionInter2 {
	void printMessage(String str);
}

2.5 JDK 自带的函数式接口

2.5.1 Supplier

Supplier 接口 : 表示供应商,所以有返回值,可以获取数据

get方法

package com.demo._FunInterface;

import java.util.function.Supplier;

/**
 * Supplier<T> 接口 : 表示供应商,所以有返回值,可以获取数据
 * 
 * get方法

 */
public class _03_JdkOwn {
	public static void main(String[] args) {
		// 匿名内部类写法
		String result = getResult(new Supplier<String>() {
			@Override
			public String get() {
				return "你好啊";
			}
		});
		System.out.println(result);
		
		// Lambda写法
		result = getResult( ()->"xxxx" );
		System.out.println(result);
		
		// 创建Supplier容器
		// 此时不会调用构造方法创建对象
		Supplier<_03_JdkOwn> sup = _03_JdkOwn::new;
		// 创建对象并返回
		_03_JdkOwn jo1 = sup.get();
		_03_JdkOwn jo2 = sup.get();
		System.out.println(jo1);
		System.out.println(jo2);
	}

	public static String getResult(Supplier<String> function) {
		return function.get();
	}
}

2.5.2 Consumer

Consumer 接口 : 表示消费者接口,所以不需要返回值

accept(T t) 用于执行消费操作

package com.demo._FunInterface;

import java.util.function.Consumer;

/**
 * Consumer<T> 接口 : 表示消费者接口,所以不需要返回值
 *
 * accept(T t) 用于执行消费操作

 */
public class _04_JdkOwn {
	public static void main(String[] args) {
		String message = "嘻嘻嘻嘻嘻嘻嘻嘻寻学习";

		consumeResult(x -> System.out.println(x), message);
	}

	public static void consumeResult(Consumer<String> function, String message) {
		function.accept(message);
	}
}

2.5.3 Function

Function<T,R> 接口 表示接收一个参数,并产生一个结果

R apply(T t) 方法

package com.demo._FunInterface;

import java.util.function.Function;

/**
 * Function<T,R> 接口 表示接收一个参数,并产生一个结果
 * 
 * R apply(T t) 方法
 * 
 
 */
public class _05_JdkOwn {
	public static void main(String[] args) {
		int num = convertType(x->Integer.parseInt(x), "123");
		System.out.println(num);
		
		Function<String, Integer> xx = x->Integer.parseInt(x);
		int num1 =xx.apply("123");
	}

	// 把字符串转换为数字
	public static int convertType(Function<String, Integer> function, String str) {
		int num = function.apply(str);
		return num;
	}
}

2.5.4 Predicate

Predicate 接口 断言接口,就是做一些判断

booean test(T) 用于做校验比较操作

package com.demo._FunInterface;

import java.util.function.Predicate;

/**
 * Predicate<T> 接口 断言接口,就是做一些判断
 * 
 * booean test(T) 用于做校验比较操作
 * 
 */
public class _06_JdkOwn {

	public static boolean call(Predicate<String> predicate, String message) {
		return predicate.test(message);
	}

	public static void main(String[] args) {
		String message = "ok";
		boolean result = call(x -> {
			return x.equals("ok");
		}, message);
		System.out.println(result);
	}
}

3. 方法、构造器、数组

3.1 概述

Lambda表达式的另一种表示形式,提高复用率和灵活性

3.2 特点

更简单,代码量更少,复用性和扩展性更高

3.3 方法引用

方法引用的三种形式

当要传递给Lambda体的操作,已经有实现的方法了,可以使用方法引用!
方法引用可以看做是Lambda表达式深层次的表达。换句话说,方法引用就是Lambda表达式,也就是函数式接口的一个实例,通过方法的名字来指向一个方法,可以认为是Lambda表达式的一个语法糖。
要求:实现接口的抽象方法的参数列表和返回值类型,必须与方法引用的方法的参数列表和返回值类型保持一致!
格式:使用操作符“::” 将类(或对象) 与方法名分隔开来。
如下三种主要使用情况:
对象::实例方法名
类::静态方法名
类::实例方法名

在这里插入图片描述
在这里插入图片描述
3.3.1 对象引用:: 实例方法名

package com.demo._FunCall;

import java.util.function.Supplier;

/**
 * 对象的引用::实例方法
 * 
 */
public class _01_FunCall {
	public static void main(String[] args) {
		Integer i1 = new Integer(12356);
		
		// 常规lambda表达式
		Supplier<String> su = () -> i1.toString();
		System.out.println(su.get());
		
		// 方法引用的写法
		Supplier<String> su1 = i1::toString;
		System.out.println(su1.get());
		
	}
}

3.3.2 类名::静态方法名

package com.demo._FunCall;

import java.util.function.BiFunction;

/**
 * 类名::静态方法名
 */
public class _02_FunCall {
	public static void main(String[] args) {
		// 常规的lambda写法
		// 前两个是 参数类型,第三个是返回值类型
		BiFunction<Integer, Integer, Integer> bif = (x,y) -> Integer.max(x, y);
		int apply = bif.apply(10, 11);
		System.out.println(apply);
		
		// 方法引用的写法
		BiFunction<Integer, Integer, Integer> bif1 = Integer::max;
		int apply1 = bif1.apply(19, 2);
		System.out.println(apply1);
	}
}

3.3.3 类名::实例方法名

package com.demo._FunCall;

import java.util.function.BiPredicate;

/**
 * 类名::实例方法

 */
public class _03_FunCall {
	public static void main(String[] args) {
		// 传统的lambda写法
		BiPredicate<String, String> predicate = (x,y) -> x.equals(y);
		System.out.println(predicate.test("a", "c"));
		
		// 方法引用写法
		BiPredicate<String, String> predicate1 = String::equals;
		System.out.println(predicate1.test("a", "a"));
	}
}

3.4 构造器引用

格式:ClassName::new
与函数式接口相结合,自动与函数式接口中方法兼容。
可以把构造器引用赋值给定义的方法,要求构造器参数列表要与接口中抽象方法的参数列表一致!且方法的返回值即为构造器对应类的对象。
在这里插入图片描述

package com.demo._FunCall;

import java.util.function.Function;
import java.util.function.Supplier;

/**
 * 构造器调用
 * 
 */
public class _04_ConstructorCall {
	public static void main(String[] args) {
		// 无参构造器
		// 常规的lambda写法
		Supplier<Object> objSup = ()-> new Object();
		System.out.println(objSup.get());
		
		// 方法引用
		Supplier<Object> objSup1 = Object::new;
		System.out.println(objSup1.get());
		
		// 有参构造器
		// 常规的lambda写法
		Function<String, Integer> func = (x)-> new Integer(x);
		System.out.println(func.apply("123"));
		
		// 方法引用写法
		Function<String, Integer> func1 = Integer::new;
		System.out.println(func1.apply("54"));
	}
}

3.5 数组引用

在这里插入图片描述

package com.demo._FunCall;

import java.util.function.Function;

public class _05_ArrayCall {
	public static void main(String[] args) {
		// lambda写法
		// 需求 : 定义一个Integer类型的数组,长度为n
		Function<Integer, Integer[]> fun = n -> new Integer[n];
		Integer[] arr = fun.apply(10);
		System.out.println(arr.length);

		// 数组引用写法
		Function<Integer, Integer[]> fun1 = Integer[]::new;
		Integer[] arr1 = fun1.apply(2);
		System.out.println(arr1.length);
		
		
		int a = 1;
		int b = 2;
		System.out.println(b);
		System.out.println(a);
	}
}

4. StramAPI

4.1 概述

Java8中有两大最为重要的改变。第一个是Lambda 表达式;另外一个则是Stream API。
Stream API ( java.util.stream)把真正的函数式编程风格引入到Java中。这是目前为止对Java类库最好的补充,因为Stream API可以极大提供Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。
Stream 是Java8 中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。使用Stream API 对集合数据进行操作,就类似于使用SQL 执行的数据库查询。也可以使用Stream API 来并行执行操作。简言之,Stream API 提供了一种高效且易于使用的处理数据的方式。

就是用来处理集合、数组的API,集合讲的是数据,而流是计算

注意:
①Stream 自己不会存储元素。
②Stream 不会改变源对象。相反,他们会返回一个持有结果的新Stream。
③Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行。

4.2 运行机制

Stream分为源source , 中间操作,终止操作

1-创建Stream
一个数据源(如:集合、数组),获取一个流

2-中间操作
一个中间操作链,对数据源的数据进行处理
一个流可以有0~N个中间操作,每一个中间操作都会返回一个新的流,方便下一个操作使用
一个流只能有一个终止操作
中间操作也称为转换算子-transformation

3-终止操作(终端操作)
一旦执行终止操作,就执行中间操作链,并产生结果。之后,不会再被使用
Stream只有遇到终止操作,它对策数据源才会开始执行遍历等操作
终止操作也称为动作算子
因为动作算子的返回值不再是Stream,所以这个计算就终止
只有碰到动作算子的时候,才会真正的计算
在这里插入图片描述

4.3 创建Stream的五种方式

package com.demo._Stream;

import java.util.Arrays;
import java.util.List;
import java.util.stream.IntStream;
import java.util.stream.Stream;

/**
 * 创建流的五种方式
 * 
 
 */
public class _01_Stream {
	public static void main(String[] args) {
		// 1 通过数组 Stream.of
		String[] strings = { "a", "b", "c", "d" };
		Stream<String> stream1 = Stream.of(strings);

		// 2 通过集合
		List<String> strings2 = Arrays.asList(strings);
		Stream<String> stream2 = strings2.stream();

		// 3 通过Stream.generate 方法来创建
		// 这是一个无限流,无限大,通过这种方式创建的流,在操作的时候,最好使用limit进行最大数量限制
		// generate的参数是 Supplier 只有一个get方法,是无参有返回值的
		// get方法的返回值,作为整个集合中的数据,下面这个等于都赋值为1
		Stream<Integer> generate = Stream.generate(() -> 1);
		// 可以通过limit限制最多元素个数
		generate.limit(5).forEach(x -> System.out.println(x));
		
		// 4 通过Stream.iterate 方法来创建
		// 这是一个无限流,无限大,通过这种方式创建的流,在操作的时候,最好使用limit进行最大数量限制
		// 第一个参数是起始值,第二个参数是UnaryOperator  继承了Function  所以 有参有返回值
		// 1 就是起始值, x+2 就是步长,类似于一个死循环,起始值是1,步长 是2,终止条件是true
		Stream<Integer> iterate = Stream.iterate(1, x->x+2);
		iterate.limit(5).forEach(x->System.out.println(x));
		
		// 5 已有类的Stream源生成API
		String str = "abc";
		IntStream chars = str.chars();
		chars.forEach(x->System.out.println(x));
	}
}

4.4 常用的中间操作-转换算子

4.4.1 概述

一个中间操作链,对数据源的数据进行处理
一个流可以有0~N个中间操作,每一个中间操作都会返回一个新的流,方便下一个操作使用
一个流只能有一个终止操作
中间操作也称为转换算子-transformation

4.4.2 常用的转换算子

常用的转换算子

filter , distinct , map , limit , skip , flatMap等

filter : 对元素进行过滤,不符合条件的,就不要了

distinct : 去掉重复

skip : 跳过多少个元素

limit : 取一个集合中的前几条数据

map : 可以理解为是在遍历集合的过程中,对元素进行操作
比如进行判断,集合元素是否大于4 ,返回值为boolean类型
或者对集合元素进行更改,比如每个元素都自身+1

flatMap : 解决一个字符串数组,返回单一的字符串使用flatMap

注意 只有此算子是不会真正进行计算的,只有调用动作算子,才会真正计算

4.4.3 常见异常

在这里插入图片描述
Stream 使用之后,必须重新生成新的Stream,不能使用原来的stream
可以链式调用,是因为转换 算子的返回值都是一个新的Stream,而这个新的Stream还没有操作过 ,所以可以链式调用
但是原来的stream就不能再使用了,否则报错

4.4.4 使用方式

package com.demo._Stream;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 常用的转换 算子
 * 
 * filter , distinct , map , limit , skip , flatMap等
 * 
 * filter : 对元素进行过滤,不符合条件的,就不要了
 * 
 * distinct : 去掉重复
 * 
 * skip : 跳过多少个元素
 * 
 * limit : 取一个集合中的前几条数据
 * 
 * map : 可以理解为是在遍历集合的过程中,对元素进行操作 比如进行判断,集合元素是否大于4 ,返回值为boolean类型
 * 或者对集合元素进行更改,比如每个元素都自身+1
 * 
 * flatMap : 解决一个字符串数组,返回单一的字符串使用flatMap
 * 
 * 注意 只有此算子是不会真正进行计算的,只有调用动作算子,才会真正计算
 * 

 */
public class _02_Stream {
	public static void main(String[] args) {
		String[] arr = { "a", "b", "c", "a" };
		List<String> strings = Arrays.asList(arr);
		// 流对象
		Stream<String> stream = strings.stream();
		/**
		 * filter : 对元素进行过滤,不符合条件的,就不要了
		 * 
		 * collect : 动作算子,把符合条件的转换为集合
		 */
		// 只要a
		// x -> x.equals("a") 返回值为false,filter就会删除该元素
		List<String> value = stream.filter(x -> x.equals("a")).collect(
				Collectors.toList());
		System.out.println(value);
		// stream使用后 必须重新生成
		// stream.filter(x -> x.equals("a")).collect(Collectors.toList());

		// 重新生成流
		stream = strings.stream();
		/**
		 * skip : 跳过n个元素,比如原来是abca 跳过1个 就是bca
		 */
		value = stream.skip(1).collect(Collectors.toList());
		// bca
		System.out.println(value);

		/**
		 * map : 可以理解为是在遍历集合的过程中,对元素进行操作 比如进行判断,集合元素是否大于4 ,返回值为boolean类型
		 * 或者对集合元素进行更改,比如每个元素都自身+1
		 */
		// 重新生成流
		stream = strings.stream();
		// 如果元素是a就返回true,否则就返回false,把返回结果形成一个新的集合
		List<Boolean> value1 = stream.map(x -> x.equals("a")).collect(
				Collectors.toList());
		// [true, false, false, true]
		System.out.println(value1);
		// 重新生成流
		stream = strings.stream();
		// 更改集合元素
		value = stream.map(x -> x + "---").collect(Collectors.toList());
		// [a---, b---, c---, a---]
		System.out.println(value);

		/**
		 * distinct : 去重
		 */
		// 重新生成流
		stream = strings.stream();
		value = stream.distinct().collect(Collectors.toList());
		// [a, b, c]
		System.out.println(value);

		/**
		 * limit : 取集合中前几条数据
		 */
		// 重新生成流
		stream = strings.stream();
		value = stream.limit(2).collect(Collectors.toList());
		// [a, b]
		System.out.println(value);

		/**
		 * flatMap : 解决一个字符串数组,返回单一的字符串使用flatMap
		 */
		// 重新生成流
		String[] arr1 = {"1,2,3","a,b,c"};
		strings = Arrays.asList(arr1);
		// 现在集合中有两个数据,分别是 "1,2,3"  和 "a,b,c"
		// 把数组中每一个元素都拿出来,分别以 , 逗号分割,形成两个字符串数组
		// 最终通过 collect 合并到一起, 得到 1,2,3,a,b,c 6个元素
		stream = strings.stream();
		value = stream.map(x->x.split(",")).flatMap(array->Arrays.stream(array)).collect(Collectors.toList());
		// [1, 2, 3, a, b, c]
		System.out.println(value);
	}
}

4.5 常用的终止操作-动作算子

4.5.1 概述

一旦执行终止操作,就执行中间操作链,并产生结果。之后,不会再被使用
Stream只有遇到终止操作,它对策数据源才会开始执行遍历等操作
终止操作也称为动作算子
因为动作算子的返回值不再是Stream,所以这个计算就终止
只有碰到动作算子的时候,才会真正的计算

4.5.2 常用动作算子

常用的动作算子 :

forEach : 循环

计算 : min,max,count,average

匹配 : anyMatch,allMatch,noneMatch,findFirst,findAny

汇聚 : reduce

收集器 : collect

4.5.3 使用方式

package com.demo._Stream;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 常用的动作算子 :
 * 
 * 	forEach : 循环
 * 
 * 计算 : min,max,count,average
 * 
 * 匹配 : anyMatch,allMatch,noneMatch,findFirst,findAny
 * 
 * 汇聚 : reduce
 * 
 * 收集器 : collect

 */
public class _03_Stream {
	public static void main(String[] args) {
		String[] arr = {"a","b","c"}; 
		List<String> strings = Arrays.asList(arr);
		Stream<String> stream = strings.stream();
		
		// 测试forEach
		stream.filter(x->x.equals("a")).forEach(x->System.out.println(x));
		
		// 测试 count
		
		stream= strings.stream();
		// 获取多少个数据
		// 如果 只想获取条数,可以调用集合的 size方法,更简单
		// 只是有动作算子价值不大,一般和转换算子一起使用,才能体现优势
		long count = stream.count();
		System.out.println(count);
		
		// 比如 统计 有几个a
		stream= strings.stream();
		count=stream.filter(x->x.equals("a")).count();
		System.out.println(count);
		
		// collect收集器
		// 把结果手机组织成集合
		stream= strings.stream();
		List<String> list = stream.map(x->x+"==").collect(Collectors.toList());
		// [a==, b==, c==]
		System.out.println(list);
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值