java8+stream+remove_Java8的Stream用法

Java8 API新增了一个新的抽象流Stream,它可以执行非常复杂的查找、过滤和映射数据等操作。使用Stream API 对集合数据进行操作,就类似于使用 SQL 执行的数据库查询。Stream就是把集合数据看作流,流在管道中传输,我们可在管道中进行排序聚合等操作。

在平时写代码的过程中,涉及到集合操作时候,Stream API可以极大的提高我们的生产力,让我们写出高效率、干净、简洁的代码。Stream API有很多操作可供使用,这里主要介绍常用的几个方法。

基础Stream API

forEach

forEach是迭代流中的每一个元素。

1

2

3

4

5

6

7

8@Test

public void testForeach() {

Random random = new Random();

List list= new ArrayList<>();

//random.ints(-100,100).limit(10).forEach(System.out::println);

random.ints(-100,100).limit(10).forEach(t->list.add(t));

System.out.println(list);

}

上述是用forEach迭代输出每一个-100至100的随机值,输出10个,还可以迭代进入一个新的List集合。

map

map对流中每个元素进行操作,返回一个新的流

1

2

3

4

5

6

7

8

9

10

11

12@Test

public void testMap(){

// 只是对流操作并不会改变原List中的数据

//Stream fruit=Stream.of("apple","orange","banner","pear");

List fruit = Arrays.asList("apple","orange","banner","pear");

fruit.stream().sorted().map(String::toUpperCase).forEach(System.out::println);

System.out.println(fruit);

// 返回新的流

List newfruit = fruit.stream().map(v->v.toUpperCase()).collect(Collectors.toList());

System.out.println(newfruit);

}

上述是对每个元素进行大写字母化,或输出或返回到新的集合中

filter

filter 方法用于通过设置的条件过滤出元素

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19/**

* Long 数组选取不为Null和大于0的值

* @param t

* @return

*/

public static Long[] removeNullAndZero(Long[] t) {

List list = Arrays.asList(t);

return list.stream().filter(v->v!=null && v>0).toArray(Long[] :: new);

}

/**

* 选取String数组 不为Null的值

* @param t

* @return

*/

public static String[] removeNullAndZero(String[] t) {

List list = Arrays.asList(t);

return list.stream().filter(v->v!=null).toArray(String[] :: new);

}

过滤Null或者大于0的元素

1

2

3

4

5

6@Test

public void testFilter() {

List intList = Arrays.asList(8,2,4,1,8,3,10,6,6,15);

List newIntList=intList.stream().filter(i->i>5).sorted().distinct().collect(Collectors.toList());

System.out.println(newIntList);

}

上述是过滤大于5的值,并且排序,取唯一的数字输出到新的集合。

parallelStream

parallelStream 是流并行处理程序的代替方法,相比较Stream是多管道操作。它就是基于ForkJoinPool执行并发任务的。

特点

使用parallelStream可以简洁高效的写出并发代码。

parallelStream并行执行是无序的。

parallelStream提供了更简单的并发执行的实现,但并不意味着更高的性能,它是使用要根据具体的应用场景。如果cpu资源紧张parallelStream不会带来性能提升;如果存在频繁的线程切换反而会降低性能。

任务之间最好是状态无关的,因为parallelStream默认是非线程安全的,可能带来结果的不确定性。

Github上对Parallel做了增强,有兴趣可以点击访问。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15@Test

public void testParallel() {

Random random = new Random();

List list= new ArrayList<>();

random.ints(-10000,10000).limit(10000).forEach(t->list.add(t));

long start = System.currentTimeMillis();

list.stream().filter(e -> e > 1000 && e< 2000).collect(Collectors.toList());

System.out.println("stream : " + (System.currentTimeMillis() - start) + "ms");

start = System.currentTimeMillis();

list.parallelStream().filter(e -> e > 1000 && e < 2000).collect(Collectors.toList());

System.out.println("parallelStream : " + (System.currentTimeMillis() - start) + "ms");

}

测试并发处理速度,上述代码对此做了测试,测试结果parallelStream速度是稍快一点。

Count

Stream API还提供简单的统计操作。

1

2

3

4

5

6

7

8

9

10

11@Test

public void testCount() {

List numList = Arrays.asList(6, 2, 4, 3, 7, 3, 5, 9);

DoubleSummaryStatistics stats = numList.stream().mapToDouble((x) -> x).summaryStatistics();

System.out.println("总个数 : " + stats.getCount());

System.out.println("列表中最大的数 : " + stats.getMax());

System.out.println("列表中最小的数 : " + stats.getMin());

System.out.println("所有数之和 : " + stats.getSum());

System.out.println("平均数 : " + stats.getAverage());

}

简单的统计的功能。

实际应用

我在实际项目对会有集合进行操作,使用Stream API能够帮我简洁的解决问题。下面是我实际使用场景。

对象类1

2

3

4

5

6

7

8

9

10

11

12

13

14import lombok.AllArgsConstructor;

import lombok.Data;

import lombok.NoArgsConstructor;

@Data

@NoArgsConstructor

@AllArgsConstructor

public class Person {

private String name;

private Integer gender;

private int age;

private double height;

}

使用场景

构造数据1

2

3

4

5

6

7

8

9

10

11

12static List createPeople(){

List people=new ArrayList();

Person person=new Person("张三",0,30,2.8);

people.add(person);

person=new Person("李四",0,32,1.6);

people.add(person);

person=new Person("王五",1,32,2.0);

people.add(person);

person=new Person("王五",1,33,1.6);

people.add(person);

return people;

}

连接某一属性

需要并行显示,用,连接某一属性

1

2

3

4

5

6

7

8@Test

public void CollectionStreamJoin(){

List people=createPeople();

Stream stream=people.stream();

// 取出对象的name值,并用,连接

String names = stream.map(v->v.getName()).collect(Collectors.joining(","));

System.out.println(names);

}

获取某属性唯一值

根据某一个属性值,删选对象。只保留唯一的属性值

1

2

3

4

5

6

7

8

9@Test

public void distinctList() {

List people=createPeople();

List distinctlist = people.stream()

.collect(Collectors.collectingAndThen(

Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Person::getName))),

ArrayList::new));

System.out.println(distinctlist);

}

多属性排序

需要用多个属性去进行排序

1

2

3

4

5

6@Test

public void sortField() {

List people=createPeople();

people.sort(Comparator.comparing(Person::getAge).reversed().thenComparing(Person::getHeight));

System.out.println(JSON.toJSONString(people));

}

分组后排序

对象列表先按照一个字段分组,并根据另一个字段的大小来排序,取第一个对象

1

2

3

4

5

6

7

8

9

10

11@Test

public void getOnlyOneByField() {

List people=createPeople();

Map map =new HashMap<>();

map = people.parallelStream()

.collect(Collectors.groupingBy(Person::getName,

Collectors.collectingAndThen(

Collectors.reducing((c1, c2) -> c1.getAge()>c2.getAge()?c1:c2),

Optional::get)));

System.out.println(map);

}

总结

使用Stream API可以让集合操作的代码更为简洁,提高生产力。而且本人在写Stream操作的时候,思想就跟写SQL语句类似,包括分组、聚合、过滤等操作,遇到难的可以在思维上借鉴下。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 可以使用Java 8中的Stream API的distinct()方法来实现去重。例如,假设我们有一个字符串列表,我们可以使用以下代码来去重并打印每个唯一的字符串: ``` List<String> stringList = Arrays.asList("apple", "banana", "apple", "orange", "banana"); stringList.stream().distinct().forEach(System.out::println); ``` 输出结果为: ``` apple banana orange ``` 在这个例子中,我们使用了Stream API的distinct()方法来去重字符串列表,并使用forEach()方法打印每个唯一的字符串。 ### 回答2: 使用Java Stream去重可以通过使用distinct()方法来实现。distinct()方法是Stream接口的一个中间操作,它会返回一个去重后的新Stream,该新Stream不包含重复的元素。 示例代码如下: List<Integer> numbers = Arrays.asList(1, 2, 3, 3, 4, 5, 5); List<Integer> distinctNumbers = numbers.stream().distinct().collect(Collectors.toList()); 在上述代码中,我们有一个整型的List,其中包含了一些重复的数字。通过使用stream()方法,我们可以将List转换为Stream,然后使用distinct()方法去重,最后通过collect(Collectors.toList())方法将去重后的Stream转换为List。 输出结果为:[1, 2, 3, 4, 5],可以看到去重后的List中只包含了不重复的数字。 需要注意的是,distinct()方法会根据元素的hashCode()和equals()方法来进行去重。所以,如果我们在自定义类中需要去重,需要确保重写了hashCode()和equals()方法。 另外,如果想要对自定义类的多个字段进行去重,可以使用如下方式: List<Person> people = new ArrayList<>(); List<Person> distinctPeople = people.stream().distinct().collect(Collectors.toList()); 在这个例子中,我们使用了自定义的Person类。如果希望根据Person对象的多个字段进行去重,就需要在Person类中重写hashCode()和equals()方法,确保根据多个字段的值来判断两个对象是否相同。 ### 回答3: Java StreamJava 8及以上版本引入的一种新的数据处理方式。在Java Stream中去重操作可以通过使用distinct()方法来实现。 通过调用Stream的distinct()方法,可以返回一个去重后的新的Stream。该方法使用元素的equals()方法来确定元素是否重复,从而保留唯一的元素并删除重复的元素。 以下是一个示例代码: ```java import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; public class RemoveDuplicates { public static void main(String[] args) { List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 3, 2, 1); List<Integer> distinctNumbers = numbers.stream() .distinct() .collect(Collectors.toList()); System.out.println(distinctNumbers); // 输出结果:[1, 2, 3, 4] } } ``` 在以上代码中,我们创建了一个包含重复元素的List,并通过Stream的distinct()方法去除了重复的元素,最后将去重后的结果收集到一个新的List中打印出来。 需要注意的是,distinct()方法依赖元素的equals()方法来判断元素是否相等,因此在自定义类的情况下需要重写equals()方法。此外,distinct()方法是没有顺序保证的,如果希望保留原有顺序,则可以使用LinkedHashSet来实现。 以上就是使用Java Stream进行去重操作的方式。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值