[Lambda] Expresiones lambda para colecciones

[1] Introducción al método de Stream

[1] Métodos comúnmente utilizados en Stream

(1) collect(toList()): genera una lista a través de Stream
(2) map: convierte un valor en el flujo en un nuevo valor
(3) filter: filtra los elementos en el Stream
(4) flatMap: convierte múltiples Stream es conectado a un Stream
(5) max: encuentra el valor máximo
(6) min: encuentra el valor mínimo
(7) reduce: genera un nuevo valor a partir de un conjunto de valores
(8) Collectors.joining: saca un valor de un conjunto de valores Hacer empalme (puede reemplazar el método String.join)

【2】recoger(toList()) y filtrar

La función de collect(toList()) es generar un objeto List a través de un objeto Stream, caso:

List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> result = list.stream().filter((value) -> value > 2).collect(toList());
result.forEach((value) -> System.out.print(value));

El código anterior primero crea un objeto List y lo inicializa, luego filtra los valores mayores que 2 y los genera.
La función del método filter es filtrar los elementos en el Stream. El método filter es una función de orden superior que recibe una interfaz de función como parámetro. Esta función de orden superior devuelve un valor booleano, y los elementos que devuelven verdadero ser retenido; método collect(toList())
Genera una lista a partir de la secuencia devuelta por la operación de filtro.

【3】mapa

Cuando operamos en una colección, a menudo extraemos selectivamente el valor de ciertos elementos de ciertos objetos, al igual que escribir SQL, especificando obtener una columna de datos específica en la tabla.La función de la función de mapa es convertir uno de los flujos El
valor se convierte en un nuevo valor. Por ejemplo, si queremos convertir una lista en una lista, entonces podemos usar el método de mapa. Código de muestra:

List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
List<String> result = list.stream().map(value -> String.format("String:%s", value)).collect(toList());
result.forEach(System.out::print);

El método map convierte los elementos Integer en String y usa el método collect(toList()) para generar una nueva Lista.

System.out::print es una abreviatura de (valor) -> System.out.print(valor).

【4】mapa plano

flatMap: conecte múltiples Streams en un Stream, cómo entender esto, dé una castaña:
primero defina un objeto de Lista, divida cada Cadena en este objeto en una letra y genere un nuevo objeto de Lista, codifique:

List<String> list = Arrays.asList("abc", "def", "ghi");
List<Character> result = list.stream().flatMap(value -> {
    
    
    char[] chars = value.toCharArray();
    Character[] characters = new Character[chars.length];
    for(int i = 0; i < characters.length; i++){
    
    
        characters[i] = chars[i];
    }
    return Stream.of(characters);
}).collect(toList());
result.forEach(System.out::println);

El código anterior primero atraviesa la lista, genera un nuevo Stream para cada elemento String a través de la función flatMap y conecta estos Streams en un nuevo Stream.

【5】máximo y mínimo

Encuentre el máximo y el mínimo

List<Integer> list = Arrays.asList(0, 1, 2, 3);
Comparator<Integer> comparator = (o1, o2) -> o1.compareTo(o2);
System.out.println(list.stream().min(comparator).get());
System.out.println(list.stream().max(comparator).get());

Las funciones min y max requieren un objeto Comparator como parámetro para la comparación.

【6】reducir

Generar un nuevo valor a partir de un conjunto de valores. La función de reducción es realmente muy versátil y poderosa. Pongamos un ejemplo de acumulación:

List<Integer> list = Arrays.asList(0, 1, 2, 3);
int count = list.stream().reduce(0, (acc, item) -> acc + item).intValue();
System.out.println(count);

Un parámetro de la función reduce es el valor inicial del ciclo, donde el valor inicial es 0 cuando se calcula la acumulación, acc representa el resultado calculado y item representa cada elemento del ciclo.

List<Integer> integers = Arrays.asList(1, 2, 3, 4, 4, 5, 5, 6, 7, 8, 2, 2, 2, 2);
Integer reduce = integers.stream().reduce(0, (integer1, integer2) -> integer1 + integer2);
System.out.println(reduce);

En el código anterior, el primer parámetro en reduce se declara como el valor inicial, y el segundo parámetro recibe una expresión lambda que representa dos elementos en la secuencia actual, que agregará repetidamente cada elemento hasta que la secuencia regrese a un resultado final.

Integer reduce = integers.stream().reduce(0,Integer::sum);

Se puede optimizar así. Por supuesto, reduce también tiene un método sobrecargado sin un parámetro de valor inicial, pero es necesario juzgar el resultado devuelto, porque si no hay elementos en la transmisión, es posible que no haya resultado. El método específico es el siguiente.

【7】si está presente

[8] findAny: encontrar elementos

Para las operaciones de conjuntos, a veces es necesario encontrar elementos que cumplan las condiciones del conjunto. Stream también proporciona API relacionadas, findAny() y findFirst(), que se pueden usar en combinación con otras operaciones de flujo. findAny se usa para obtener un elemento aleatorio en la secuencia y findFirst se usa para obtener el primer elemento en la secuencia. En cuanto a algunos requisitos de personalización especiales, debe implementarlos usted mismo.

findAny se usa para obtener un elemento aleatorio en la transmisión y usar el cortocircuito para finalizar inmediatamente cuando se encuentra el resultado

//findAny用于获取流中随机的某一个元素,并且利用短路在找到结果时,立即结束
ArrayList<Student> students = new ArrayList<>();
students.add(new Student(1,19,"张三1","M",true));
students.add(new Student(1,18,"张三2","M",false));
students.add(new Student(1,21,"张三3","F",true));
students.add(new Student(1,20,"张三4","F",false));
students.add(new Student(1,20,"张三5","F",false));
students.add(new Student(1,20,"张三6","F",false));
Optional<Student> student1 = students.stream().filter(student -> student.getSex().equals("F")).findAny();
System.out.println(student1.toString());

【9】buscarprimero:

[9] anyMatch: la condición de juicio coincide con al menos un elemento

anyMatch() se usa principalmente para determinar si hay al menos un elemento elegible en la secuencia, devolverá un valor booleano y su operación generalmente se denomina evaluación de cortocircuito.

Determinar si hay estudiantes menores de 20 años en la colección.

//判断集合中是否有年龄小于20的学生
ArrayList<Student> students = new ArrayList<>();
students.add(new Student(1,19,"张三","M",true));
students.add(new Student(1,18,"李四","M",false));
students.add(new Student(1,21,"王五","F",true));
students.add(new Student(1,20,"赵六","F",false));

if(students.stream().anyMatch(student -> student.getAge() < 20)){
    
    
    System.out.println("集合中有年龄小于20的学生");
}else {
    
    
    System.out.println("集合中没有年龄小于20的学生");
}

【10】allMatch: determina si la condición coincide con todos los elementos

El principio de funcionamiento de allMatch() es similar a anyMatch(), pero cuando se ejecuta anyMatch, siempre que haya un elemento en la transmisión que cumpla con las condiciones, devolverá verdadero y allMatch juzgará si todas las condiciones en el stream cumple con las condiciones, y todas volverán verdaderas

Determine si la edad de todos los estudiantes en el conjunto es menor de 20

//判断集合所有学生的年龄是否都小于20
ArrayList<Student> students = new ArrayList<>();
students.add(new Student(1,19,"张三","M",true));
students.add(new Student(1,18,"李四","M",false));
students.add(new Student(1,21,"王五","F",true));
students.add(new Student(1,20,"赵六","F",false));

if(students.stream().allMatch(student -> student.getAge() < 20)){
    
    
    System.out.println("集合所有学生的年龄都小于20");
}else {
    
    
    System.out.println("集合中有年龄大于20的学生");
}

[11] saltar: saltar

Interceptar 5 datos del tercero en la colección

//从集合第三个开始截取5个数据
List<Integer> integers = Arrays.asList(1, 2, 3, 4, 4, 5, 5, 6, 7, 8, 2, 2, 2, 2);
List<Integer> collect = integers.stream().skip(3).limit(5).collect(Collectors.toList());
collect.forEach(integer -> System.out.print(integer+" "));

Primero intercepte 5 elementos de la colección y luego tome los últimos 3

//先从集合中截取5个元素,然后取后3个
List<Integer> integers = Arrays.asList(1, 2, 3, 4, 4, 5, 5, 6, 7, 8, 2, 2, 2, 2);
List<Integer> collect = integers.stream().limit(5).skip(2).collect(Collectors.toList());
collect.forEach(integer -> System.out.print(integer+" "));

[12] distinto: deduplicación

List<Integer> integers = Arrays.asList(1, 2, 3, 4, 4, 5, 5, 6, 7, 8, 2, 2, 2, 2);
integers.stream().distinct().collect(Collectors.toList());

[13] límite: rebanada

Obtenga los primeros cinco dígitos de la matriz

//获取数组的前五位
List<Integer> integers = Arrays.asList(1, 2, 3, 4, 4, 5, 5, 6, 7, 8, 2, 2, 2, 2);
integers.stream().limit(5);

[14] filtro: filtro

Obtener todos los estudiantes menores de 20 años

public class FilterDemo {
    
    
    public static void main(String[] args) {
    
    
        
        //获取所有年龄20岁以下的学生
        ArrayList<Student> students = new ArrayList<>();
        students.add(new Student(1,19,"张三","M",true));
        students.add(new Student(1,18,"李四","M",false));
        students.add(new Student(1,21,"王五","F",true));
        students.add(new Student(1,20,"赵六","F",false));
        students.stream().filter(student -> student.getAge()<20);
    }
}

[2] Resumen de casos comunes

【1】Método de preparación para consultar la base de datos para obtener el resultado de la Lista

Utilizo el mapeador de Mybatis-plus, o puedo personalizar una colección de listas por mí mismo

@SpringBootTest
public class LambdaTest {
    
    
    @Autowired
    private UserMapper userMapper;

    @Test
    public void selectList() {
    
    
        // 通过条件构造器查询一个List集合,如果没有条件,就可以设置null为参数
        List<User> list = userMapper.selectList(null);
        list.forEach(System.out::println);
    }
}

El código de clase de entidad es

@Data // 包含以上,除了有参构造
@TableName("user")
public class User {
    
    
    private Long id;
    private String name;
    private Integer age;
    private String email;
}

Los resultados de salida son los siguientes
inserte la descripción de la imagen aquí

[2] valor

Tome un determinado valor objetivo de la clase de entidad de la lista y colóquelo en el nuevo resultado de la lista. Por ejemplo, tome el nombre de la clase de entidad User de la colección List y colóquelo en List.

El código es el siguiente (¡las siguientes dos formas de escribir son posibles!):

List<String> nameList = list.stream().map(User::getName).collect(Collectors.toList());
List<String> nameList = list.stream().map(it->it.getName()).collect(Collectors.toList());

El efecto de la ejecución es el siguiente:
inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí

[3] Agrupación: agrupación por

Clasifique y almacene las clases de entidad en la Lista de acuerdo con un cierto valor en la clase de entidad y use el Mapa para recibir los resultados. Por ejemplo, clasificamos y almacenamos los Usuarios de la Lista en diferentes Listas según la edad.

el código se muestra a continuación:

Map<Integer, List<User>> ageMap = list.stream().collect(Collectors.groupingBy(User::getAge));
ageMap.forEach((k,v)->{
    
    
    System.out.println(k+":\n"+String.join("\n",v.toString()));
});

El resultado de la ejecución es el siguiente:
inserte la descripción de la imagen aquí

【4】Deduplicación

el código se muestra a continuación:

@Test
public void distinctTield() {
    
    
    List<String> numList = Arrays.asList("1","2","2","3","3","4","4","5","6","7","8");
    List<User> userList = userMapper.selectList(null);

    System.out.println(LambdaTest.distinctElements(numList));
    System.out.println(LambdaTest.getNoDuplicateElements(numList));
    System.out.println(LambdaTest.getDuplicateElements(numList));
    System.out.println(LambdaTest.getDuplicateElementsForObject(userList));
    System.out.println(LambdaTest.getNoDuplicateElementsForObject(userList));
    System.out.println(LambdaTest.getElementsAfterDuplicate(userList));
    System.out.println(LambdaTest.getDuplicateObject(userList));
    System.out.println(LambdaTest.getNoDuplicateObject(userList));
    System.out.println(LambdaTest.distinctObject(userList));
}

//(1)把重复的数据删除,只留下一个
//去重后的集合 [1, 2, 3, 4, 5, 6, 7, 8]
public static <T> List<T> distinctElements(List<T> list) {
    
    
    return list.stream().distinct().collect(Collectors.toList());
}

//(2)把所有出现重复的数据都删除
//lambda表达式 去除集合重复的值  [1, 5, 6, 7, 8]
public static <T> List<T> getNoDuplicateElements(List<T> list) {
    
    
    // 获得元素出现频率的 Map,键为元素,值为元素出现的次数
    Map<T, Long> map = list.stream().collect(Collectors.groupingBy(p -> p,Collectors.counting()));
    System.out.println("getDuplicateElements2: "+map);
    return map.entrySet().stream() // Set<Entry>转换为Stream<Entry>
            .filter(entry -> entry.getValue() == 1) // 过滤出元素出现次数等于 1 的 entry
            .map(entry -> entry.getKey()) // 获得 entry 的键(重复元素)对应的 Stream
            .collect(Collectors.toList()); // 转化为 List
}

//(3)把出现重复的数据查出来
//lambda表达式 查找出重复的集合 [2, 3, 4]
public static <T> List<T> getDuplicateElements(List<T> list) {
    
    
    return list.stream().collect(Collectors.collectingAndThen(Collectors
            .groupingBy(p -> p, Collectors.counting()), map->{
    
    
        map.values().removeIf(size -> size ==1); // >1 查找不重复的集合;== 1 查找重复的集合
        List<T> tempList = new ArrayList<>(map.keySet());
        return tempList;
    }));
}

//利用set集合
public static <T> Set<T> getDuplicateElements2(List<T> list) {
    
    
    Set<T> set = new HashSet<>();
    Set<T> exist = new HashSet<>();
    for (T s : list) {
    
    
        if (set.contains(s)) {
    
    
            exist.add(s);
        } else {
    
    
            set.add(s);
        }
    }
    return exist;
}

/**-----------对象List做处理--------------*/

//查找对象中某个原属重复的  属性集合
public static List<String> getDuplicateElementsForObject(List<User> list) {
    
    
    return list.stream().collect(Collectors.groupingBy(p -> p.getName(),Collectors.counting())).entrySet().stream()// 根据name分类,并且统计每个name出现的次数
            .filter(entry -> entry.getValue() > 1) // >1 查找重复的集合;== 查找不重复的集合
            .map(entry -> entry.getKey())
            .collect(Collectors.toList());
}

//查找对象中某个原属未重复的  属性集合
public static List<String> getNoDuplicateElementsForObject(List<User> list){
    
    
    Map<String,List<User>> map = list.stream().collect(Collectors.groupingBy(User::getName));
    return map.entrySet().stream().filter(entry -> entry.getValue().size() == 1)
            .map(entry -> entry.getKey()) // 获得 entry 的键(重复元素)对应的 Stream
            .collect(Collectors.toList()); // 转化为 List

}

//查找对象中某个原属去重后的集合
public static List<String> getElementsAfterDuplicate(List<User> list) {
    
    
    return list.stream().map(o->o.getName()).distinct().collect(Collectors.toList());
}

//对象中某个原属重复的 对象集合
public static List<List<User>> getDuplicateObject(List<User> list) {
    
    
    return list.stream().collect(Collectors.groupingBy(User::getName)).entrySet().stream()
            .filter(entry -> entry.getValue().size() > 1) // >1 查找重复的集合;== 查找不重复的集合
            .map(entry -> entry.getValue())
            .collect(Collectors.toList());
}

//对象中某个原属未重复 对象集合
public static List<User> getNoDuplicateObject(List<User> list) {
    
    
    List<User> cities = new ArrayList<>();
    list.stream().collect(Collectors.groupingBy(User::getName)).entrySet().stream()
            .filter(entry -> entry.getValue().size() ==1) //>1 查找重复的集合;== 查找不重复的集合;
            .map(entry -> entry.getValue())
            .forEach(p -> cities.addAll(p));
    return cities;
}


//根据对象的某个原属去重后的 对象集合
public static List<User> distinctObject(List<User> list) {
    
    
    return list.stream().filter(distinctByKey(User::getName)).collect(Collectors.toList());
}

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

[5] Ordenar

el código se muestra a continuación:

@Test
public void sortField() {
    
    
    List<Integer> list = Arrays.asList(10,1,6,4,8,7,9,3,2,5);
    List<User> userList = userMapper.selectList(null);

    System.out.println(sort(list));
    System.out.println(reversed(list));
    System.out.println(sortForObject(userList));
    System.out.println(reversedForObject(userList));
    System.out.println(sortForObject2(userList));
}

//list排序 正序
public static <T> List<T> sort(List<T> list){
    
    
    return list.stream().sorted().collect(Collectors.toList());
}

//list排序 倒序
public static List<Integer> reversed(List<Integer> list){
    
    
    return list.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());
}

//根据对象某个属性排序  正序
public static List<User> sortForObject(List<User> list){
    
    
    return list.stream().sorted(Comparator.comparing(User::getAge)).collect(Collectors.toList());
}

//根据对象某个属性排序  倒序
public static List<User> reversedForObject(List<User> list){
    
    
    return list.stream().sorted(Comparator.comparing(User::getAge).reversed()).collect(Collectors.toList());
}

//根据对象两个属性排序  正序
public static List<User> sortForObject2(List<User> list){
    
    
    return list.stream().sorted(Comparator.comparing(User::getAge).thenComparing(User::getId)).collect(Collectors.toList());
}

El efecto de ejecución es el siguiente:
inserte la descripción de la imagen aquí

[6] El valor máximo, el valor medio y la suma de la lista

el código se muestra a continuación:

@Test
public void getInfo() {
    
    
    List<Integer> list = Arrays.asList(10,1,6,4,8,7,9,3,2,5);
    List<User> userList = userMapper.selectList(null);
    calculation1(list);
    calculation2(userList);
}

//根据对象某个属性求各自值
///IntSummaryStatistics{count=4, sum=132, min=11, average=33.000000, max=55}
public static IntSummaryStatistics calculation1(List<Integer> list){
    
    
    IntSummaryStatistics stat = list.stream().collect(Collectors.summarizingInt(p -> p));
    System.out.println("max:"+stat.getMax());
    System.out.println("min:"+stat.getMin());
    System.out.println("sum:"+stat.getSum());
    System.out.println("count:"+stat.getCount());
    System.out.println("average:"+stat.getAverage());
    Integer max = list.stream().reduce(Integer::max).get();//得到最大值
    Integer min = list.stream().reduce(Integer::min).get();//得到最小值
    System.out.println("max:"+max+";min:"+min);
    return stat;
}
//根据对象某个属性求各自值
// sum=397,max=29,min=12,ave=23.352941176470587
public static void calculation2(List<User> list){
    
    
    System.out.println("sum="+ list.stream().mapToInt(User::getAge).sum());
    System.out.println("max="+ list.stream().mapToInt(User::getAge).max().getAsInt());
    System.out.println("min="+ list.stream().mapToInt(User::getAge).min().getAsInt());
    System.out.println("ave="+ list.stream().mapToInt(User::getAge).average().getAsDouble());
}

El efecto de la operación de código es el siguiente:
inserte la descripción de la imagen aquí

【7】Resumen de la colección de listas

public static void main(String[] args) {
    
    
    List<BigDecimal> list = new ArrayList<>();
    list.add(BigDecimal.valueOf(1.1));
    list.add(BigDecimal.valueOf(1.2));
    list.add(BigDecimal.valueOf(1.3));
    list.add(BigDecimal.valueOf(1.4));

    BigDecimal decimal = list.stream().reduce(BigDecimal.ZERO, BigDecimal::add);
    System.out.println(decimal);
}

【8】Filtro

(1) Caso 1

//功能描述 过滤
public static List<City> filter(List<City> list){
    
    
    return list.stream().filter(a -> a.getTotal()>44).collect(Collectors.toList());
}

(2) Caso 2
Por ejemplo, hay dos listas, a saber, notFinishList y finalList, y queremos filtrar todos los valores de notFinishList en finalList, por lo que podemos usar el filtro para lograr

List<Long> taskIds = Array.asList(1,2,3,4);
// 从List<DevelopTask>中取出实体类的id值生成一个List<Long>,假设结果是{1,2}
List<Long> notFinishTaskids = notFinishList.stream().map(DevelopTask::getId).collect(Collectors.toList());
// 从{1,2,3,4}取出除了{1,2}以外的值,也就是{3,4}
taskIds = taskIds.stream().filter(it -> !notFinishTaskids.contains(it)).collect(Collectors.toList());

(3) Caso 3
Determinar si existe un determinado valor en la colección actual y el resultado devuelto es un valor booleano

Boolean overallReviewRst = details.stream().filter(it->it.getReviewRst().equals(ReviewStatEnum.NO_PASS.getName())).findAny().isPresent();

(4) Caso 4
Determinar si existe cierto valor en la colección actual

audits.stream().anyMatch(a -> po.getIdCard().equals(a.getIdCard()))

(5) Caso 5
Juzgar si hay un cierto valor en la colección actual, si existe, filtrarlo y ponerlo en una nueva colección

List<TaskXReviewProjRescResponse> details = detailById.stream()
        .filter(d -> String.valueOf(d.getTaskId()).equals(dto.getId()))
        .collect(Collectors.toList());

【9】recorrido del mapa

(1) la corriente atraviesa la clave y el valor

map.forEach((k, v) -> System.out.println("key:value = " + k + ":" + v));

【10】mapa a lista, lista a mapa

(1) Conversión mutua entre mapa y lista

//功能描述 List转map
public static void listToMap(List<User> list){
    
    
    //用 (k1,k2)->k1 来设置,如果有重复的key,则保留key1,舍弃key2
    Map<String,User> map = list.stream().collect(Collectors.toMap(User::getName,user -> user, (k1, k2) -> k1));
    map.forEach((k,v) -> System.out.println("k=" + k + ",v=" + v));
}

//功能描述 map转list
public static void mapToList(Map<String,User> map){
    
    
    List<User> list =
            map.entrySet().stream().map(key -> key.getValue()).collect(Collectors.toList());
    System.out.println(list);
    list.forEach(bean -> System.out.println(bean.getName() + "," + bean.getEmail()));
}

(2) mapa a la lista

map.entrySet().stream().map(e -> new Person(e.getKey(),e.getValue())).collect(Collectors.toList());
map.keySet().stream().collect(Collectors.toList());
map.values().stream().collect(Collectors.toList());

(3) lista para mapear

Map<Integer, String> result1 = list.stream().collect(
                Collectors.toMap(Hosting::getId, Hosting::getName));

Map<Long, User> maps = userList.stream().collect(Collectors.toMap(User::getId,Function.identity()));

//看来还是使用JDK 1.8方便一些。另外,转换成map的时候,可能出现key一样的情况,如果不指定一个覆盖规则,上面的代码是会报错的。转成map的时候,最好使用下面的方式
Map<Long, User> maps = userList.stream().collect(Collectors.toMap(User::getId, Function.identity(), (key1, key2) -> key2));

[11] Conversión entre lista y cadena

//功能描述 字符串转list
public static void stringToList(String str){
    
    
    //不需要处理
    //<String> list = Arrays.asList(str.split(","));
    //需要处理
    List<String> list = Arrays.asList(str.split(",")).stream().map(string -> String.valueOf(string)).collect(Collectors.toList());
    list.forEach(string -> System.out.println(string));
}

//功能描述 姓名以逗号拼接
public static void joinStringValueByList(List<User> list){
    
    
    System.out.println(list.stream().map(User::getName).collect(Collectors.joining(",")));
}

//功能描述 姓名以逗号拼接
public static void joinStringValueByList2(List<String> list){
    
    
    //方式一
    System.out.println(String.join(",", list));
    //方式二
    System.out.println(list.stream().collect(Collectors.joining(",")));
}

【12】Colectores.unión para empalme

(1) Descripción del escenario
Si hay una lista de usuarios y desea mostrar los nombres de todas las personas, debe usar comas como separadores para unir los nombres

(2) La forma de escribir antes de la optimización
La idea es sacar todos los nombres y ponerlos en la lista, y luego usar String.join para empalmar. Luego, la verificación de la especificación del código indicará que no está estandarizado.

String packUser = String.join(",",packPlans.stream().map(it->it.getPackUser()).collect(Collectors.toList()));


(3) Collectors.joining realiza directamente el método de escritura optimizado

String packUser = list.stream().collect(Collectors.joining(","));

[13] El método de mapa realiza operaciones de conversión en los datos

El papel de la función de mapa es realizar operaciones de conversión en cada elemento de datos en el flujo de canalización

(1) Caso 1
Convierta cada cadena de caracteres de la colección a mayúsculas

List<String> alpha = Arrays.asList("Monkey", "Lion", "Giraffe", "Lemur");

//不使用Stream管道流
List<String> alphaUpper = new ArrayList<>();
for (String s : alpha) {
    
    
    alphaUpper.add(s.toUpperCase());
}
System.out.println(alphaUpper); //[MONKEY, LION, GIRAFFE, LEMUR]

// 使用Stream管道流
List<String> collect = alpha.stream().map(String::toUpperCase).collect(Collectors.toList());
//上面使用了方法引用,和下面的lambda表达式语法效果是一样的
//List<String> collect = alpha.stream().map(s -> s.toUpperCase()).collect(Collectors.toList());

System.out.println(collect); //[MONKEY, LION, GIRAFFE, LEMUR]

(2) Caso 2
Procesamiento de elementos de colección de tipo no cadena
La función de mapa no solo puede procesar datos, sino también convertir el tipo de datos

List<Integer> lengths = alpha.stream()
        .map(String::length)
        .collect(Collectors.toList());

System.out.println(lengths); //[6, 4, 7, 5]
Stream.of("Monkey", "Lion", "Giraffe", "Lemur")
        .mapToInt(String::length)
        .forEach(System.out::println);

Salida: 6 4 7 5

Excepto mapToInt. También hay usos como maoToLong, mapToDouble, etc.

(3) Caso 3: función de vista previa
Conversión de formato de datos de objeto de procesamiento
Aumente la edad de cada Empleado en un año, reemplace "M" en género con "masculino" y reemplace F con Femenino.

public static void main(String[] args){
    
    
    Employee e1 = new Employee(1,23,"M","Rick","Beethovan");
    Employee e2 = new Employee(2,13,"F","Martina","Hengis");
    Employee e3 = new Employee(3,43,"M","Ricky","Martin");
    Employee e4 = new Employee(4,26,"M","Jon","Lowman");
    Employee e5 = new Employee(5,19,"F","Cristine","Maria");
    Employee e6 = new Employee(6,15,"M","David","Feezor");
    Employee e7 = new Employee(7,68,"F","Melissa","Roy");
    Employee e8 = new Employee(8,79,"M","Alex","Gussin");
    Employee e9 = new Employee(9,15,"F","Neetu","Singh");
    Employee e10 = new Employee(10,45,"M","Naveen","Jain");


    List<Employee> employees = Arrays.asList(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10);

    /*List<Employee> maped = employees.stream()
            .map(e -> {
                e.setAge(e.getAge() + 1);
                e.setGender(e.getGender().equals("M")?"male":"female");
                return e;
            }).collect(Collectors.toList());*/

    List<Employee> maped = employees.stream()
            .peek(e -> {
    
    
                e.setAge(e.getAge() + 1);
                e.setGender(e.getGender().equals("M")?"male":"female");
            }).collect(Collectors.toList());

    System.out.println(maped);

}

Dado que el parámetro e del mapa es el valor de retorno, se puede usar la función de observación. La función de observación es una función de mapa especial. Cuando la función no tiene valor de retorno o el parámetro es el valor de retorno, se puede usar la función de observación.

(4) Caso 4: El
mapa de funciones flatMap puede convertir los datos en el flujo de la tubería, pero ¿qué se debe hacer si todavía hay tuberías en la tubería? Es decir: cómo manejar arreglos bidimensionales y clases de colección bidimensionales. Para lograr un requisito simple:

Imprime el conjunto de dos cadenas que consisten en "hola" y "mundo", y cada letra del elemento. ¿Cómo podemos escribir sin Stream? Escriba 2 capas de bucles for, la primera capa atraviesa la cadena y divide la cadena en matrices de caracteres, y la segunda capa de bucles for atraviesa la matriz de caracteres.

List<String> words = Arrays.asList("hello", "word");
words.stream()
        .map(w -> Arrays.stream(w.split("")))    //[[h,e,l,l,o],[w,o,r,l,d]]
        .forEach(System.out::println);

Es imposible usar el método del mapa, y este requisito no puede cumplirse con el método del mapa. El mapa solo puede operar en matrices unidimensionales. Hay matrices en matrices y tuberías en tuberías. No puede manejar todos los elementos.

inserte la descripción de la imagen aquí

flatMap puede entenderse como una expansión plana de todos los datos en varios subcanales en el canal principal para su procesamiento.
inserte la descripción de la imagen aquí

words.stream()
        .flatMap(w -> Arrays.stream(w.split(""))) // [h,e,l,l,o,w,o,r,l,d]
        .forEach(System.out::println);

【3】Otros casos de estudio

[1] Optional.ofNullable: sentencia no nula

(1) Función

A menudo se encuentra en el trabajo que la consulta devuelve nulo Si no hay un juicio nulo, se producirá una excepción de puntero nulo si no tiene cuidado. También es posible agregar procesamiento de sentencia if, pero jdk1.8 tiene un método de procesamiento más elegante.

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));
}

Si la colección de listas no está vacía, asigne la colección de listas a newList; si la colección de listas está vacía, cree una colección de objetos vacía y asígnela a newList para asegurarse de que la colección de listas nunca esté vacía y evitar las excepciones de puntero nulo.

(2) Combinaciones comunes

(1) Optional.ofnullable().orelse()
Optional.ofnullable().orelse() es un método de la clase Optional en Java 8, que se utiliza para juzgar si el objeto Optional está vacío y devolver un valor predeterminado si lo está. vacío. El método ofNullable() se usa para crear un objeto opcional y el método orElse() se usa para devolver un valor predeterminado. Si el objeto Opcional no es nulo, devuelve el propio objeto Opcional. Este método se puede utilizar para evitar la excepción NullPointerException.

List<String> lists = null;
List<String> list = new ArrayList<String>();
list.add("你好");
list.add("hello");
List<String> newList = Optional.ofNullable(list).orElse(lists);

(2) Optional.ofnullable().ifpresent
es un método de la clase Optional en Java 8, y su función es realizar una operación cuando el objeto Optional no está vacío. No hace nada si el objeto Opcional está vacío.

(3) El principio del código fuente

//静态变量 empty
private static final Optional<?> EMPTY = new Optional<>();
 
//如果对象为空,执行empty()方法;不为空,执行of(value)方法
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. Primero ejecute el método ofNullable(), si el objeto T está vacío, ejecute el método vacío(), si no está vacío, ejecute el método of(value), 2. Método vacío(), inicialice un objeto vacío
Opcional (objeto vacío y nulo no son lo mismo)
3. método de (valor), use el objeto genérico T para el parámetro del método de construcción opcional y devuelva un objeto valorado
4. Después de los dos pasos anteriores, es garantizado que el Opcional no es nulo, evitando un puntero nulo;

(4) Casos de uso

Si el resultado no es nulo, realice las siguientes operaciones, si es nulo, no realice ninguna operación

Optional.ofNullable(result)
                .map(ApiResponse::getData)
                .ifPresent(it -> {
    
    
                    if (StrUtil.isNotBlank(it.getTmpScriptContent())) {
    
    
                        HiveSqlFieldLineageParser parser = HiveSqlFieldLineageParser.build(
                                it.getTmpScriptContent(), false, false);
                        it.setErrors(parser.getErrors());
                    }
                });

Supongo que te gusta

Origin blog.csdn.net/weixin_44823875/article/details/130668095
Recomendado
Clasificación