赞
踩
Stream流是JDK8中提供的一种新特性
Stream流的使用步骤:
获取方式 | 方法名 | 说明 |
---|---|---|
单例集合 | default Stream<E> stream() | Collection中的默认方法 |
双列集合 | 无 | 无法直接使用stream流 |
数组 | public static <T> Stream<T> stream(T[] array) | Arrays工具类中的静态方法 |
零散数据 | public static<T> Stream<T>of(T… values) | Stream接口中的静态方法,需要同种数据类型 |
单列集合获取Stream流
//集合的批量添加
List<String> list = new ArrayList<String>(){
{
add("张无忌");
add("周芷若");
add("赵敏");
add("张三丰");
add("张翠山");
add("王二麻子");
add("谢广坤");
add("马超");
add("张良");
}
};
// 获取stream流并打印
list.stream().forEach(s -> System.out.println(s));
双列集合获取Stream流
Map<Integer,String> map = new HashMap<Integer,String>(){
{
put(1,"张无忌");
put(2,"周芷若");
put(3,"赵敏");
}
};
// 直接获取map中的key
map.keySet().stream().forEach(k -> System.out.println(k));
// 获取map中的value
map.values().stream().forEach(v -> System.out.println(v));
// 获取键值对
map.entrySet().stream().forEach(e-> System.out.println(e));
数组获取Stream流
String[] str = {"张无忌","周芷若","赵敏","张三丰","张翠山","王二麻子","谢广坤","马超","张良"};
// 数组转集合
List<String> collect = Arrays.stream(str).collect(Collectors.toList());
System.out.println(collect);
零散数据获取Stream流
前提零散数据类型是一样的
Stream.of("张无忌","周芷若","赵敏","张三丰","张翠山","王二麻子","谢广坤","马超","张良").forEach(s -> System.out.println(s));
名称 | 说明 |
---|---|
Stream<T> filter(Predicate<? super T> predicate) | 过滤 |
Stream<T> limit(long maxSize) | 获取前几个元素 |
Stream<T> skip(long n) | 跳过前几个元素 |
Stream<T> distinct() | 元素去重,依赖(hashCode和equals方法) |
static <T> Stream<T> concat(Stream a, Stream b) | 合并a和b两个流为一个流 |
Stream<R> map(Function<T, R> mapper) | 转换流中的数据类型 |
filter方法
该方法返回true表示保留该数据,false表示过滤掉该数据
public static void main(String[] args) {
//集合的批量添加
List<String> list = new ArrayList<String>() {
{
add("张无忌");
add("周芷若");
add("赵敏");
add("张三丰");
add("张翠山");
add("王二麻子");
add("谢广坤");
add("马超");
add("张良");
}
};
// s表示集合里的每一条数据
list.stream().filter(new Predicate<String>() {
@Override
public boolean test(String s) {
return false;
}
});
// 打印以张开头的前两条数据
list.stream().filter(s -> s.startsWith("张")).limit(2).forEach(s -> System.out.println(s));
}
concat方法
concat方法是Stream的静态方法,作用是将两个Stream流合并成一个,注意如果两个流的数据类型不一致就会将类型提示为他们共同的父类。
//集合的批量添加
List<String> list = new ArrayList<String>() {
{
add("张无忌");
add("周芷若");
add("赵敏");
add("张三丰");
add("张翠山");
add("王二麻子");
add("谢广坤");
add("马超");
add("张良");
}
};
Stream.concat(list.stream(),list.stream()).forEach(s -> System.out.println(s));
map方法
打印每个人的年龄
public static void main(String[] args) {
//集合的批量添加
List<String> list = new ArrayList<String>() {
{
add("张无忌-22");
add("周芷若-20");
add("赵敏-20");
add("张三丰-70");
add("张翠山-50");
add("王二麻子-20");
add("谢广坤-44");
add("马超-35");
add("张良-30");
}
};
// 匿名内部类写法
list.stream().map(new Function<String, Integer>() {
@Override
public Integer apply(String s) {
String[] split = s.split("-");
int ret = Integer.parseInt(split[1]);
return ret;
}
}).forEach(s->System.out.println(s));
// lambda写法,在forEach中s已经编程整形
list.stream().map(s->Integer.parseInt(s.split("-")[1])).forEach(s->System.out.println(s));
}
}
名称 | 说明 |
---|---|
void forEach(Consumer action) | 遍历 |
long count() | 统计 |
toArray() | 收集流中的数据放到数组中 |
collect(Collector collertor) | 收集流中的数据,放到集合中 |
toArray()方法
public static void main(String[] args) {
//集合的批量添加
List<String> list = new ArrayList<String>() {
{
add("张无忌");
add("周芷若");
add("赵敏");
add("张三丰");
add("张翠山");
add("王二麻子");
add("谢广坤");
add("马超");
add("张良");
}
};
// 匿名内部类写法
String[] array = list.stream().toArray(new IntFunction<String[]>() {
/**
*
* @param value 数组的容量
* @return
*/
@Override
public String[] apply(int value) {
return new String[value];
}
});
System.out.println(Arrays.toString(array));
// lambda写法
String[] array1 = list.stream().toArray(value -> new String[value]);
System.out.println(Arrays.toString(array1));
}
collect方法
收集为List或者Set是比价简单的
public static void main(String[] args) {
//集合的批量添加
List<String> list = new ArrayList<String>() {
{
add("张无忌-男-22");
add("周芷若-女-20");
add("赵敏-女-20");
add("张三丰-男-66");
add("张翠山-男-55");
add("谢广坤-男-35");
add("马超-男-30");
add("张良-男-29");
}
};
// 将所有男性收集到一个List中
List<String> ret = list.stream().filter(s -> "男".equals(s.split("-")[1])).collect(Collectors.toList());
// 将素所有女性收集到一个Set中
Set<String> set = list.stream().filter(s -> "女".equals(s.split("-")[1])).collect(Collectors.toSet());
System.out.println(ret);
System.out.println(set);
}
来看一下收集到Map里,将姓名和年龄形成一个键值对。
注意:使用toMap收集流中的数据时,key是不能重复的,否则会抛出异常
public static void main(String[] args) {
//集合的批量添加
List<String> list = new ArrayList<String>() {
{
add("张无忌-男-22");
add("周芷若-女-20");
add("赵敏-女-20");
add("张三丰-男-66");
add("张翠山-男-55");
add("谢广坤-男-35");
add("马超-男-30");
add("张良-男-29");
}
};
// 匿名内部类写法
/**
* toMap的第一个函数接口参数:
* 泛型参数:key: 表示流的数据类型
* 泛型参数 value: 表示要转换Map的key的数据类型
* toMap的第二个函数接口参数:
* 泛型参数:key: 表示流的数据类型
* 泛型参数 value: 表示要转换Map的value的数据类型
*/
Map<String,Integer> map1 = list.stream().collect(Collectors.toMap(
new Function<String, String>() {
/**
* 该方法的参数就是流中的元素
* 该方法的返回值就是Map的key
* @param s the function argument
* @return
*/
@Override
public String apply(String s) {
return s.split("-")[0];
}
},
new Function<String, Integer>() {
/**
* 该方法的参数就是流中的元素
* 该方法的返回值就是Map的value
* @param s the function argument
* @return
*/
@Override
public Integer apply(String s) {
return Integer.parseInt(s.split("-")[2]);
}
}));
// lambda写法
Map<String ,Integer> map2 = list.stream().collect(Collectors.toMap(s -> s.split("-")[0],s->Integer.parseInt(s.split("-")[2])));
System.out.println(map1);
System.out.println(map2);
}
方法引用就是把已经有的方法拿过来用,当做函数式接口中抽象方法的方法体
使用方法引用需要注意以下4点:
举个例子,我们要对一个数组进行降序排序。
public static void main(String[] args) {
Integer[] arr = {1,6,8,3,4,6,7,5,2,9};
// 使用匿名内部类
Arrays.sort(arr, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2-o1;
}
});
// 使用lambda表达式
Arrays.sort(arr, (o1, o2) -> o2-o1);
System.out.println(Arrays.toString(arr));
}
我们可以通过方法引用的方式来进行
Arrays.sort的第二个参数比较规则,是函数式接口满足要求,其余3点也满足就可以使用方法引用。
public static void main(String[] args) {
Integer[] arr = {1,6,8,3,4,6,7,5,2,9};
// 使用方法引用
Arrays.sort(arr, Main::cmp);
System.out.println(Arrays.toString(arr));
}
public static int cmp(int a,int b){
return b-a;
}
::
是一个方法引用符号
类名::静态方法
Integer::parseInt
比如将一组字符串数组转换成整形数字,直接将Integer的静态方法拿过来用即可
public static void main(String[] args) {
List<String> list = new ArrayList<String>(){
{
add("1");
add("2");
add("3");
add("4");
add("5");
}
};
// 匿名内部类写法
List<Integer> ret1 = list.stream().map(new Function<String, Integer>() {
@Override
public Integer apply(String s) {
return Integer.parseInt(s);
}
}).collect(Collectors.toList());
System.out.println(ret1);
// 使用方法引用写法
List<Integer> ret2 = list.stream().map(Integer::parseInt).collect(Collectors.toList());
System.out.println( ret2);
}
对象::成员方法
其他对象::方法名
this::方法名
(引用处不能是静态方法)super::方法名
(引用处不能是静态方法)需求:打印性张且名字长度为3个字人
调用其他类的成员方法
class Test{
public boolean filter(String s) {
return s.startsWith("张") && s.length() == 3;
}
}
public class Main {
public static void main(String[] args) {
//集合的批量添加
List<String> list = new ArrayList<String>() {
{
add("张无忌");
add("周芷若");
add("赵敏");
add("张三丰");
add("张翠山");
add("谢广坤");
add("马超");
add("张良");
}
};
// 匿名内部类写法
list.stream().filter(new Predicate<String>() {
@Override
public boolean test(String s) {
return s.startsWith("张") && s.length() == 3;
}
}).forEach(s -> System.out.println(s));
// 方法引用,引用其他类方法
Test test = new Test();
list.stream().filter(test::filter).forEach(s -> System.out.println(s));
}
}
引用本类的成员方法
需求:打印性张且名字长度为3个字人
public class Main {
public boolean filter(String s) {
return s.startsWith("张") && s.length() == 3;
}
public void main(String[] args) {
//集合的批量添加
List<String> list = new ArrayList<String>() {
{
add("张无忌");
add("周芷若");
add("赵敏");
add("张三丰");
add("张翠山");
add("谢广坤");
add("马超");
add("张良");
}
};
// 方法引用,引用本类类方法
list.stream().filter(new Main()::filter).forEach(s -> System.out.println(s));
}
}
引用父类的成员方法
class Test {
public boolean filter(String s) {
return s.startsWith("张") && s.length() == 3;
}
}
public class Main extends Test {
public boolean filter(String s) {
return s.startsWith("张") && s.length() == 3;
}
public void func() {
//集合的批量添加
List<String> list = new ArrayList<String>() {
{
add("张无忌");
add("周芷若");
add("赵敏");
add("张三丰");
add("张翠山");
add("谢广坤");
add("马超");
add("张良");
}
};
// 方法引用,引用父类方法
list.stream().filter(super::filter).forEach(System.out::println);
}
}
类名::new
需求:将字符串张三-22
构成User对象
class User {
String username;
int age;
public User(String username, int age) {
this.username = username;
this.age = age;
}
public User(String str) {
String[] split = str.split("-");
this.username = split[0];
this.age = Integer.parseInt(split[1]);
}
@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", age=" + age +
'}';
}
}
public class Main {
public boolean filter(String s) {
return s.startsWith("张") && s.length() == 3;
}
public static void main(String[] args) {
//集合的批量添加
List<String> list = new ArrayList<String>() {
{
add("张无忌-22");
add("周芷若-20");
add("赵敏-20");
add("张三丰-60");
add("张翠山-35");
}
};
// 匿名内部类写法
List<User> userList1 = list.stream().map(new Function<String, User>() {
@Override
public User apply(String str) {
String[] split = str.split("-");
return new User(split[0], Integer.parseInt(split[1]));
}
}).collect(Collectors.toList());
System.out.println(userList1);
// 使用构造方法引用写法,拿User类的构造方法作为参数
List<User> userList2 = list.stream().map(User::new).collect(Collectors.toList());
System.out.println(userList2);
}
}
类名::成员方法
String::toUpperCase
这种通过类名引用成员方法的方式有点特别,需要遵循以下规则,
方法引用的规则:
抽象方法形参注意事项:
需求:将一堆字符串都转换成大写
public static void main(String[] args) {
List<String> stringList = Arrays.asList("aa","bb","cc","dd");
// 匿名内部类写法
List<String> ret1 = stringList.stream().map(new Function<String, String>() {
@Override
public String apply(String s) {
return s.toUpperCase();
}
}).collect(Collectors.toList());
System.out.println(ret1);
// 方法引用写法
List<String> ret2 = stringList.stream().map(String::toUpperCase).collect(Collectors.toList());
System.out.println(ret2);
}
public String toUpperCase() {
return toUpperCase(Locale.getDefault());
}
局限性:
数据类型[]:new
int[]::new
需求将List中的数据放到一个新数组中
public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>(){
{
add(1);
add(2);
add(3);
add(4);
add(5);
}
};
// 匿名内部类写法
Integer[] array = list.stream().toArray(new IntFunction<Integer[]>() {
@Override
public Integer[] apply(int value) {
return new Integer[value];
}
});
System.out.println(Arrays.toString(array));
// 方法引用写法
Integer[] array2 = list.stream().toArray(Integer[]::new);
System.out.println(Arrays.toString(array2));
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。