Java 8 是一个非常成功的版本,这个版本新增的Stream,配合同版本出现的 Lambda ,给我们操作集合(Collection)提供了极大的便利。
那么什么是Stream?
Stream将要处理的元素集合看作一种流,在流的过程中,借助Stream API对流中的元素进行操作,比如:筛选、排序、聚合等。
list.stream() //转换成流进行操作
stream的操作符可以分为两种:中间操作符和终止操作符
/**
* 用于过滤不满足条件的元素
*/
@Test
public void filter(){
List<String> list = Arrays.asList("abc","sd","as","few","wth","dfg");
List<String> filtered = list.stream().filter(str -> str.contains("a")).collect(Collectors.toList());
System.out.println(filtered);
}
/**
* 用于去掉重复的元素
*/
@Test
public void distinct(){
List<String> list = Arrays.asList("abc","sd","as","few","wth","dfg","as");
List<String> distincted = list.stream().distinct().collect(Collectors.toList());
System.out.println(distincted);
}
/**
* 用于获取前n个元素
*/
@Test
public void limit(){
List<String> list = Arrays.asList("abc","sd","as","few","wth","dfg","as");
List<String> limited = list.stream().limit(3).collect(Collectors.toList());
System.out.println(limited);
}
/**
* 用于获取除前n个元素以外的所有元素
*/
@Test
public void skip(){
List<String> list = Arrays.asList("abc","sd","as","few","wth","dfg","as");
List<String> skiped = list.stream().skip(3).collect(Collectors.toList());
System.out.println(skiped);
}
/**
* 用于对所有元素进行集体的操作
*/
@Test
public void map(){
List<String> list = Arrays.asList("abc","sd","as","few","wth","dfg","as");
List<String> mapped = list.stream().map(str->"han Shen_"+str).collect(Collectors.toList());
System.out.println(mapped);
}
/**
* 用于对所有元素进行扁平化的操作
*/
@Test
public void flatMap(){
List<String> list = Arrays.asList("abc","sd","as","few","wth","dfg","as");
List<Character> flatMaped = list.stream().flatMap(str -> javaStream.getCharacter(str)).collect(Collectors.toList());
System.out.println(flatMaped);
}
//创建了一个字符流转换的方法
public static Stream<Character> getCharacter(String str){
ArrayList<Character> list = new ArrayList<>();
for (Character character : str.toCharArray()) {
list.add(character);
}
return list.stream();
}
/**
* 用于对所有元素进行以a到z顺序进行排序
*/
@Test
public void sorted(){
//---------------------------字母排序-------------------------------------
List<String> list = Arrays.asList("abc","sd","as","few","wth","dfg","as");
List<String> sorted = list.stream().sorted().collect(Collectors.toList());//正序
List<String> collect1 = list.stream().sorted(Collections.reverseOrder(Collator.getInstance(Locale.US))).collect(Collectors.toList());
System.out.println(sorted);
System.out.println(collect1);
//---------------------------汉字排序-------------------------------------
List<String> list3 = Arrays.asList("吕布","刘备","阿斗","赵云","张辽","马超","法正");
List<String> sorted1 = list3.stream().sorted(Collator.getInstance(Locale.CHINA)).collect(Collectors.toList());//正序
List<String> collect2 = list3.stream().sorted(Collections.reverseOrder(Collator.getInstance(Locale.CHINA))).collect(Collectors.toList());
System.out.println(sorted1);
System.out.println(collect2);
//---------------------------数字排序-------------------------------------
List<Integer> list1 = Arrays.asList(1,5,9,54,33,-52,54);
List<Integer> collect = list1.stream().sorted().collect(Collectors.toList());//正序
Stream<Integer> sorted2 = list1.stream().sorted(Collections.reverseOrder());//反序
System.out.println(collect);
sorted2.forEach(s-> System.out.print(s+","));
}
/**
* 用于判断集合中是否有一个元素满足条件
*/
@Test
public void anyMatch(){
List<String> list = Arrays.asList("abc","sd","as","few","wth","dfg","as");
boolean a = list.stream().anyMatch(s -> s.contains("a"));
System.out.println(a);
}
/**
* 用于判断集合中是否所有元素都满足条件
*/
@Test
public void allMatch(){
List<String> list = Arrays.asList("abc","sd","as","few","wth","dfg","as");
boolean a = list.stream().allMatch(s -> s.contains("a"));
System.out.println(a);
}
/**
* 用于判断集合中是否所有元素都不满足条件
*/
@Test
public void noneMatch(){
List<String> list = Arrays.asList("abc","sd","as","few","wth","dfg","as");
boolean a = list.stream().noneMatch(s -> s.length()>4);
System.out.println(a);
}
/**
* 用于返回集合中的任意元素
*/
@Test
public void findAny(){
List<String> list = Arrays.asList("abc","sd","as","few","wth","dfg","as");
for (int i=0;i<1000;i++){
Optional<String> any = list.parallelStream().findAny();
if (any.isPresent()) System.out.println(any.get());
}
}
/**
* 用于返回集合中的第一个元素
*/
@Test
public void findFirst(){
List<String> list = Arrays.asList("abc","sd","as","few","wth","dfg","as");
Optional<String> first = list.stream().findFirst();
if (first.isPresent()) System.out.println(first.get());
}
/**
* 用于循环
*/
@Test
public void forEach(){
List<String> list = Arrays.asList("abc","sd","as","few","wth","dfg","as");
list.stream().forEach(s -> System.out.println(s));
}
/**
* 用于将流转换成其他类型的数据:list,map,set
*/
@Test
public void collect(){
List<String> list = Arrays.asList("abc","sd","as","few","wth","dfg","as");
Set<String> collect = list.stream().collect(Collectors.toSet());
System.out.println(collect);
//-------------------------------------------------------------------
Map<String, Object> collect1 = list.stream().collect(Collectors.toMap(v -> "han_" + v, v -> v,(oldvalue, newvalue)->newvalue));
System.out.println(collect1);
}
/**
* 将流中的元素反复的结合起来得到一个结果
*/
@Test
public void reduce(){
List<String> list = Arrays.asList("abc","sd","as","few","wth","dfg","as");
Optional<String> reduce = list.stream().reduce((acc,item) -> {return (acc+item).replace("s","h");});
if(reduce.isPresent()) System.out.println(reduce.get());
}
/**
* 获取集合中元素的数量
*/
@Test
public void count(){
List<String> list = Arrays.asList("abc","sd","as","few","wth","dfg","as");
long count = list.stream().count();
System.out.println(count);
}
/*拼接*/
public static void join(){
List<User> list = users();
String names = list.stream()
.map(User::getName)
.collect(Collectors.joining(", "));
System.out.println(names);
}
/*一次性得到元素的个数、总和、最大值、最小值*/
public static void allVlaue(){
List<User> list = users();
IntSummaryStatistics statistics = list.stream()
.collect(Collectors.summarizingInt(User::getAge));
System.out.println(statistics);
}
/*分组*/
public static void group(){
Map<Integer, List<User>> map = users().stream()
.collect(Collectors.groupingBy(User::getSex));
System.out.println(new Gson().toJson(map));
System.out.println();
Map<Integer, Map<Integer,List<User>>> map2 = users().stream()
.collect(Collectors.groupingBy(User::getSex,
Collectors.groupingBy(User::getAge)));
System.out.println(new Gson().toJson(map2));
}
/*分组合计*/
public static void groupCount(){
Map<Integer, Long> num = users().stream()
.collect(Collectors.groupingBy(User::getSex, Collectors.counting()));
System.out.println(num);
Map<Integer, Long> num2 = users().stream()
.filter(user -> user.getAge()>=18)
.collect(Collectors.groupingBy(User::getSex, Collectors.counting()));
System.out.println(num2);
}
/*分区*/
public static void partitioningBy(){
List<User> list = users();
Map<Boolean, List<User>> part = list.stream()
.collect(Collectors.partitioningBy(user -> user.getAge() <= 30));
System.out.println(new Gson().toJson(part));
}
public static void max_min(){
List<User> list = users();
Optional<User> max = list.stream()
.collect(
Collectors.maxBy(
Comparator.comparing(User::getAge)
)
);
Optional<User> min = list.stream()
.collect(
Collectors.minBy(
Comparator.comparing(User::getAge)
)
);
System.out.println("max--> " + max+" min--> "+ min);
}
/*求和_平均值*/
public static void sum_avg(){
List<User>list = users();
int totalAge = list.stream()
.collect(Collectors.summingInt(User::getAge));
System.out.println("totalAge--> "+ totalAge);
/*获得列表对象金额, 使用reduce聚合函数,实现累加器*/
BigDecimal totalMpney = list.stream()
.map(User::getMoney)
.reduce(BigDecimal.ZERO, BigDecimal::add);
System.out.println("totalMpney--> " + totalMpney);
double avgAge = list.stream()
.collect(Collectors.averagingInt(User::getAge));
System.out.println("avgAge--> " + avgAge);
}
重要
1.isPresent();
为了判断查询的类对象是否存在,采用此方法
.isPresent()一般与.get()方法合用,当optional中存在course时,optional.isPresent()值为true,通过get()方法返回对象。
2.IntStream是存的是int类型的stream,而Steam是一个存了Integer的stream。boxed的作用就是将int类型的stream转成了Integer类型的Stream。
比如下面这段代码就是很好理解了:
List<Integer> numbers = Arrays.asList(1, 2, 3, 3, 4, 5);
IntStream intStream = numbers.stream().mapToInt(i -> i); //转成IntStream
Stream<Integer> boxed = intStream.boxed(); //转成Stream
所以我们在用到这种原始int值的流,比如下面生成随机数的,得到IntStream在转成集合是不行的。会报错。
random.ints(0, 100).limit(10).collect(Collectors.toList());
所以我们一定要把它转成。Integer类型,像下面这种使用boxed转成了object类型
random.ints(0, 100).limit(10).boxed().collect(Collectors.toList());