Java中的Stream是一种用于处理集合数据的抽象概念。它提供了一种流式操作的方式,可以对集合中的元素进行过滤、映射、排序、聚合等操作,使得代码更加简洁和易读。
在Java中,可以通过集合流和数组流来创建Stream对象。集合流是通过集合类的stream()方法创建的,数组流是通过Arrays类的stream()方法创建的。
它有以下特性:
1.stream不存储数据 2.stream不改变源数据 3.stream的延迟执行特性
以下是两种创建Stream对象的例子:
- 集合流:
List<String> list = new ArrayList<>();
Stream<String> stream = list.stream();
2. 数组流:
String[] array = new String[]{"a", "b", "c"};
Stream<String> stream = Arrays.stream(array);
创建了Stream对象后,可以对其进行各种操作,例如过滤、映射、排序、聚合等。这些操作可以通过Stream类提供的方法来实现,例如filter()、map()、sorted()、reduce()等。
请注意,Stream操作通常是惰性求值的,只有在终止操作(例如forEach()、collect())被调用时才会执行。这种延迟执行的特性可以提高性能和效率。
Stream是对集合的包装,通常和lambda一起使用。 使用lambdas可以支持许多操作,如 map, filter, limit, sorted, count, min, max, sum, collect 等等。 Stream使用懒运算,他们并不会真正地读取所有数据,遇到像getFirst() 这样的方法就会结束链式语法。
示例:
public class Person {
private String firstName, lastName, job, gender;
private int salary, age;
public Person(String firstName, String lastName, String job,
String gender, int age, int salary) {
this.firstName = firstName;
this.lastName = lastName;
this.gender = gender;
this.age = age;
this.job = job;
this.salary = salary;
}
// Alt+ Insert -- Getter and Setter
List<Person> javaProgrammers = new ArrayList<Person>() {
{
add(new Person("Tom", "Brittany", "Java programmer", "female", 23, 1500));
add(new Person("Fran", "Donny", "Java programmer", "male", 33, 1800));
add(new Person("Cindy", "Jonie", "Java programmer", "female", 32, 1600));
add(new Person("Vacy", "Hervey", "Java programmer", "male", 22, 1200));
add(new Person("Mark", "Jaimie", "Java programmer", "female", 27, 1900));
add(new Person("Shawn", "Randall", "Java programmer", "male", 30, 2300));
add(new Person("Jayden", "Corrina", "Java programmer", "female", 35, 1700));
add(new Person("Palmert", "Dene", "Java programmer", "male", 33, 2000));
add(new Person("Addili", "Pam", "Java programmer", "female", 34, 1300));
}
};
(1) 使用forEach方法:
//使用forEach方法来迭代输出上述列表:
javaProgrammers.forEach((p) -> System.out.printf("%s %s; ", p.getFirstName(), p.getLastName()));
//使用forEach方法,增加程序员的工资5%:
Consumer<Person> giveRaise = e -> e.setSalary(e.getSalary() / 100 * 5 + e.getSalary());
javaProgrammers.forEach(giveRaise);
(2)使用过滤器filter() 方法:
System.out.println("下面是月薪超过 $1,800 的PHP程序员:")
javaProgrammers.stream()
.filter((p) -> (p.getSalary() > 1800))
.forEach((p) -> System.out.printf("%s %s; ", p.getFirstName(), p.getLastName()));
(3)使用limit方法:
System.out.println("最前面的3个Java programmers:");
javaProgrammers.stream()
.limit(3)
.forEach((p) -> System.out.printf("%s %s; ", p.getFirstName(), p.getLastName()));
(4)使用sorted方法:
System.out.println("根据 name 排序,并显示前5个 Java programmers:");
List<Person> sortedJavaProgrammers = javaProgrammers
.stream()
.sorted((p, p2) -> (p.getFirstName().compareTo(p2.getFirstName())))
.limit(5)
.collect(toList());
// 使用sorted按名字进行自定义排序,并用limit筛选前5个
(5)使用min/max方法:
System.out.println("工资最低的 Java programmer:");
Person pers = javaProgrammers
.stream()
.min((p1, p2) -> (p1.getSalary() - p2.getSalary()))
.get()
System.out.printf("Name: %s %s; Salary: $%,d.", pers.getFirstName(), pers.getLastName(), pers.getSalary())
(6)使用collect方法:
System.out.println("将 javaprogrammers 的 first name 拼接成字符串:");
String javaDevelopers = javaDevFirstName
.stream()
.map(Person::getFirstName)
.collect(joining(" ; ")); // 在进一步的操作中可以作为标记(token)
System.out.println("将 Java programmers 的 first name 存放到 Set:");
Set<String> javaDevFirstName = javaProgrammers
.stream()
.map(Person::getFirstName)
.collect(toSet());
System.out.println("将 Java programmers 的 last name 存放到 TreeSet:");
TreeSet<String> javaDevLastName = javaProgrammers
.stream()
.map(Person::getLastName)
.collect(toCollection(TreeSet::new));
//或者收集为一个map
Map<Integer, String> map = per.stream().collect(Collectors.toMap(e -> e.age, e -> e.name));
List<WebElementFacade> List = locator.resolveAllFor(actor);
list.stream().filter(WebElementFacade::isVisible).collect(Collectors.toList());
(7)使用map方法:
List<Interger> numList = Arrays.asList(1,2,3,4,5,6,7,8);
List<String> strList = numList.stream()
.map(it -> Interger.toString(it))
.collect(Collectors.toList());
map 和 flatmap的区别:
map只是一维 1对1 的映射,而flatmap可以将一个两层集合映射成一层,相当于他映射的深度比map深了一层 ,所以名称上就把map加了个flat 叫flatmap。
map:转换流,将一种类型的流转换为另外一种流。
flapMap:拆解流,将流中每一个元素拆解成一个流,最后合并流,也就是说flatMap方法最终会把所有返回的stream合并。flapMap不做示例。