在传统J2EE的应用中,java代码经常不得不依赖于关系型数据库的聚合操作来完成诸如:
这类的操作。而在java集合API中,仅仅有极少量的辅助型方法,更多的时候需要用Iterator来遍历集合,完成相关的聚合应用逻辑。
获取数组最大值
public static void main(String[] args) {
int[] nums={1,2,3,4,5,6,7};
int max = Arrays.stream(nums).max().getAsInt();
System.out.println(max);
}
Stream不是集合元素,不是数据结构并不保存数据,是有关算法和计算的,类似于一个高版本的Iterator。我们只需要给出需要对其包含的元素执行什么操作,Stream就会隐式地在内部进行遍历,做出相应的数据转换。
Stream如同一个迭代器,单向,不可往复,数据只能遍历一次,遍历一次后即用尽了。
Stream可以并行化操作,迭代器只能命令式地、串行化操作。
Stream的一大特点就是数据源本身可以是无限的。
分为三个基本步骤
获取一个数据源——数据转化——执行操作获取先要的结构
每次转换原有的Stream对象不改变,返回一个新的Stream对象(可以有多次转化),这就允许对其操作可以向链条一样排列,变成一个管道
有多种方式生成Stream Source:
public static void main(String[] args) {
// 1. Individual values
Stream stream = Stream.of("a", "b", "c");
// 2. Arrays
String [] strArray = new String[] {"a", "B", "c"};
stream = Stream.of(strArray);
stream = Arrays.stream(strArray);
// 3. Collections
List<String> list = Arrays.asList(strArray);
stream = list.stream();
}
IntStream.of(new int[]{1, 2, 3}).forEach(System.out::println);
IntStream.range(1, 3).forEach(System.out::println);
IntStream.rangeClosed(1, 3).forEach(System.out::println);
// 1. Array
String[] strArray1 = stream.toArray(String[]::new);
// 2. Collection
List<String> list1 = stream.collect(Collectors.toList());
List<String> list2 = stream.collect(Collectors.toCollection(ArrayList::new));
Set set1 = stream.collect(Collectors.toSet());
Stack stack1 = stream.collect(Collectors.toCollection(Stack::new));
// 3. String
String str = stream.collect(Collectors.joining()).toString();
方法 | 描述 |
---|---|
filter(Predicate p) | 接收Lambda表达式,从流中排除某些元素 |
distinct() | 筛选,通过流所生成元素的hashCode()和equals()去除重复元素 |
limit(long maxSize) | 截断流,使其元素不能超过给定数量 |
skip(long n) | 跳过元素,返回一个扔掉了前n个元素的流。若流中的元素不足n个,则返回一个空流与limit(n)互补 |
public class Employee implements Serializable {
private String name;
private Integer age;
private Double salary;
}
protected List<Employee> list = Arrays.asList(
new Employee("张三", 18, 9999.99),
new Employee("李四", 38, 5555.55),
new Employee("王五", 60, 6666.66),
new Employee("赵六", 8, 7777.77),
new Employee("田七", 58, 3333.33)
);
主要是接收Lambda表达式,从流中排除某些元素
//内部迭代:在此过程中没有进行过迭代,由Stream api进行迭代
//中间操作:不会执行任何操作
Stream<Person> stream = list.stream().filter((e) -> {
System.out.println("Stream API 中间操作");
return e.getAge() > 30;
});
主要作用为:截断流,使其元素不超过给定数量
//过滤之后取2个值
list.stream().filter((e) -> e.getAge() >30 ).limit(2).forEach(System.out :: println);
在其中我们可以配合其他的中间操作,并截断流,使我们可以取得相应个数的元素。
跳过元素,返回一个扔掉了前n个元素的流。若流中元素不足n个,则返回一个空流。与limit(n)互补
//跳过前2个值
list.stream().skip(2).forEach(System.out :: println);
筛选,通过流所生成元素的hashCode和equals()去除重复元素
list.stream().distinct().forEach(System.out :: println);
distict需要在实体中重写hashCode和equal方法才能使用
方法 | 描述 |
---|---|
map(Function f) | 接收一个函数,该函数会被引用到每个元素上,并将其映射成一个新的元素 |
mapToDouble(ToDoubleFunction f) | 接收一个函数,该函数会被引用到每个元素上,产生一个新的DoubleStream |
mapToInt(ToIntFunction f) | 接收一个函数,该函数会被引用到每个元素上,产生一个新的IntStream |
mapToLong(ToLongFunction f) | 接收一个函数,该函数会被引用到每个元素上,产生一个新的LongStream |
flagMap(function f) | 接收一个函数,将流中的每个值都换成另一个流,然后把所有流,连接成一个流。 |
map() 方法
//将流中每一个元素都映射到map的函数中,每个元素执行这个函数,再返回
List<String> list = Arrays.asList("aaa", "bbb", "ccc", "ddd");
list.stream().map((e) -> e.toUpperCase()).forEach(System.out::printf);
//获取Person中的每一个人得名字name,再返回一个集合
List<String> names = this.list.stream().map(Person :: getName).collect(Collectors.toList());
flagMap()
/**
* flatMap —— 接收一个函数作为参数,将流中的每个值都换成一个流,然后把所有流连接成一个流
*/
@Test
public void testFlatMap () {
StreamAPI_Test s = new StreamAPI_Test();
List<String> list = Arrays.asList("aaa", "bbb", "ccc", "ddd");
list.stream().flatMap((e) -> s.filterCharacter(e)).forEach(System.out::println);
//如果使用map则需要这样写
list.stream().map((e) -> s.filterCharacter(e)).forEach((e) -> {
e.forEach(System.out::println);
});
}
/**
* 将一个字符串转换为流
*/
public Stream<Character> filterCharacter(String str){
List<Character> list = new ArrayList<>();
for (Character ch : str.toCharArray()) {
list.add(ch);
}
return list.stream();
}
其实map方法相当于Collection的add方法,如果add的是个集合的话会变为二维数组,而flatMap相当于Collection的addAll犯法
方法 | 描述 |
---|---|
sorted() | 产生一个新流,其按自然顺序排序 |
sort(Comparator comp) | 产生一个新流,其中按比较器书序排序 |
// 自然排序
List<Employee> persons = list.stream().sorted().collect(Collectors.toList());
//定制排序
List<Employee> persons1 = list.stream().sorted((e1, e2) -> {
if (e1.getAge() == e2.getAge()) {
return 0;
} else if (e1.getAge() > e2.getAge()) {
return 1;
} else {
return -1;
}
}).collect(Collectors.toList());