JDK 1.8 流式编程在数据处理方面的应用

jdk1.8 List集合Stream流式处理 Java 8 引入了一个新的抽象层——Stream API,它允许你以声明性方式处理数据集合(包括数组、集合等)。Stream API 提供了一种高效且易于表达的方式来处理数据集合,包括过滤、排序、映射和归约等操作。这种处理方式极大地提高了代码的可读性和可维护性,同时也提升了处理大量数据的性能。Stream(流)是 Java 8 引入的一个关键抽象概念,它代表了一个来自数据源的元素队列并支持聚合操作。 阅读详情

Stream流式编程在JDK 1.8版本中与Lambda表达式一起推出,这一特性标志着JDK 1.8成为Java历史上的又一里程碑。之前在公司接手的关于数据分析及展示需求中就会频繁地使用到Stream流式编程。今天来看一看Stream流式编程在数据分析方面的应用及原理,并且这里会再次带大家回顾一下Lambda表达式的使用。

一、Lambda表达式

之前写过关于JDK函数式编程的文章,可以先进行了解:
https://blog.youkuaiyun.com/pbrlovejava/article/details/85226974

1.1、基本使用

在介绍Stream流式编程之前,需要先了解Lambda表达式的使用及基本原理。

一般使用Lambda表达式的场景是优化匿名内部类的繁琐声明,以达到简化代码的效果,譬如在JDK 1.7版本,我们需要声明一个线程(Thread)并且包含一个匿名任务(Runnable)时,我们会这样做:

  • JDK 1.7版本
public static void main(String[] args) {
        Runnable task = new Runnable() {
            @Override
            public void run() {
                // 具体的任务执行内容
            }
        };
        Thread thread = new Thread(task);
        thread.start();
    }

这里的task的本质是一个实现了Runnable接口的匿名内部类,最后在new Thread(task)时将其传入构造方法中,以创建一个线程来执行这段任务。

当然,我们还可以进一步进行简化:

  • JDK 1.7版本(简化)
public static void main(String[] args) {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                // 具体的任务执行内容
            }
        });
        thread.start();
    }

我们可以直接在创建Thread时,直接在构造函数中传入new Runnable并重写run方法,实现具体的任务执行内容。

此时,若没有Idea的帮助,写出这段代码你至少需要记得:

  1. Thread类构造方法可传入类型
  2. 传入类型需要重写的方法

但是这种写法很麻烦,我们明明知道这样写不过是为了符合当初的构造定义,但是确实有些脱裤子放屁的意思,此时,Lambda表达式的出现解决了这一问题:

我们只需要记住匿名内部类需要被重写的方法参数及返回值,剩下的,交给Lambda就好了!

  • JDK 1.8(Lambda)
public static void main(String[] args) {
        Thread thread = new Thread(()->{
            // 具体的任务执行内容
        });
        thread.start();
    }

多么地简单明了?现在代码看起来变得更易于阅读了。下面再举几个例子来看看:

  • 实现大顶堆(JDK 1.7)
public static void main(String[] args) {
    PriorityQueue<Integer> maxHeap = new PriorityQueue<>(new Comparator<Integer>() {
        @Override
        public int compare(Integer x, Integer y) {
            return y - x;
        }
    });
}
  • 实现大顶堆(JDK 1.8 Lambda)
public static void main(String[] args) {
    PriorityQueue<Integer> maxHeap = new PriorityQueue<>((x, y) -> y - x);
}

是不是可以很明显地看出差距了呢,使用Lambda表达式只需要一行就可以声明一个大顶堆,而不需要手动创建比较器、重写比较器方法这两个步骤。

最后需要注意的是:在使用Lambda表达式去代替匿名接口重写方法时,这个接口有且只有唯一的一个抽象方法,不然Lambda表达式无法判断需要重写哪个方法。

1.2、实现原理

看完了基本使用后,现在来了解一下Lambda表达式的实现原理。

还是上面那段代码,Debug可以发现:
在这里插入图片描述
当执行到Lambda表达式的时候,其实是通过字节码技术与反射技术,生成了相应的匿名内部类实现。(因为是在内存中生成,所以只能通过Idea查看运行时状态)

所以使用Lambda表达式时,相较于普通的匿名内部类方式会产生额外的字节码生成及反射带来的效率损失,但是只要不是特别频繁地、多地的使用,一般察觉不到。

更深入地了解请阅读:

https://cloud.tencent.com/developer/article/1328370

二、Stream流式编程

Stream流式编程的使用依赖于Lambda表达式,是JDK 1.8的一大特点所在。使用Stream流式编程可以很方便和灵活地处理数据,而不需要通过数据库去做额外的处理,所以被广泛地应用在数据处理相关程序中。

2.1、Stream API 和 Lambda Expression实现遍历的Demo

现在假设我们需要获取List< String >中首字母为a的数据,可以有以下两种写法,我们可以发现使用流式编程和Lambda表达式后会更加地凝练:
获取流-过滤流-遍历流。

		 String[] arrays = {"a1","a2","b","c"};
        //将arrays转化为List<String>
        List<String> stringList = Arrays.asList(arrays);

        //原始的处理方法
        for (String s : stringList) {
            if(s.charAt(0) == 'a'){
                System.out.println(s);
            }
        }
        
        //Stream API 结合 Lambda Expression
        stringList.stream()
                     .filter(s->s.charAt(0) == 'a')
                     .forEach(s-> System.out.println(s));


2.2、Stream常用方法

Stream是在Java 8之后更新的一种流,它不同于io流中的InputStream、OutputStream等,准确地说,这个位于java.util下的Stream和io中的流毫无关系。这里的Stream是数据流和对象流。

2.2.1、 of(T… values)

要把List、Set转化为数据流可以使用xxxList.stream()或者使用Stream.of(T…values),T…values代表着数组或者是不定数量的数据,它们会按顺序转换成数据流。

  • 获得Stream的三种方式
		//1
        Stream<String> stringStream1 = Stream.of(new String[]{"a","b","c"});
        //2
        Stream<String> stringStream2 = Stream.of("a","b","c");
        //3
        Stream<String> stringStream3 = stringList.stream();
2.2.2、filter(Predicate<? super T> predicate)

filter用以将流按需过滤成新的流,需要传入的参数为一个位于java.util.function下的Predicate接口并重写test方法去进行校验:

Stream newStream = stringList.stream().filter(new Predicate() {
            @Override
            public boolean test(Object s) {
                if (s.toString().charAt(0) == 'a') {
                    return true;
                }
                return false;
            }
        });

利用Lambda表达式,我们可以将上述代码简化为:

Stream newStream = stringList.stream().filter(s->s.charAt(0) == 'a');
2.2.3、 forEach(Consumer<? super T> action)

对此流的每一个元素进行操作,需要传入的参数为Consumer接口并且实现其accept方法:

stringStream.forEach(new Consumer(){
            @Override
            public void accept(Object s) {
                System.out.println(s);
            }
        });

结合Lambda表达式:

stringStream.forEach(s->System.out.println(s));
2.2.4、map(Function<? super T,? extends R> mapper)

map方法的作用是对Stream进行处理并且返回一个其他对象充当原Stream。

  • 将数据转换为大写
 String[] arrays = {"a1","a2","b","c"};
        //将arrays转化为List<String>
        List<String> stringList = Arrays.asList(arrays);
        List<String> collect = stringList.stream()
                .map(String::toUpperCase)
                .collect(Collectors.toList());
        System.out.println(collect);

需要说明的是,map方法需要传入的参数是一个函数式方法,可以使用lambda表达式也可直接使用双冒号表达式(现在可以将双冒号表达式::理解为对象通过::调用方法并且传入当前的数据作为参数);而collect方法则是将经过map处理的流“收集”起来形成新的流,传递参数Collectors.toList()表示以List的形式转化流。

  • 删除末尾的数字
List<String> collect1 = Stream.of(arrays)
                .filter(v -> v != null)
                .map(v -> {
                    if (v.length() == 2) {
                        //删除尾部
                        v = v.substring(0, v.length()-1);
                    }
                    //返回最终结果
                    return v;
                })
                .collect(Collectors.toList());
        System.out.println(collect1);
  • 将Person对象转化为Student对象
    class Person implements Serializable {
            //编号
            private int id;
            //姓名
            private String name;
            //年龄
            private int age;
            //getter setter...
        }

        class Student implements Serializable {
            //学号
            private int schoolId;
            //姓名
            private String name;
            //年龄
            private int age;
            //getter setter...
        }


        public static void main(String[] args) {
            List<Person> personList = Arrays.asList(new Person(1, "lily", 18)
                , new Person(2, "arong", 19)
                , new Person(3, "joke", 20));
        //将PersonList转化为Studentlist
        List<Student> studentList = personList.stream().map(p -> {
            Student student = new Student();
            student.setSchoolId(3111000 + p.getId());
            student.setName(p.getName());
            student.setAge(p.getAge());
            //将转化好的student作为结果返回
            return student;
        }).collect(Collectors.toList());
        
        System.out.println(studentList.toString());

        }
    }

三、使用Stream和Lambda表达式进行数据处理

3.1、基本应用

现在来看看Stream流式编程在数据处理方面的一些优势。

假设有这么一个需求,前端需要获取到后端这边提供的基础监控数据用以展示,基础监控数据和MySQL交互的VO已经封装成如下:

  • BasicDataVO
/**
 * @Auther: ARong
 * @Date: 2020/7/9 5:59 下午
 * @Description: 基础数据VO
 */
public class BasicDataVO {
    private String name; // 数据名称
    private String type; // 数据类别
    private int count;   // 数据数量

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getType() {
        return type;
    }
    public void setType(String type) {
        this.type = type;
    }
    public int getCount() {
        return count;
    }
    public void setCount(int count) {
        this.count = count;
    }

    @Override
    public String toString() {
        return "BasicDataVO{" +
                "name='" + name + '\'' +
                ", type='" + type + '\'' +
                ", count=" + count +
                '}';
    }
}

现在需要在一个页面中展示如下数据表格:

  1. 数量前三的基础数据(根据数量排序)
  2. 类别为"国内"的基础数据(根据数量排序)
  3. 将类别"海外"的基础数据中的数量进行精度修正并和全量数据一起返回(根据数量进行排序)

如果按正常的编程逻辑,这3个需求需要查询3次数据库,跑3个不同的SQL以组合成所需的数据集:

  • BasicDataController
@Controller
public class BasicDataController {
    @RequestMapping("/getBasicData")
    public Map<String, List<BasicDataVO>> getBasicData() {
        HashMap<String, List<BasicDataVO>> res = new HashMap<String, List<BasicDataVO>>();
        // 数量前三的基础数据(根据数量排序)
        List<BasicDataVO> dataList1 = queryLimit3OrderByCount();
        // 类别为"国内"的基础数据(根据数量排序)
        List<BasicDataVO> dataList2 = queryType1OrderByCount();
        // 将类别"海外"的基础数据中的数量进行精度修正并和全量数据一起返回(根据数量进行排序)
        List<BasicDataVO> dataList3 = queryType2AndFixDataOrderByCount();
        // 数据封装
        res.put("list1", dataList1);
        res.put("list2", dataList2);
        res.put("list3", dataList3);
        return res;
    }
}

当然这是没有问题的,但是为了3份区别不大的数据进行了3次MySQL连接和查询,这其实是比较浪费资源的,所以另外的方案就是先查询出通用数据,然后在通用数据的基础上使用Steam流式编程与Lambda表达式获取到所需的定制化数据:

  • BasicDataController
@Controller
public class BasicDataController {
    @RequestMapping("/getBasicData")
    public Map<String, List<BasicDataVO>> getBasicData() {
        HashMap<String, List<BasicDataVO>> res = new HashMap<String, List<BasicDataVO>>();
        // 获取通用数据
        List<BasicDataVO> dataList = queryBasicData();
        // 数量前三的基础数据(根据数量排序)
        List<BasicDataVO> dataList1 = dataList.stream()
                .sorted((x, y) -> x.getCount() - y.getCount())
                .limit(3)
                .collect(Collectors.toList());
        // 类别为"国内"的基础数据(根据数量排序)
        List<BasicDataVO> dataList2 = dataList.stream()
                .filter(x -> "国内服务器".equals(x.getType()))
                .sorted((x, y) -> x.getCount() - y.getCount())
                .collect(Collectors.toList());
        // 将类别"海外"的基础数据中的数量进行精度修正并和全量数据一起返回(根据数量进行排序)
        // 此处存在浅拷贝问题
        List<BasicDataVO> dataList3 = dataList.stream().map(x -> {
            x.setCount(fixData(x.getName()));
            return x;
        })
        .sorted((x, y) -> x.getCount() - y.getCount())
        .collect(Collectors.toList());
        // 数据封装
        res.put("list1", dataList1);
        res.put("list2", dataList2);
        res.put("list3", dataList3);
        return res;
    }
}
3.2、基本原理

Stream流的原理和实现是很复杂的,这里只是作为简单学习和了解,需要深入了解请点击这篇文章,讲的很好:

https://www.cnblogs.com/CarpenterLee/p/6637118.html

当使用list.stream()的时候,会返回一个Stream对象,这是因为在JDK 1.8中,开发者们修改了Collection,即集合框架的顶层接口,并在里头新增了一个钩子方法:

  • Collection
public interface Collection<E> extends Iterable<E> {

    default Stream<E> stream() {
            return StreamSupport.stream(spliterator(), false);
    }

}

这个钩子方法就是stream(),然后通过StreamSupport这个类获取到相应的流对象。

  • StreamSupport
 public static <T> Stream<T> stream(Spliterator<T> spliterator, boolean parallel) {
        Objects.requireNonNull(spliterator);
        return new ReferencePipeline.Head<>(spliterator,
                                            StreamOpFlag.fromCharacteristics(spliterator),
                                            parallel);
}

可以看到,StreamSupport会新创建一个ReferencePipeline.Head这个类,看到Head会不会有些眼熟?是的,整个Stream是通过一个双向链表组织起来的,每一个阶段会对应着一个Stream:

在这里插入图片描述

Java8 函数式编程 Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来对 Java 集合运算和表达的高阶抽象。Stream API 可以极大提高 Java 程序员的生产力,让程序员写出高效率、干净、简洁的代码。这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 变换,聚合等。 阅读详情

相关推荐

流式编程 JDK8 Stream的简单使用方法介绍

JDK8 Stream 文章目录JDK8 Stream概念特点代码简洁多核友好示例foreach方式Stream方式流程操作特性常用操作符具体用法一、流的创建1.1使用Collection下的 stream() 和 parallelStream() 方法。1.2 使用Arrays 中的 stream() 方法,将数组转成流。1.3 使用Stream中的静态方法:of()、iterate()、generate()。1.4 使用 BufferedReader.lines() 方法,将每行内容转成流。1.5 使用

enjoy678的博客 893

Java基础(4)-Java8函数式编程

文章目录一、Lambda表达式1.1、用Lambda表达式代替匿名内部类1.2、Lambda表达式的参数类型判断二、Stream API2.1、Stream API 和 Lambda Expression实现遍历的Demo2.2、Stream常用方法2.2.1、 of(T... values)2.2.2、filter(Predicate&amp;amp;amp;amp;amp;amp;amp;amp;lt;? super T&amp;amp;amp;amp;amp;amp;amp;amp;g

BoringError的博客 2247

java1.8流式用法-工作使用总结经验

工作中经常需要用到流的用法,通过使用流让程序的阅读性更强,代码更简洁。

ZhiguoXue_IT的博客 346

【转】Java8 函数式编程详解

1.Java函数式编程的语法: 使用Consumer作为示例,它是一个函数式接口,包含一个抽象方法accept,这个方法只有输入而无输出也就是说这个方法无返回值。 现在我们要定义一个Consumer接口的实例化对象,传统的方式是这样定义的: public static void main(String[] args) { //JDK1.8版本之前的做法 Consumer<Integer> con = new Consumer<Integer>() { @Override

魂-淡 2588

Linux系统上JDK1.8的安装与配置指南

本文还有配套的精品资源,点击获取 简介:本文详细介绍了在64位Linux操作系统上安装和配置Java Development Kit 1.8(JDK 1.8)的过程。内容包括JDK 1.8的新特性、64位操作系统的必要性、使用.tar.gz格式文件的细节、具体的安装步骤、安装验证方法、Java开发与运行环境的设置、Oracle JDK的更新与维护、替代选择OpenJDK的介...

weixin_28933797的博客 4534

JDK1.8中文API文档及Java 8特性深入解析

Lambda表达式是Java 8引入的一种简洁的表示可传递的匿名函数的方式,使得Java语言支持了函数式编程。Lambda表达式可以被看作是匿名内部类的简化表达,其基本构成包括参数、箭头(->)和函数体。参数和函数体都可选。具体形式可以表示为:(参数1, 参数2…) -> { 函数体 }。// 一个简单的Lambda表达式示例:一个无参、无返回值的Lambda表达式Lambda表达式要求参数类型可以省略(编译器根据上下文进行推断),如果参数只有一个,连圆括号也可以省略;

weixin_29097457的博客 1141

JDK8 新特性流式数据处理

在学习JDK8新特性Optional类的时候,提到对于Optional的两个操作映射和过滤设计到JDK提供的流式出来。这篇文章便详细的介绍流式处理

不能说的秘密的博客 2万+

5G LDPC编码实战:从校验矩阵到Matlab代码实现(附完整源码)

本文深入解析5G NR标准中的LDPC编码工程实现,聚焦于从3GPP协议中的QC-LDPC校验矩阵到高效Matlab代码的转换。文章详细阐述了基础矩阵(BG1/BG2)选择、提升因子确定以及利用双对角结构的快速编码算法,并提供了完整的、可优化的Matlab源码,旨在帮助通信算法工程师和开发者快速构建5G LDPC编码仿真原型,为硬件实现奠定基础。

table的专栏 377

JDK1.8新特性Stream流式操作,简化遍历操作

一. 前言 随着Java的发展,越来越多的企业开始使用JDK1.8 版本。JDK1.8 是自 JDK1.5之后最重要的版本,这个版本包含语言、编译器、库、工具、JVM等方面的十多个新特性。本次文章将着重学习Stream。 Stream 是JDK1.8 中处理集合的关键抽象概念,Lambda 和 Stream 是JDK1.8新增的函数式编程最有亮点的特性了,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。使用Stream API 对集合数据进行操

Thinkingcao的专栏 1万+

OpenAI Codex 国内安装配置全攻略:从零到实战的 AI 编程助手集成指南

AI 编程助手正成为提升开发效率的关键工具,其核心原理是基于大规模语言模型对代码语义进行深度理解与生成。这类技术通过将自然语言指令转化为可执行的代码、自动化重构与调试,为开发者提供了智能化的结对编程体验,其技术价值在于显著降低编码复杂度、加速项目迭代。在实际应用场景中,AI 编程助手可集成于日常开发流,辅助完成代码生成、项目分析与自动化任务。本文聚焦于 OpenAI 的 Codex,针对国内开发者在网络、认证和配置上的常见挑战,提供了涵盖多种安装方式、详细配置步骤及核心使用技巧的实战指南,并特别介绍了如何利

weixin_28715081的博客 415

DPO(Direct Preference Optimization)实战全流程指南

《DPO实战全流程指南》摘要 本文提供了端到端的DPO(直接偏好优化)实战方案,包含数据准备、模型训练、评估部署全流程。核心内容包括: 数据构建:推荐UltraFeedback等高质量数据集,提供数据预处理代码 训练配置:基于HuggingFace TRL库的DPO实现,详解beta值等关键参数调优 工业优化:显存节省技巧(LoRA、梯度检查点)、领域自适应方法和在线学习架构 效果评估:量化对比显示DPO可降低86%有害回复率,提升24%用户满意度 常见问题:针对灾难性遗忘、过度安全化等问题给出解决方案 附

技术引领业务创新 1468

jdk1.8新特性——Stream流式编程

Stream流是Java 8新加入的最常用的流接口,位于java.util.stream包下(java.util.stream.Stream ),这并不是一个函数式接口,接口里面包含了很多抽象方法,这些方法对于Stream流的操作都是至关重要的,最常见的方法有filter、map、foreach、count、limit、skip、concat 获取Stream流的两种方法 所有的 Collection 集合都可以通过 stream 默认方法获取流,stream()方法是Collection集合接口的一个默

can_chen的博客 2383

FFmpeg入门详解之110:RTSP协议讲解

TCP/IP 协议体系中的一个应用层协议,该协议定义了一对多应用程序如何有效地通过 IP 网络传送多媒体数据。RTSP在体系结构上位于RTP和RTCP之上,它使用TCP或UDP完成数据传输。HTTP与RTSP相比,HTTP传送HTML,而RTSP传送的是多媒体数据。正在上传…重新上传取消RTSP是基于文本的协议,采用ISO10646字符集,使用UTF-8编码方案。行以CRLF中断(\r\n:10,13:0x0A,0x0D),包括消息类型、消息头、消息体和消息长。

福优学苑@音视频+流媒体 2529

Java8 :流式数据处理

java8的流式处理极大了简化我们对于集合、数组等结构的操作,让我们可以以函数式的思想去操作,本篇文章将探讨java8的流式数据处理的基本使用。 一. 流式处理简介 在我接触到java8流式处理的时候,我的第一感觉是流式处理让集合操作变得简洁了许多,通常我们需要多行代码才能完成的操作,借助于流式处理可以在一行中实现。 比如我们希望对一个包含整数的集合中筛选出所有的偶数,并将其封装成为一个...

琦彦 1万+

STEP 7-Micro/WIN SMART 编程软件:从入门到精通的使用指南

通过不断实践,熟悉软件的各项功能和操作技巧,工程师可更好地应对工业自动化控制中的各种挑战,开发出高效、稳定的控制程序。项目的基本组件是构成程序的核心元素,包括:程序块(主程序 OB1、子程序和中断程序)、数据块(给 V 存储器赋初值)、系统块(硬件组态和参数设置)、符号表(用符号代替存储器地址,使程序更易理解)以及状态图表(监视、修改和强制变量状态)。下载程序时,单击工具栏上的 “下载” 按钮,在弹出的下载对话框中选择要下载的块(程序块、数据块、系统块),单击 “下载” 即可。

电工 5575

YOLOv11改进策略【Neck】| ASF-YOLO 注意力尺度序列融合模块改进颈部网络,提高小目标检测精度

ASF-YOLO是一种基于YOLO的新颖框架,结合了空间和尺度特征以实现准确和快速的分割。其中,注意力尺度序列融合模块。

Limiiiing的博客 4394

JDK1.8新增的Stream的使用及原理

可以说函数式编程,Lambda 和 Stream 是JDK1.8新增的最有亮点的特性了。在学习Apache Flink 的时候,经常遇到算子运算,其实这就是一种最常用的Stream流编程运算,今天就来研究一下Java 的JDK1.8提供的Stream流式编程,以便对后续学习Flink和Spark还有Strom这些流式和批式处理框架有所帮助。 新的java.util.stream包...

leehsiao的专栏 1万+

大疆前端开发面试题及参考答案(4万字长文)

在前端项目中,难点和性能优化的挑战无处不在。比如在处理复杂交互界面时,实现流畅的动画效果和实时反馈就是一大难点。当界面中有大量元素需要同时进行交互和动态更新,像电商平台的商品筛选和排序功能,不仅要保证操作的即时响应,还要确保界面在各种设备和网络环境下的稳定性,这就需要对事件处理、DOM 操作和数据更新机制有深入理解。在性能优化方面,首屏加载速度是常见的难点。当页面包含大量图片、脚本和样式文件时,如何合理地进行资源压缩、合并与缓存,以减少加载时间,是需要精心考虑的。

大模型大数据攻城狮的专栏 1155

JDK1.8,Java8常用新特性

A.Lamdba表达式 1.Java8概述 Java8,也就是jdk1.8,是意义深远的一个新版本 是Java5之后一个大的版本升级,让Java语言和库仿佛获得了新生 新特性包含: a.随着大数据的兴起,函数式编程在处理大数据上的优势开始体现,引入了Lambada函数式编程 b.使用Stream彻底改变了集合使用方式:只关注结果,不关心过程 c.新的客户端图形化工具界面库:Ja...

壹零万联的博客 5万+

打开.nc降水气象数据制作年降水量地图

图层的单位为度,在反距离插值中也是以度为单位,比较麻烦,还是想用以m为单位的投影,这里是个bug,后续调整一下。该彩色部分是以2021年1月、2月、3月的降水数据分别作为RGB得到。因为该栅格的分辨率还是太大了,一个栅格就能覆盖一个县,若想要进行降尺度,可以做插值处理。下载的数据集为2021-2022年,因此有12+12=24个月,24个波段。想要得到廊坊市周围的数据,需要裁剪范围,在降水数据图层上导出数据。打开数据管理工具-投影和变换-定义投影。在降水数据图层上右击属性,添加投影。得到了降尺度的插值图。

所有专家都曾始于新手 4520

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

## JDK8流式(Stream)API处理集合

JDK8流式(Stream)API处理集合 流式API是JDK8中新增的一项函数式编程技术,可以通过API中提供的相关接口,方法轻松简洁的实现对于集合元素的过滤,搜索,排序,收集等操作。流式API处理接口分为以下几个步骤: 获取Stream对象 过滤,映射 遍历,排序,统计,收集等操作 实例: public class Demo { public static void main(Stri...

RequirementJava的博客 542

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

JDK8新特性

JDK8 常用新特性。

2301_78985459的博客 1404

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

JDK7和JDK8的区别

面试总是遇到这个问题,做一个小总结,可能总结的不全 1. 接口中的default方法 一般来说接口中的方法都是不实现的,基本通过实现类来实现方法。但是jdk8中提供了一种被default修饰的方法,可以直接在接口中进行实现。 2. lambda表达式 jdk8引入了lambda表达式,也可称为closure(闭包),通常是在需要一个函数,但又不想费神去命名一个函数的场合下使用,也就是指匿名函数。 lambda允许把函数作为一个方法的参数(函数作为参数传递进方法中)。 由于其几乎被所有主流开发语言支持。是ja

weixin_44844089的博客 6518

这一篇带你学点儿 Java8 中的流式数据处理

作者:琦彦blog.csdn.net/fly910905/article/details/87533856java8的流式处理极大了简化我们对于集合、数组等结构的操作,让我们可以以函数式...

Java知音 733
上一篇: 记四至六月:春华秋实,做好当下,切勿急躁,避免焦虑
下一篇: 记录在阿里云的这段日子
BoringRong
BoringRong 领域专家: 后端开发技术领域 领域专家: 后端开发技术领域
博客等级 码龄9年 2万+粉丝 386原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BoringRong

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值