跳到主要内容

Java8 Stream的一些使用

·1462 字·3 分钟

实战过程中Java8 stream的一些使用

1.根据对象(比如list)中某个属性去重(java stream distinct() 按指定对象属性进行去重) #

场景: #

list中有5条数据如下:

[{
	name = '沈阳市',
	value = '1001',
	parentValue = '1000',
	num = '1'
}, {
	name = '大连市',
	value = '1002',
	parentValue = '1000',
	num = '2'
}, {
	name = '鞍山市',
	value = '1003',
	parentValue = '1000',
	num = '3'
}, {
	name = '长春市',
	value = '2001',
	parentValue = '2000',
	num = '4'
}, {
	name = '吉林市',
	value = '2002',
	parentValue = '2000',
	num = '5'
}]

假如,parentValue=‘1000’和‘2000’分别代表辽宁和吉林,现在想要晒出这两个省的第一个城市。

列出例子Area.class

class Area{
    private String name;
    private String value;
    private String parentValue;
    private String num;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public String getParentValue() {
        return parentValue;
    }

    public void setParentValue(String parentValue) {
        this.parentValue = parentValue;
    }

    public String getNum() {
        return num;
    }

    public void setNum(String num) {
        this.num = num;
    }

    @Override
    public String toString() {
        return "Area{" +
                "name='" + name + '\'' +
                ", value='" + value + '\'' +
                ", parentValue='" + parentValue + '\'' +
                ", num='" + num + '\'' +
                '}';
    }
}

方法1: #

distinct()不提供按照属性对对象列表进行去重的直接实现。它是基于hashCode()和equals()工作的。如果我们想要按照对象的属性,对对象列表进行去重,我们可以通过其它方法来实现。

private static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
	Map<Object, Boolean> seen = new ConcurrentHashMap<>();
	return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
}
//调用
List<Area> parentList = list.stream().filter(distinctByKey(Area::getParentValue).collect(Collectors.toList();

例子代码:

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

public class TestMain {
    public static void main(String[] args) {
        Area area1 = new Area();
        area1.setName("沈阳市");
        area1.setValue("1001");
        area1.setParentValue("1000");
        area1.setNum("1");

        Area area2 = new Area();
        area2.setName("大连市");
        area2.setValue("1002");
        area2.setParentValue("1000");
        area2.setNum("2");

        Area area3 = new Area();
        area3.setName("鞍山市");
        area3.setValue("1003");
        area3.setParentValue("1000");
        area3.setNum("3");

        Area area4 = new Area();
        area4.setName("长春市");
        area4.setValue("2001");
        area4.setParentValue("2000");
        area4.setNum("4");

        Area area5 = new Area();
        area5.setName("吉林市");
        area5.setValue("2002");
        area5.setParentValue("2000");
        area5.setNum("5");

        List<Area> list = new ArrayList<>();
        list.add(area1);
        list.add(area2);
        list.add(area3);
        list.add(area4);
        list.add(area5);
        System.out.println("筛选前");
        System.out.println(list);

        List<Area> parentList = list.stream().filter(distinctByKey(Area::getParentValue).collect(Collectors.toList();
        System.out.println("筛选后");
        System.out.println(parentList);


    }
    private static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
        Map<Object, Boolean> seen = new ConcurrentHashMap<>();
        return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
    }
}

输出:

筛选前
[Area{name='沈阳市', value='1001', parentValue='1000', num='1'}, Area{name='大连市', value='1002', parentValue='1000', num='2'}, Area{name='鞍山市', value='1003', parentValue='1000', num='3'}, Area{name='长春市', value='2001', parentValue='2000', num='4'}, Area{name='吉林市', value='2002', parentValue='2000', num='5'}]
筛选后
[Area{name='沈阳市', value='1001', parentValue='1000', num='1'}, Area{name='长春市', value='2001', parentValue='2000', num='4'}]

方法2: #

使用stream流的衍生功能:

ArrayList<Area> parentList = list.stream().collect(Collectors.collectingAndThen(
                Collectors.toCollection(() -> new TreeSet<>(
                        Comparator.comparing(
                                Area::getParentValue)), ArrayList::new);
System.out.println("筛选后");
System.out.println(parentList);

输出:

筛选前
[Area{name='沈阳市', value='1001', parentValue='1000', num='1'}, Area{name='大连市', value='1002', parentValue='1000', num='2'}, Area{name='鞍山市', value='1003', parentValue='1000', num='3'}, Area{name='长春市', value='2001', parentValue='2000', num='4'}, Area{name='吉林市', value='2002', parentValue='2000', num='5'}]
筛选后
[Area{name='沈阳市', value='1001', parentValue='1000', num='1'}, Area{name='长春市', value='2001', parentValue='2000', num='4'}]

如果是多个属性字段或多个条件去重:

ArrayList<PatentDto> collect1 = patentDtoList.stream().collect(Collectors.collectingAndThen(
                Collectors.toCollection(() -> new TreeSet<>(
                        Comparator.comparing(p->p.getPatentName() + ";" + p.getLevel()), ArrayList::new);

2.排序 #

升序: #

//根据msgSeq字段对TimMsgDTO的list进行升序排序
List<TimMsgDTO> sortedNotnullMsgList = notnullMsgList.stream().sorted(Comparator.comparing(TimMsgDTO::getMsgSeq).collect(Collectors.toList();

降序: #

//根据start_time字段对SynBaseinfoDTO的list进行降序排序
List<SynBaseinfoDTO> sortedList = returnList.stream().sorted(Comparator.comparing(SynBaseinfoDTO::getStart_time).reversed().collect(Collectors.toList();
Anarkh
作者
Anarkh
博学之 审问之 慎思之 明辨之 笃行之