Java 8 新特性(三)Stream API

目录

一、Stream API

生成流

1、filter

2、forEach

3、map

4、limit

5、sorted

6、anyMatch,allMatch,noneMatch

7、distinct

二、Collectors

1、toList

2、toSet

3、toMap

4、joining

5、groupingBy

练习案例:

案例1:

案例2:使用List流排序

案例3:使用set流排序

案例4:使用Map流排序


一、Stream API

Java 8 API添加了一个新的抽象称为流Stream,可以让你以一种声明的方式处理数据。 

这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。

元素流在管道中经过中间操作(intermediate operation)的处理,最后由最终操作(terminal operation)得到前面处理的结果。

生成流

在 Java 8 中, 集合接口有两个方法来生成流:

  • stream() − 为集合创建串行流

  • parallelStream() − 为集合创建并行流

List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
List<String> filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());

操作集合的方法 :Collection.stream(); 会返回一个Stream对象,通过这个Stream对象,以流的方式操作集合中的元素 

1、filter

Stream filter(Predicate<? super T> predicate); 

对集合中的元素进行过滤,返回包含符合条件的元素流

List<String>strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
// 获取空字符串的数量
long count = strings.stream().filter(string -> string.isEmpty()).count();

2、forEach

void forEach(Consumer<? super T> action);

遍历集合中的元素

【注意】:在forEach中想达成 continue 的效果是直接使用 return;

【原因】:" ()-> " 方式其实是匿名内部类,在匿名内部类里面return了也仅仅是匿名内部类的调用终止;for循环继续下一次循环而已。匿名内部类当然不能使用break和continue啦(没理解记得多读几遍)

List<String>strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");

strings.stream().forEach(string -> System.out.println(string));
strings.stream().forEach(System.out::println);//是上面的简写方式

3、map

Stream map(Function<? super T, ? extends R> mapper);

map 方法用于对集合内对象进行操作,映射每个元素到对应的结果

List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
// 获取对应的平方数
List<Integer> squaresList = numbers.stream().map( i -> i*i).distinct().collect(Collectors.toList());

案例:先对集合中元素进行操作,再对集合中年龄大于27岁的进行过滤,并遍历集合

		List<Person> persons = new ArrayList<Person>(){
			{//匿名类初始化参数
				add(new Person("marvin", 18));
				add(new Person("jerry", 31));
				add(new Person("sally", 30));
				add(new Person("max", 27));
				add(new Person("jason", 32));

			}
		};

		persons.stream()
				//年龄大于27岁的对象返回,其他的设置为null
				.map(e ->{
					if(e.getAge()>27){
						return e;
					}
					return null;
				})
				//过滤掉null的数据
				.filter(e -> e!=null)
				//将流转换为list集合
				.collect(Collectors.toList())
				//遍历集合中的对象
				.forEach(System.out::println);

4、limit

Stream limit(long maxSize);

limit 方法用于获取指定数量的流,返回参数maxSize所指定的个数的元素

//以下代码片段使用 limit 方法打印出随机 10 条数据
Random random = new Random();
random.ints().limit(10).forEach(System.out::println);
//获取前三个
List<String> s = Arrays.asList("1","2","3","4","5","6");
s.stream().limit(3).forEach(System.out::println);

5、sorted

Stream sorted();

sorted 方法用于对流中的元素自然排序

Stream sorted(Comparator<? super T> comparator);

根据参数指定的比较规则,对集合中元素排序

List<String> s = Arrays.asList("6","5","3","1","2","1");
s.stream().sorted().forEach(System.out::println);

案例:将集合中对象以年龄倒序排序 

List<Person> persons = new ArrayList<Person>(){
			{//匿名类初始化参数
				add(new Person("marvin", 18));
				add(new Person("jerry", 31));
				add(new Person("sally", 30));
				add(new Person("max", 27));
				add(new Person("jason", 32));

			}
		};
		persons.stream().sorted(Comparator.comparing(Person::getAge).reversed()).forEach(System.out::println);

6、anyMatch,allMatch,noneMatch

用于判断集合中所有的数据数据,返回true、false

anyMatch:判断的条件里,任意一个元素成功,返回true

allMatch:判断条件里的元素,所有的都是,返回true

noneMatch:与allMatch相反,判断条件里的元素,所有的都不是,返回true

public static void main(String[] args) {

    List<Integer> list = Arrays.asList(1, 2, 1, 1, 1);
    
    boolean anyMatch = list.stream().anyMatch(f -> f == (1));
    boolean allMatch = list.stream().allMatch(f -> f == (1));
    boolean noneMatch = list.stream().noneMatch(f -> f == (1));
    
    System.out.println(anyMatch);  // true
    System.out.println(allMatch);  // false
    System.out.println(noneMatch); // false
}

7、distinct

Stream<T> distinct();

用于去重:使用 hashCode() 和 equals() 方法来获取不同的元素。因此,我们的类必须实现hashCode()和equals()方法。如果distinct()正在处理有序流,那么对于重复元素,将保留以遭遇顺序首先出现的元素,并且以这种方式选择不同元素是稳定的。在无序流的情况下,不同元素的选择不一定是稳定的

public static void main(String[] args) {
    List<String> list = Arrays.asList("AA", "BB", "CC", "BB", "CC", "AA", "AA");
    long count = list.stream().distinct().count();
    System.out.println("count:"+ count);
    String output = list.stream().distinct().collect(Collectors.joining(","));
    System.out.println(output);
}
//返回内容如下
//count:3
//AA,BB,CC 

二、Collectors

Collectors 类实现了很多归约操作,例如将流转换成集合和聚合元素。Collectors 可用于返回列表或字符串:

List<String>strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
List<String> filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());
System.out.println("筛选列表: " + filtered);

String mergedString = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.joining(", "));
System.out.println("合并字符串: " + mergedString);

1、toList

数据返回为list集合

List<Person> persons = new ArrayList<Person>(){
			{//匿名类初始化参数
				add(new Person("marvin", 18, "男", "后端"));
				add(new Person("jerry", 31, "男", "前端"));
				add(new Person("sally", 30, "女", "后端"));
				add(new Person("max", 27, "男", "前端"));
				add(new Person("jason", 32, "男", "后端"));

			}
		};
		
// 数据过滤并转list
List<Person> toList = persons.stream().filter(e->"后端".equals(e.getType())).collect(Collectors.toList());
System.out.println("转list:" + toList);

转list:
[
    Person [name=marvin, age=18, sex=男, type=后端], 
    Person [name=sally, age=30, sex=女, type=后端], 
    Person [name=jason, age=32, sex=男, type=后端]
]

2、toSet

数据返回为set集合

List<Person> persons = new ArrayList<Person>(){
			{//匿名类初始化参数
				add(new Person("marvin", 18, "男", "后端"));
				add(new Person("jerry", 31, "男", "前端"));
				add(new Person("sally", 30, "女", "后端"));
				add(new Person("max", 27, "男", "前端"));
				add(new Person("jason", 32, "男", "后端"));

			}
		};
		
// 转set
Set<Person> toSet = persons.stream().collect(Collectors.toSet());
System.out.println("转set:" + toSet);

3、toMap

数据返回为Map集合

返回结果为Map:key,value 自己定义

List<Person> persons = new ArrayList<Person>(){
			{//匿名类初始化参数
				add(new Person("marvin", 18, "男", "后端"));
				add(new Person("jerry", 31, "男", "前端"));
				add(new Person("sally", 30, "女", "后端"));
				add(new Person("max", 27, "男", "前端"));
				add(new Person("jason", 32, "男", "后端"));

			}
		};

// 转map集合		
Map<String, Person> toMap = persons.stream().collect(Collectors.toMap(Person::getName, Person -> Person));
System.out.println("转map:" + toMap);

转map:
{
    marvin=Person [name=marvin, age=18, sex=男, type=后端], 
    max=Person [name=max, age=27, sex=男, type=前端], 
    jason=Person [name=jason, age=32, sex=男, type=后端], 
    sally=Person [name=sally, age=30, sex=女, type=后端], 
    jerry=Person [name=jerry, age=31, sex=男, type=前端]
}

4、joining

数据合并返回

List<Person> persons = new ArrayList<Person>(){
			{//匿名类初始化参数
				add(new Person("marvin", 18, "男", "后端"));
				add(new Person("jerry", 31, "男", "前端"));
				add(new Person("sally", 30, "女", "后端"));
				add(new Person("max", 27, "男", "前端"));
				add(new Person("jason", 32, "男", "后端"));

			}
		};

// 合并字符串	
String s = persons.stream().map(Person::getName).collect(Collectors.joining(","));
System.out.println("合并字符串:" + s);

 合并字符串:marvin,jerry,sally,max,jason

5、groupingBy

数据进行分组

返回结果为Map:key=分组的条件,value=分组的结果

List<Person> persons = new ArrayList<Person>(){
			{//匿名类初始化参数
				add(new Person("marvin", 18, "男", "后端"));
				add(new Person("jerry", 31, "男", "前端"));
				add(new Person("sally", 30, "女", "后端"));
				add(new Person("max", 27, "男", "前端"));
				add(new Person("jason", 32, "男", "后端"));

			}
		};

// 通过性别和类型进行分组(返回map)
Map<String, List<Person>> groups = persons.stream().collect(Collectors.groupingBy(e->e.getSex() + "_" + e.getType()));
System.out.println("分组-通过性别和类型进行:" + groups);

分组-通过性别和类型进行:
{
    女_后端=[Person [name=sally, age=30, sex=女, type=后端]], 
    男_后端=[Person [name=marvin, age=18, sex=男, type=后端], 
                    Person [name=jason, age=32, sex=男, type=后端]], 
    男_前端=[Person [name=jerry, age=31, sex=男, type=前端], 
                    Person [name=max, age=27, sex=男, type=前端]]
}

练习案例:

案例1:

对persons集合过滤,过滤条件为姓名字符串的长度大于3,接着按照姓名排序,再把集合中前三个Person对象的信息打印出来

	public static void main(String[] args) {
		List<Person> persons = new ArrayList<Person>(){
			{//匿名类初始化参数
				add(new Person("marvin", 18));
				add(new Person("jerry", 31));
				add(new Person("sally", 30));
				add(new Person("max", 27));
				add(new Person("jason", 32));
				
			}
		};
		
		persons.stream().filter(p->p.getName().length()>3)//姓名字符串长度大于3
		.sorted((p1,p2)->(p1.getName().compareTo(p2.getName())))
		.limit(3)//取出 三个元素
		.forEach(p->System.out.println(p.getName()+":"+p.getAge()));
	}

案例2:使用List流排序

package com.stream.demo;
 
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
 
public class StreamListDemo {
	public static void main(String[] args) {
		List<Student> list = new ArrayList<>();
		list.add(new Student(1, "Mahesh", 12));
		list.add(new Student(2, "Suresh", 15));
		list.add(new Student(3, "Nilesh", 10));
 
		System.out.println("---Natural Sorting by Name---");
		List<Student> slist = list.stream().sorted().collect(Collectors.toList());
		slist.forEach(e -> System.out.println("Id:" + e.getId() + ", Name: " + e.getName() + ", Age:" + e.getAge()));
 
		System.out.println("---Natural Sorting by Name in reverse order---");
		slist = list.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());
		slist.forEach(e -> System.out.println("Id:" + e.getId() + ", Name: " + e.getName() + ", Age:" + e.getAge()));
 
		System.out.println("---Sorting using Comparator by Age---");
		slist = list.stream().sorted(Comparator.comparing(Student::getAge)).collect(Collectors.toList());
		slist.forEach(e -> System.out.println("Id:" + e.getId() + ", Name: " + e.getName() + ", Age:" + e.getAge()));
 
		System.out.println("---Sorting using Comparator by Age with reverse order---");
		slist = list.stream().sorted(Comparator.comparing(Student::getAge).reversed()).collect(Collectors.toList());
		slist.forEach(e -> System.out.println("Id:" + e.getId() + ", Name: " + e.getName() + ", Age:" + e.getAge()));
	}
}
package com.stream.demo;
 
public class Student implements Comparable<Student> {
	private int id;
	private String name;
	private int age;
 
	public Student(int id, String name, int age) {
		this.id = id;
		this.name = name;
		this.age = age;
	}
 
	public int getId() {
		return id;
	}
 
	public String getName() {
		return name;
	}
 
	public int getAge() {
		return age;
	}
 
	@Override
	public int compareTo(Student ob) {
		return name.compareTo(ob.getName());
	}
 
	@Override
	public boolean equals(final Object obj) {
		if (obj == null) {
			return false;
		}
		final Student std = (Student) obj;
		if (this == std) {
			return true;
		} else {
			return (this.name.equals(std.name) && (this.age == std.age));
		}
	}
 
	@Override
	public int hashCode() {
		int hashno = 7;
		hashno = 13 * hashno + (name == null ? 0 : name.hashCode());
		return hashno;
	}
}

执行结果

---Natural Sorting by Name---
Id:1, Name: Mahesh, Age:12
Id:3, Name: Nilesh, Age:10
Id:2, Name: Suresh, Age:15
---Natural Sorting by Name in reverse order---
Id:2, Name: Suresh, Age:15
Id:3, Name: Nilesh, Age:10
Id:1, Name: Mahesh, Age:12
---Sorting using Comparator by Age---
Id:3, Name: Nilesh, Age:10
Id:1, Name: Mahesh, Age:12
Id:2, Name: Suresh, Age:15
---Sorting using Comparator by Age with reverse order---
Id:2, Name: Suresh, Age:15
Id:1, Name: Mahesh, Age:12
Id:3, Name: Nilesh, Age:10

案例3:使用set流排序


package com.stream.demo;
 
import java.util.Comparator;
import java.util.HashSet;
import java.util.Set;
 
public class StreamSetDemo {
	public static void main(String[] args) {
		Set<Student> set = new HashSet<>();
		set.add(new Student(1, "Mahesh", 12));
		set.add(new Student(2, "Suresh", 15));
		set.add(new Student(3, "Nilesh", 10));
 
		System.out.println("---Natural Sorting by Name---");
		System.out.println("---Natural Sorting by Name---");
		set.stream().sorted().forEach(e -> System.out.println("Id:"
						+ e.getId() + ", Name: " + e.getName() + ", Age:" + e.getAge()));
 
		System.out.println("---Natural Sorting by Name in reverse order---");
		set.stream().sorted(Comparator.reverseOrder()).forEach(e -> System.out.println("Id:"
						+ e.getId() + ", Name: " + e.getName() + ", Age:" + e.getAge()));
 
		System.out.println("---Sorting using Comparator by Age---");
		set.stream().sorted(Comparator.comparing(Student::getAge))
						.forEach(e -> System.out.println("Id:" + e.getId() + ", Name: " + e.getName() + ", Age:" + e.getAge()));
 
		System.out.println("---Sorting using Comparator by Age in reverse order---");
		set.stream().sorted(Comparator.comparing(Student::getAge).reversed())
						.forEach(e -> System.out.println("Id:" + e.getId() + ", Name: " + e.getName() + ", Age:" + e.getAge()));
	}
}

案例4:使用Map流排序

package com.stream.demo;
 
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
 
public class StreamMapDemo {
	public static void main(String[] args) {
		Map<Integer, String> map = new HashMap<>();
		map.put(15, "Mahesh");
		map.put(10, "Suresh");
		map.put(30, "Nilesh");
 
		System.out.println("---Sort by Map Value---");
		map.entrySet().stream().sorted(Comparator.comparing(Map.Entry::getValue))
						.forEach(e -> System.out.println("Key: "+ e.getKey() +", Value: "+ e.getValue()));
 
		System.out.println("---Sort by Map Key---");System.out.println("---Sort by Map Key---");
		map.entrySet().stream().sorted(Comparator.comparing(Map.Entry::getKey))
						.forEach(e -> System.out.println("Key: "+ e.getKey() +", Value: "+ e.getValue()));
	}
}
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值