Common methods and application examples of java8 Stream

         1. Grouping, traversal and sorting

/**
     * For the assessment list of production waste and operation, each enterprise only keeps the latest assessment data
     *
     * @param entCheckList
     * @return
     */
    private List<Map<String, Object>> cleanEntCheckList(List<Map<String, Object>> entCheckList) {
        Map<String, List<Map<String, Object>>> groupCheckList = entCheckList.stream().collect(Collectors.groupingBy(map -> map.get("enterpriseId").toString()));
        groupCheckList.forEach((key, checkList) -> {
                    if (checkList.size() > 1) {
                        Collections.sort(checkList, new Comparator<Map<String, Object>>() {
                            public int compare(Map<String, Object> o1, Map<String, Object> o2) {
                                return ((String) o2.get("createTime")).compareTo((String) o1.get("createTime"));
                            }
                        });
                        Map<String, Object> temp = checkList.get(0);
                        checkList.clear();
                        checkList.add(temp);
                    }
                }
        );
        entCheckList.clear();
        for (List<Map<String, Object>> map : groupCheckList.values()) {
            entCheckList.addAll(map);
        }
        return entCheckList;
    }

2. Traverse list < map < string, Object > > to obtain the data of composite conditions

List<Map<String, Object>> originEpaCheckList = new ArrayList<Map<String, Object>>();
... //  Assign a value to originEpaCheckList
Set<String> originCheckIdList = new HashSet<>();// Set stores non repeating elements
originEpaCheckList.stream().forEach(map -> originCheckIdList.add(map.get("id").toString()));

3. Traverse List < Object >, and summarize a field in the object into a List

List<InventoryBillVO> recordList = new ArrayLsit<InventoryBillVO>();
List<String> inventoryBillIdList = recordList.stream().map(InventoryBillVO::getId).collect(Collectors.toList());

4. Multi dimensional grouping data processing

/**
     * The waste list is grouped according to the receipt document ID, and then filled into the receipt document information
     *
     * @param recordList
     * @param detailList
     */
    public void fillInventoryBillInfo(List<InventoryBillVO> recordList, List<InventoryInfoDetailVO> detailList) {
        Map<String, List<InventoryInfoDetailVO>> detailGroup = detailList.stream().collect(Collectors.groupingBy(InventoryInfoDetailVO::getInventoryBillId));
        recordList.forEach(record -> {
            List<InventoryInfoDetailVO> wasteList = detailGroup.get(record.getId());
            record.setWasteList(groupByWasteIdAndStorageId(wasteList));
        });
    }

/**
     * The transfer volume is summarized in groups according to waste ID and storage point ID
     *
     * @param wasteList
     * @return
     */
    public List<InventoryInfoDetailVO> groupByWasteIdAndStorageId(List<InventoryInfoDetailVO> wasteList) {
        double totalInventoryWaste = (double) 0.0;
        List<InventoryInfoDetailVO> inventoryInfoDetailVOListNew = Lists.newArrayList();
        if (wasteList != null && wasteList.size() > 0) {
            Map<String, Map<String, List<InventoryInfoDetailVO>>> result = wasteList.parallelStream()
                    .collect(Collectors.groupingBy(InventoryInfoDetailVO::getWasteId,
                            Collectors.groupingBy(InventoryInfoDetailVO::getStorageId)));

            for (Map.Entry<String, Map<String, List<InventoryInfoDetailVO>>> wasteIdMap : result.entrySet()) {
                for (Map.Entry<String, List<InventoryInfoDetailVO>> storageIdmap : wasteIdMap.getValue().entrySet()) {
                    totalInventoryWaste = (double) 0.0;
                    for (InventoryInfoDetailVO inventoryInfoDetailVO : storageIdmap.getValue()) {
                        totalInventoryWaste += Double.parseDouble(inventoryInfoDetailVO.getQuantity()) / Double.parseDouble(inventoryInfoDetailVO.getConversion());
                    }
                    storageIdmap.getValue().get(0).setQuantity(ArithUtil.roundAndSubZero(totalInventoryWaste));
                    inventoryInfoDetailVOListNew.add(storageIdmap.getValue().get(0));
                }
            }
        }
        return inventoryInfoDetailVOListNew;
    }

5. Sum: add the score sum of all elements in the object set

Collectors.summingDouble()
List<EvaluationModule> resultMdls = new ArrayList<EvaluationModule>();
resultMdls  = query SQL;
double score = resultMdls.stream().collect(Collectors.summingDouble(EvaluationModule::getScore));

6. After the collection is filtered, take the first element that meets the condition. If not, return null

if (CollectionUtils.isNotEmpty(yesterdayTrainingPlanList)) {
                yesterdayAudioVisualPlan = yesterdayTrainingPlanList.stream()
                        .filter(plan -> TrainingMdlEnum.AudioVisual.getCode().equals(plan.getType()))
                        .findFirst().orElse(null);
            }

In addition to findFirst(), java.util.stream.Stream also has findAny(), allMatch(), anyMatch(), noneMatch(),   min(),max(), count(), concat(),limit(long maxSize),skip(long n),filter().

java.util.Optional in addition to orElse(T other), orelseget (supplier <? Extensions T > other), ofnullable(), get(), isPresent(), filter(),

7. Set sorting

This class is required to sort using stream().sorted()   Comparable   Interface, which has only one method to be implemented, as follows:

public int compareTo(T o);

Specific implementation examples:

definition StudentInfo Classes, implementing Comparable Interface

//Test data, please do not tangle with the preciseness of the data
List<StudentInfo> studentList = new ArrayList<>();
studentList.add(new StudentInfo("Xiao Ming Li",true,18,1.76,LocalDate.of(2001,3,23)));
studentList.add(new StudentInfo("Zhang Xiaoli",false,18,1.61,LocalDate.of(2001,6,3)));
studentList.add(new StudentInfo("Wang Dapeng",true,19,1.82,LocalDate.of(2000,3,11)));
studentList.add(new StudentInfo("Chen xiaopao",false,17,1.67,LocalDate.of(2002,10,18)));

//Output before sorting
StudentInfo.printStudents(studentList);
//Sort by age (Integer type)
List<StudentInfo> studentsSortName = studentList.stream().sorted(Comparator.comparing(StudentInfo::getAge)).collect(Collectors.toList());
//Output after sorting
StudentInfo.printStudents(studentsSortName);

8. Summation

BigDecimal:

BigDecimal bb =list.stream().map(Plan::getAmount).reduce(BigDecimal.ZERO,BigDecimal::add);

int,double,long:

double max = list.stream().mapToDouble(User::getHeight).sum();

9.Stream.iterate() stream iterator

Stream.iterate(BigInteger.ONE, n->n.add(BigInteger.ONE))

The result is a BigInteger type stream incremented by 1 from 1.

Use example:

/**
     * Cumulative state duration
     * <p>
     * Status duration of current time = sum of status duration from start time to current time
     */
    public static void periodMetricReduce(Map<String, ? extends BaseMetric> metricMap) {

        List<String> keyList = Lists.newArrayList(metricMap.keySet());

        Stream.iterate(0, item -> item + 1)
                .limit(metricMap.size())
                .forEach(item -> {

                    if (item == 0) return;

                    StatePeriodMetric statePeriodMetric = metricMap.get(keyList.get(item)).getStatePeriodMetric();

                    StatePeriodMetric statePeriodMetricForLast = metricMap.get(keyList.get(item - 1)).getStatePeriodMetric();

                    statePeriodMetric.setShutdown(statePeriodMetric.getShutdown() + statePeriodMetricForLast.getShutdown())
                            .setStandby(statePeriodMetric.getStandby() + statePeriodMetricForLast.getStandby())
                            .setWork(statePeriodMetric.getWork() + statePeriodMetricForLast.getWork())
                            .setTotal(statePeriodMetric.getTotal() + statePeriodMetricForLast.getTotal());
                });

    }

10.flatmap

The effect of using the flatMap method is that each array is not mapped to a stream separately, but to the content of the stream. All single streams generated when using map(Array::stream) are merged, that is, flattened into one stream.

example:

        String[] words = new String[]{"Hello","World"};
        List<String> a = Arrays.stream(words)
                .map(word -> word.split(""))
                .flatMap(Arrays::stream)
                .distinct()
                .collect(toList());
        a.forEach(System.out::print);
  List<User> uList = Lists.newArrayList();
        User u1 = new User();
        u1.setAddr("a1;a2;a3;a4;a5");
 
        User u2 = new User();
        u2.setAddr("b1;b2;b3;b4;b5");
 
        uList.add(a);
        uList.add(b);
 
        List<String> addrList = uList.stream().map(x -> x.getAddr()).flatMap(x->Arrays.stream(x.split(";"))).collect(Collectors.toList());
        //perhaps
        List<String> ridStrList = uList.stream().map(x -> x.getAddr()).map(x -> x.split(";")).flatMap(Arrays::stream).collect(Collectors.toList());
        System.out.println(addrList);

11.Optional.ofNullable() method, which can handle null pointer exceptions more gracefully

The query returns null. If there is no null judgment processing, a null pointer exception will occur accidentally. It's OK to add if judgment processing, but jdk1.8 has a more elegant processing method.

public static void main(String[] args) {
        List<String> list = null;
        List<String> newList = Optional.ofNullable(list).orElse(Lists.newArrayList());
        newList.forEach(x -> System.out.println(x));
    }

Source code

//Static variable empty
private static final Optional<?> EMPTY = new Optional<>();
 
//If the object is empty, execute the empty() method; If it is not empty, execute the of(value) method
public static <T> Optional<T> ofNullable(T value) {
        return value == null ? empty() : of(value);
    }
 
public static<T> Optional<T> empty() {
        @SuppressWarnings("unchecked")
        Optional<T> t = (Optional<T>) EMPTY;
        return t;
    }
 
public static <T> Optional<T> of(T value) {
        return new Optional<>(value);
    }

1. First, execute ofNullable() method. If T object is empty, execute empty() method; If it is not empty, execute the of(value) method;
2.empty() method, initialize an empty object optional (empty object and null are not the same thing);

3.of(value) method, use the generic object T on the parameters of the Optional constructor method and return a value object

4. After the above two steps, it is ensured that the Optional is not null and the null pointer is avoided;


twelve   How to write List to Map: get the Map of primary energy type code

The data source itself is an object containing a subset list aggregate

public static Map<String, Set<String>> convertCodeToMap(Collection<CommonNodeTreeVO> trees) {

        if (org.springframework.util.CollectionUtils.isEmpty(trees)) {
            return Maps.newHashMap();
        }

        return trees.stream().
                collect(Collectors.toMap(
                        CommonNodeTreeVO::getCode,
                        e -> Optional.ofNullable(e.getChild())
                                .map(k -> k.stream().map(CommonNodeTreeVO::getCode).collect(Collectors.toCollection(LinkedHashSet::new)))
                                .orElseGet(Sets::newLinkedHashSet),
                        (k1, k2) -> k2,
                        LinkedHashMap::new
                ));

    }

100.java8 Stream example

(1)Use of Lambda expressions in Java - Franson - blog Garden

(2)Performance comparison between grouping statistics using stream and ordinary grouping statistics in Java 8_ Feng Libin's blog - CSDN blog_ java stream grouping statistics

Keywords: Java

Added by magicmoose on Sat, 06 Nov 2021 11:04:36 +0200