Java8 stream
java 8 API添加了一个新的抽象叫流Stream,可以用一种声明的方式处理数据。
stream是使用一种类似用sql从数据库查询数据的方式来提供对java集合运算的抽象,这种风格是将要处理的元素集合当做一种流,流在管道中传输,并且可以在流的管道的节点上进行筛选、排序、聚合等处理。
1.集合接口有两种方法生成流Stream
- stream():为集合创建串行流;
- parallelStream():为集合创建并行流;
List<Student> list = new ArrayList<Student>();
list.add(new Student(1, "zhangsan1", "beijing1"));
list.add(new Student(2, "zhangsan2", "beijing2"));
list.add(new Student(3, "zhangsan3", "beijing3"));
String str1 = list.stream().map(i -> i.getId()).collect(Collectors.toList()).toString();
String str2 = list.parallelStream().map(i -> i.getId()).collect(Collectors.toList()).toString();
System.out.println("result1:" + str2);
System.out.println("result2:" + str2);
2.forEach
- stream 提供了新的方法“forEach”来迭代流中的每个数据
List<Student> list = new ArrayList<Student>();
list.add(new Student(1, "zhangsan1", "beijing1"));
list.add(new Student(2, "zhangsan2", "beijing2"));
list.add(new Student(3, "zhangsan3", "beijing3"));
list.stream().forEach(item->{System.out.println("strudent="+item);});
3.map
map方法相当于映射每个元素到对应的结果,如下代码使用map映射除了元素对应的平方数:
List<Integer> numbers = Arrays.asList(1, 2, 4, 14, 13, 12, 23, 19, 32);
List<Integer> squareslist = numbers.stream().map(i -> i * i).distinct().collect(Collectors.toList());
4.filter
filter方法用于通过设置的条件进行过滤,如下使用filter方法过滤出空字符串:
List<String> strings = Arrays.asList("abc", "", "bcc", "defd", "", "jkd");
long count = strings.stream().filter(str -> str.isEmpty()).count();
5.limit
limit方法用于获取指定数量的流,如下代码使用limit方法打印5条数据:
Random random = new Random();
random.ints().limit(5).sorted().forEach(System.out::println);
6.sorted
sorted方法用于对流进行排序,如下代码对5个随机数进行排序打印:
Random random = new Random();
random.ints().limit(5).sorted().forEach(System.out::println);
7.parallel
parallelStream是流并行处理的方法,如下代码使用此方法过滤出空字符串;
List<String> strings = Arrays.asList("abc", "", "bcc", "defd", "", "jkd");
long count = strings.parallelStream().filter(str -> str.isEmpty()).count();
8.Collectors
collectors类实现了很多归约,用于返回列表和字符串:
List<String> strings = Arrays.asList("abc", "", "bcc", "defd", "", "jkd");
List<String> list = strings.stream().filter(str -> !str.isEmpty()).collect(Collectors.toList());
String joinString = strings.stream().filter(str -> !str.isEmpty()).collect(Collectors.joining(","));
9.完整实例
public class Java8Test {
public static void main(String[] args) {
System.err.println(" use java7:----------------------");
// 计算空字符串
List<String> strings = Arrays.asList("abc", "", "bcc", "defd", "", "jkd");
System.out.println("列表:" + strings);
long count = getCountEmptyStringsUsingJava7(strings);
System.out.println("空字符串的数量:" + count);
count = getCountLength3UsingJava7(strings);
System.out.println("字符串长度为3的数量:" + count);
// 删除空字符串
List<String> filtered = deleteEmptyStringsUsingJava7(strings);
System.out.println("刷选后的数组:" + filtered);
// 删除空字符串,并使用“,”号拼接起来
String mergedString = getMergedStringUsingJava7(strings, ",");
System.out.println("刷选后的拼接字符串是:" + mergedString);
List<Integer> numbers = Arrays.asList(1, 2, 4, 14, 13, 12, 23, 19, 32);
// 获取列表元素平方根
List<Integer> squaresList = getSquares(numbers);
System.out.println("平方数列表:" + squaresList);
System.out.println("列表的Max:" + getMax(numbers));
System.out.println("列表的Min:" + getMin(numbers));
System.out.println("列表的和:" + getSum(numbers));
System.out.println("列表的平均数:" + getAverage(numbers));
System.out.println("随机数:");
Random random = new Random();
for (int i = 0; i < 5; i++) {
System.out.println(random.nextInt());
}
System.err.println("use java8:-------------------------");
System.out.println("列表:" + strings);
count = strings.stream().filter(str -> str.isEmpty()).count();
System.out.println("空字符串的数量是:" + count);
count = strings.stream().filter(str -> str.length() == 3).count();
System.out.println("字符串长度为3的数量是:" + count);
List<String> list = strings.stream().filter(str -> !str.isEmpty()).collect(Collectors.toList());
System.out.println("筛选后的列表:" + list);
String joinString = strings.stream().filter(str -> !str.isEmpty()).collect(Collectors.joining(","));
System.out.println("筛选后的拼接字符串:" + joinString);
List<Integer> list2 = numbers.stream().map(i -> i * i).distinct().collect(Collectors.toList());
System.out.println("平方数列表:" + list2);
IntSummaryStatistics stats = numbers.stream().mapToInt((x) -> x).summaryStatistics();
System.out.println("max:" + stats.getMax());
System.out.println("min:" + stats.getMin());
System.out.println("sum:" + stats.getSum());
System.out.println("average:" + stats.getAverage());
System.out.println("随机数:");
random.ints().limit(5).sorted().forEach(System.out::println);
// 并行处理
count = strings.parallelStream().filter(str -> str.isEmpty()).count();
System.out.println("空字符串的数量是:" + count);
// 测试
List<Student> list3 = new ArrayList<Student>();
list3.add(new Student(1, "zhangsan1", "beijing1"));
list3.add(new Student(2, "zhangsan2", "beijing2"));
list3.add(new Student(3, "zhangsan3", "beijing3"));
String str1 = list3.stream().map(i -> i.getId()).collect(Collectors.toList()).toString();
String str2 = list3.parallelStream().map(i -> i.getId()).collect(Collectors.toList()).toString();
System.out.println("result1:" + str2);
System.out.println("result2:" + str2);
list3.stream().forEach(item->{
System.out.println("strudent="+item);
});
}
private static int getAverage(List<Integer> numbers) {
int average = getSum(numbers) / numbers.size();
return average;
}
private static int getSum(List<Integer> numbers) {
int sum = 0;
for (Integer integer : numbers) {
sum += integer;
}
return sum;
}
private static int getMin(List<Integer> numbers) {
int min = numbers.get(0);
for (int i = 1; i < numbers.size(); i++) {
if (min > numbers.get(i)) {
min = numbers.get(i);
}
}
return min;
}
private static int getMax(List<Integer> numbers) {
int max = numbers.get(0);
for (int i = 1; i < numbers.size(); i++) {
if (max < numbers.get(i)) {
max = numbers.get(i);
}
}
return max;
}
private static List<Integer> getSquares(List<Integer> numbers) {
List<Integer> squareList = new ArrayList<Integer>();
for (Integer nubmer : numbers) {
if (nubmer != null) {
Integer square = new Integer(nubmer.intValue() * nubmer.intValue());
squareList.add(square);
}
}
return squareList;
}
private static String getMergedStringUsingJava7(List<String> strings, String sperator) {
StringBuffer stringBuffer = new StringBuffer();
for (String str : strings) {
if (!str.isEmpty()) {
stringBuffer.append(str);
stringBuffer.append(sperator);
}
}
String stringBufferString = stringBuffer.toString();
String mergedString = stringBufferString.substring(0, stringBufferString.length() - 1);
return mergedString;
}
private static List<String> deleteEmptyStringsUsingJava7(List<String> strings) {
List<String> filtered = new ArrayList<String>();
for (String str : strings) {
if (!str.isEmpty()) {
filtered.add(str);
}
}
return filtered;
}
private static long getCountLength3UsingJava7(List<String> strings) {
int count = 0;
for (String str : strings) {
if (!str.isEmpty() && str.length() == 3) {
count++;
}
}
return count;
}
private static long getCountEmptyStringsUsingJava7(List<String> strings) {
int count = 0;
for (String str : strings) {
if (str.isEmpty()) {
count++;
}
}
return count;
}
}
运行结果:
10.Stream()和parallelStream()比较
一般方式和单管道方式耗时差不多,但是多管道方式效率比较高;
public class Java8Demo {
public static void main(String[] args) {
List<Integer>list=buildIntList();
//一般方式
long start = System.currentTimeMillis();
for (Integer integer : list) {
try {
TimeUnit.MILLISECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("一般方式耗时:"+(System.currentTimeMillis()-start)+"ms");
//单管道
start=System.currentTimeMillis();
list.stream().forEach(e->{
try {
TimeUnit.MILLISECONDS.sleep(1);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
});
System.out.println("单管道耗时:"+(System.currentTimeMillis()-start)+"ms");
//多管道
start=System.currentTimeMillis();
list.parallelStream().forEach(e->{
try {
TimeUnit.MILLISECONDS.sleep(1);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
});
System.out.println("duo管道耗时:"+(System.currentTimeMillis()-start)+"ms");
}
private static List<Integer> buildIntList() {
List<Integer>list=new ArrayList<Integer>();
for (int i = 0; i <60000; i++) {
list.add(i);
}
return Collections.unmodifiableList(list);
}
}
耗时:
11.Stream去除集合重复数据
去除list中重复的String
List unique = list.stream().distinct().collect(Collectors.toList());
去除List中重复的对象
public class Person {
private String id;
private String name;
private String sex;
<!--省略 get set-->
}
// 根据name去重
List<Person> unique = persons.stream().collect(
Collectors.collectingAndThen(
Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Person::getName))), ArrayList::new)
);
// 根据name,sex两个属性去重
List<Person> unique = persons.stream().collect(
Collectors. collectingAndThen(
Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(o -> o.getName() + ";" + o.getSex()))), ArrayList::new)
);
filter()过滤列表
List<Person> filterList = persons.stream().filter(p -> p.getSex().equals(1)).collect(Collectors.toList());
List转Map
从一个Person对象的List集合,取出id和name组成一个map集合
Map<String, String> collect = list.stream().collect(Collectors.toMap(p -> p.getId(), p -> p.getName()));
从 List 中取出某个属性的组成 list 集合
//1.提取出list对象中的一个属性
List<String> stIdList1 = stuList.stream().map(Person::getId).collect(Collectors.toList());
//2.提取出list对象中的一个属性并去重
List<String> stIdList2 = stuList.stream().map(Person::getId).distinct().collect(Collectors.toList());