-
传统的方式过滤集合
// 以传统的方式过滤集合 List<String> list=new ArrayList<>(); list.add("张三"); list.add("张无忌"); list.add("赵六"); list.add("王五"); List<String> lista=new ArrayList<>(); for (String s : list) { if(s.startsWith("张")){ lista.add(s); } } List<String> listb=new ArrayList<>(); for (String s : lista) { if(s.length()==3){ listb.add(s); } } System.out.println(list); // [张三, 张无忌, 赵六, 王五] System.out.println(lista); // [张三, 张无忌] System.out.println(listb); // [张无忌]
-
Stream流对集合进行过滤
List<String> list=new ArrayList<>(); list.add("张三"); list.add("张无忌"); list.add("赵六"); list.add("王五"); // Stream流对集合进行过滤 list.stream().filter(name->name.startsWith("张")) .filter(name->name.length()==3) .forEach(name-> System.out.println(name)); // 张无忌 System.out.println(list); // [张三, 张无忌, 赵六, 王五]
获取流
-
所有的
Collection
集合都可以通过stream
默认方法获取流default Stream<E> stream() 返回一个序列 Stream与此集合作为其来源。
// 将集合转换为Stream流 List<String> list = new ArrayList<>(); Stream<String> streamList = list.stream(); HashSet<String> setHash = new HashSet<>(); Stream<String> streamSet = setHash.stream(); HashMap<String, String> map = new HashMap<>(); // 获取键存储到set集合中 Set<String> keySet = map.keySet(); Stream<String> streamMapKey = keySet.stream(); // 获取值存储到Collection集合中 Collection<String> values = map.values(); Stream<String> streamMapValues = values.stream(); // 获取键值对 Set<Map.Entry<String, String>> entrySet = map.entrySet(); Stream<Map.Entry<String, String>> streamMapEntry = entrySet.stream();
-
Stream
接口的静态方法of
可以获取数组对应的流static <T> Stream<T> of(T... values) 返回其元素是指定值的顺序排序流。
// 数组转换为Stream流 Stream<Integer> streamInteger = Stream.of(1, 2, 3, 5, 8); Integer[] arrInt={1,2,3,4}; Stream<Integer> streamInteger1 = Stream.of(arrInt); String[] arrStr={"hello","world"}; Stream<String> streamStr = Stream.of(arrStr);
常用方法
-
延迟方法:返回值类型依然是Stream接口自身类型的方法,支持链式调用。(除终结方法外均为延迟方法)
- filter方法,过滤剩下满足条件的元素组成新的流
Stream<T> filter(Predicate<? super T> predicate) 返回由与此给定谓词匹配的此流的元素组成的流。
Stream<String> stream1 = Stream.of("张三丰", "张无忌", "赵敏", "周芷若"); stream1.filter((item)->{ return item.startsWith("张"); }).forEach(item-> System.out.println(item)); // 张三丰,张无忌
- map方法(映射)
<R> Stream<R> map(Function<? super T,? extends R> mapper) 返回由给定函数应用于此流的元素的结果组成的流。
Stream<String> stream2 = Stream.of("1", "2", "3", "4"); stream2.map((item)->{ return Integer.parseInt(item)+1; }).forEach((item)->{ System.out.println(item); // 2,3,4,5 });
- limit方法,对流进行截取,只取前n个
Stream<T> limit(long maxSize) 返回由此流的元素组成的流,截短长度不能超过 maxSize 。
Stream<String> stream4 = Stream.of("hello", "world", "nihao", "wohao", "dajiahao"); stream4.limit(2).forEach((item)->{ System.out.println(item); // hello,world });
- skip方法,跳过前n个元素,获取新的流
Stream<T> skip(long n) 在丢弃流的第一个到n元素后,返回由该流的剩余元素组成的流。
Stream<Character> stream5 = Stream.of('a', 'b', 'c', 'd', 'e', 'f'); stream5.skip(4).forEach((item)->{ System.out.println(item); // e,f });
- coucat方法,两个流合并为一个流,属于静态方法
static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b) 创建一个懒惰连接的流,其元素是第一个流的所有元素,后跟第二个流的所有元素。
Stream<String> stream6 = Stream.of("hello"); Stream<String> stream7 = Stream.of("nihao"); Stream.concat(stream6,stream7).forEach((item)->{ System.out.println(item); });
-
终结方法:返回值类型不是Stream接口自身类型的方法,不支持链式调用。(count和forEach方法)
- forEach方法,用来遍历流中的数据
void forEach(Consumer<? super T> action) 对此流的每个元素执行操作。
Stream<String> stream = Stream.of("zhangsan", "wangwu", "lisi"); stream.forEach((item)->{ System.out.println(item); // zhangsan,wangwu,lisi });
- count方法,统计个数
long count() 返回此流中的元素数。
Stream<Integer> stream3 = Stream.of(1, 2, 3, 4, 5); long len=stream3.filter((item)->{ return item>3; }).count(); System.out.println(len); // 2
-
特点
- Stream属于管道流,只能被消费使用一次。
案例
-
public class Person { private String name; private int age; public Person() { } public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
ArrayList<String> listOne = new ArrayList<>(); listOne.add("欧阳飞雪"); listOne.add("土豆"); listOne.add("张无忌"); listOne.add("张君宝"); listOne.add("小熊"); listOne.add("好事多"); ArrayList<String> listTwo = new ArrayList<>(); listTwo.add("古力娜扎"); listTwo.add("狼牙"); listTwo.add("迪丽热巴"); listTwo.add("尼古拉斯凯奇"); listTwo.add("张官司"); listTwo.add("张无知"); listTwo.add("张天佑"); listTwo.add("张翠山"); // 只要第一个集合中长度等于3的前两个 Stream<String> listOneResult = listOne.stream().filter((item) -> { return item.length() == 3; }).limit(2); // 只要第二个集合中以张开头的,不要前两个 Stream<String> listTwoResult = listTwo.stream().filter((item) -> { return item.startsWith("张"); }).skip(2); // 将两个流合并,并用里面的每一个元素来创建一个Person对象,存储到新的流中 Stream.concat(listOneResult,listTwoResult).map((name)->{ return new Person(name,new Random().nextInt(100)); }).forEach(person -> { System.out.println(person); });