1.什么是stream流
1.Java 8 API添加了一个新的抽象称为流Stream,可以让你以一种声明的方式处理数据。 2.Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。 3.Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。 4.这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。 5.元素流在管道中经过中间操作(intermediate operation)的处理,最后由最终操作(terminal operation)得到前面处理的结果。
2.Stream流常用的操作案例
1.使用stream流的方式遍历
@Test
public void stream01() {
String str[] = {"北京", "上海", "深圳", "广州", "南京", "武汉", "重庆",};
List<String> strList = new ArrayList<>(Arrays.asList(str));
strList.stream().forEach(s-> System.out.println(s));
}
输出结果如下:
2.使用stream循环输根据下标输出元素
/**
* iterate指定一个常量seed,生成从seed到常量f(由UnaryOperator返回的值得到)的流
* stream循环输根据下标输出元素
*/
@Test
public void stream02(){
List<String> list = new ArrayList<>();
list.add("10");
list.add("20");
list.add("30");
list.add("40");
list.add("50");
Stream.iterate(0, i -> i + 1).limit(list.size()).forEach(i -> {
String s= list.get(i);
System.out.println("数组下标"+i+"|"+"数组元素"+s);
});
}
输出结果如下:
3.使用stream流将list数组按照某个属性分组
/**
*
* list中根据年龄分组
*/
@Test
public void stream03(){
List<Person> list = new ArrayList<>();
Person person1 = new Person(11,"张三","男","1835555555");
Person person2 = new Person(11,"李四","男","1835555555");
Person person3 = new Person(21,"王武","男","1835555555");
Person person4 = new Person(21,"赵刘","男","1835555555");
Person person5 = new Person(31,"小三","男","1835555555");
Person person6 = new Person(31,"小红","女","1835555555");
list.add(person1);
list.add(person2);
list.add(person3);
list.add(person4);
list.add(person5);
list.add(person6);
//按照年龄分组
Map<Integer, List<Person>> collect = list.stream().collect(Collectors.groupingBy(Person::getAge));
collect.forEach((k,v)->{
System.out.println("key=:"+k+" value=:"+v);
});
}
输出结果如下:
4.stream中map和flatMap的操作
/**
* list中map和flatMap的操作
* flatMap方法中需要传一个steam流
*/
@Test
public void stream04(){
List<Person> list = new ArrayList<>();
Person person1 = new Person(11,"张.三","男","1835555555");
Person person2 = new Person(11,"李.四","男","1835555555");
Person person3 = new Person(21,"王.武","男","1835555555");
Person person4 = new Person(21,"赵.刘","男","1835555555");
Person person5 = new Person(31,"小.三","男","1835555555");
Person person6 = new Person(31,"小.红","女","1835555555");
list.add(person1);
list.add(person2);
list.add(person3);
list.add(person4);
list.add(person5);
list.add(person6);
//list.stream().map(Person::getName)返回的是Stream<String>
List<String> names = list.stream().map(Person::getName).collect(Collectors.toList());
names.stream().forEach(n-> System.out.println("姓名:"+n));
//list.stream().map(Person::getName).map(n -> n.split("\\.")) 返回的是Stream<String[]>
Stream<String[]> stream = list.stream().map(Person::getName).map(n -> n.split("\\."));
//输出的名字是以数组的形式
stream.forEach(n-> System.out.println(Arrays.asList(n)));
//list.stream().map(Person::getName).flatMap(n -> Arrays.stream(n.split("\\."))) 返回的是Stream<String>
List<String> collect = list.stream().map(Person::getName).flatMap(n -> Arrays.stream(n.split("\\."))).collect(Collectors.toList());
//姓名扁平化的输出
collect.forEach(n-> System.out.println(n));
}
输出结果如下:
5.Stream 中的toMap
/**
* Stream 中的toMap
*/
@Test
public void stream05(){
List<Person> list = new ArrayList<>();
Person person1 = new Person(1,"张.三","男","1835555555");
Person person2 = new Person(2,"李.四","男","1835555555");
Person person3 = new Person(3,"王.武","男","1835555555");
Person person4 = new Person(4,"赵.刘","男","1835555555");
Person person5 = new Person(5,"小.三","男","1835555555");
Person person6 = new Person(6,"小.红","女","1835555555");
list.add(person1);
list.add(person2);
list.add(person3);
list.add(person4);
list.add(person5);
list.add(person6);
//toMap返回map<k,v> v是某个属性值 例如k为年龄 v为姓名
Map<Integer, String> collect = list.stream().collect(Collectors.toMap(Person::getAge, Person::getName));
collect.forEach((k,v)->{
System.out.println("年龄(k):"+k+" 姓名v:"+v);
});
System.out.println("\t");
//toMap返回map<k,v> v是某个属性值 例如k为年龄 v对象本身 有两种写法
Map<Integer, Person> collect1 = list.stream().collect(Collectors.toMap(Person::getAge, Person -> Person));
Map<Integer, Person> collect2 = list.stream().collect(Collectors.toMap(Person::getAge, Function.identity()));
//输出的k为年龄 v为对象本身 collect1和collect2结果一样
collect2.forEach((k,v)->{
System.out.println("年龄(k):"+k+" 对象v:"+v);
});
}
输出结果如下:
6.stream中filter用法
/**
* filter
*/
@Test
public void stream06(){
List<String>strings = Arrays.asList("我", "", "是", "", "一个","", "程序员");
System.out.println("过滤前");
strings.forEach(s-> System.out.println(s));
System.out.println("过滤后");
Stream<String> stringStream = strings.stream().filter(s -> !s.isEmpty());
stringStream.forEach(s-> System.out.println(s));
//根据对象某一个属性或多个属性进行过滤
List<Person> list = new ArrayList<>();
Person person1 = new Person(1,"张三","男","1835555555");
Person person2 = new Person(2,"李四","男","1835555555");
Person person3 = new Person(3,"王武","男","1835555555");
Person person4 = new Person(4,"赵刘","男","1835555555");
Person person5 = new Person(5,"小三","男","1835555555");
Person person6 = new Person(6,"小红","女","1835555555");
list.add(person1);
list.add(person2);
list.add(person3);
list.add(person4);
list.add(person5);
list.add(person6);
//输出小红
list.stream().filter(p -> p.getSex().equals("女")).forEach(s-> System.out.println("输出结果:"+s));
}
输出结果如下:
7.stream中findFirst用法
/**
* findFirst
*/
@Test
public void stream07(){
List<String> list = Arrays.asList("huawei", "iphone", "xiaomi", "zte","samsung");
//从list中获取第一个
Optional<String> first = list.stream().findFirst();
if(first.isPresent()){
System.out.println(first.get());
}
//从不等于某个字符串后的第一个
Optional<String> iphone = list.stream().filter(s -> !s.equals("huawei")).findFirst();
//输出iphone
if(iphone.isPresent()){
System.out.println(iphone.get());
}
}
输出结果如下:
8.stream中findAny用法
/**
* findAny 返回任何元素
*/
@Test
public void stream08(){
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
Optional<Integer> any = list.stream().findAny();
if(any.isPresent()){
System.out.println(any.get());
}
//输出不存在的元素
Optional<Integer> no = list.stream().filter(x->x>10).findAny();
if(no.isPresent()){
System.out.println(no.get());
}else{
System.out.println("没有大于10的元素存在");
}
}
输出结果如下:
9.stream中limit和skip用法
/**
* limit和skip
*/
@Test
public void stream09(){
List<String> list = Arrays.asList("huawei", "iphone", "xiaomi", "zte","samsung");
//limit 输出截取之前的
list.stream().limit(3).forEach(s-> System.out.println("limit输出结果:"+s));
//skip 跳过指定的元素数后输出 输出结果为 zte samsung
list.stream().skip(3).forEach(s-> System.out.println("skip输出结果:"+s));
}
输出结果如下:
10.stream中sorted 排序操作
/**
* sorted 排序操作
*/
@Test
public void stream10(){
List<Person> list = new ArrayList<>();
Person person1 = new Person(1,"张三","男","1835555555");
Person person2 = new Person(2,"李四","男","1835555555");
Person person3 = new Person(3,"王武","男","1835555555");
Person person4 = new Person(4,"赵刘","男","1835555555");
Person person5 = new Person(5,"小三","男","1835555555");
Person person6 = new Person(6,"小红","女","1835555555");
list.add(person1);
list.add(person2);
list.add(person3);
list.add(person4);
list.add(person5);
list.add(person6);
//默认操作是升序
list.stream().sorted(Comparator.comparing(Person::getAge)).forEach(s-> System.out.println("升序操作"+s));
System.out.println("\t");
//降序操作
list.stream().sorted(Comparator.comparing(Person::getAge,Comparator.reverseOrder())).forEach(s-> System.out.println("降序操作"+s));
}
输出结果如下:
11.stream中Min Max Average方法使用
/**
* Min Max Average方法使用
*/
@Test
public void stream11(){
List<Person> list = new ArrayList<>();
Person person1 = new Person(1,"张三","男","1835555555");
Person person2 = new Person(2,"李四","男","1835555555");
Person person3 = new Person(3,"王武","男","1835555555");
Person person4 = new Person(4,"赵刘","男","1835555555");
Person person5 = new Person(5,"小三","男","1835555555");
Person person6 = new Person(6,"小红","女","1835555555");
list.add(person1);
list.add(person2);
list.add(person3);
list.add(person4);
list.add(person5);
list.add(person6);
//最大值
Person person = list.stream().max(Comparator.comparing(Person::getAge)).orElse(null);
System.out.println("最大年龄的人:"+person);
//最小值
Person min = list.stream().min(Comparator.comparing(Person::getAge)).orElse(null);
System.out.println("最小年龄的人:"+min);
//平均值
DoubleStream doubleStream = list.stream().mapToDouble(Person::getAge);
OptionalDouble obj = doubleStream.average();
if(obj.isPresent()){
System.out.println("平均值:"+obj.getAsDouble());
}
输出结果如下:
12.stream中distinct方法使用去重
/**
* distinct方法使用去重
*/
@Test
public void stream12(){
List<String>strings = Arrays.asList("A", "A", "S", "S", "V","F", "G");
strings.stream().forEach(s-> System.out.println("去重前:"+s));
System.out.println("\t");
strings.stream().distinct().forEach(s-> System.out.println("去重后:"+s));
}
输出结果如下:
13. stream中Match方法使用
/**
* Match方法使用
* allMatch:Stream 中全部元素符合传入的 predicate,返回 true;
* anyMatch:Stream 中只要有一个元素符合传入的 predicate,返回 true;
* noneMatch:Stream 中没有一个元素符合传入的 predicate,返回 true.
*/
@Test
public void stream13(){
List<String>strings = Arrays.asList("A", "A", "S", "S", "V","F", "G");
System.out.println("allMatch:"+strings.stream().allMatch(s->s.equalsIgnoreCase("A")));
System.out.println("anyMatch:"+strings.stream().anyMatch(s->s.equalsIgnoreCase("A")));
System.out.println("noneMatch:"+strings.stream().noneMatch(s->s.equalsIgnoreCase("o")));
}
输出结果如下: