首页 > 编程语言 >使用java对栅格数据的处理,对栅格文件进行导入导出

使用java对栅格数据的处理,对栅格文件进行导入导出

时间:2024-09-09 16:52:40浏览次数:15  
标签:info gt java log 栅格数据 栅格 org new String

需求背景:

对栅格文件进行导入导出(使用代码的方式,非命令方式);

当然也可以使用代码和GDAL的方式进行,但是GDAL配置部署不便捷,故选用GeoTools方式来实现。

ps:若是使用命令方式,首先打开PostgreSQL的安装目录【\PostgreSQL\14\bin】,然后使用如下命令即可实现把栅格文件导入到数据库中:

# 指定切片大小
raster2pgsql -s 4326 -I -C -M D:\model\tif\TDM1_DEM__30_N34E108_DEM.tif -F -t 256x256 sdx.tdm1_dem | psql -h 192.168.31.200 -p 5432 -U postgres -d testShp

# 4326 是ESP
# 256*256 是切片大小
# sdx.tdm1_dem 是哪个模式下的哪个表,也可以是public.tdm1_dem
# -h 192.168.31.200 是数据库地址
# -p 5432 端口
# -U postgres 用户名
# -d testShp 数据库名


# 自动切片大小
raster2pgsql -s 4326 -d -k -N -e -I -C -M "D:\model\tif\TDM1_DEM__30_N34E108_DEM.tif" -F -t auto public.raster_data | psql -h 192.168.31.200 -p 5432 -d testdb -U postgres

 若是使用代码导入的思路:

  • 配置好前置条件
  • 读取栅格数据
  • 连接到数据库
  • 创建表
  • 将数据插入到数据库中

实现:

1、配置好前置条件

  • 确保你的PostgreSQL数据库已安装并启用了PostGIS扩展
-- 安装PostGIS扩展
CREATE EXTENSION postgis;

-- 安装PostGIS的栅格支持
CREATE EXTENSION postgis_raster;
  • 确认PostGIS版本

确保你使用的是支持栅格数据的PostGIS版本。你可以使用以下命令来检查PostGIS版本:

SELECT POSTGIS_VERSION();
-- 查看函数
SELECT proname, proargtypes, prosrc
FROM pg_proc
JOIN pg_namespace ON pg_namespace.oid = pg_proc.pronamespace
WHERE proname = 'st_fromgdalraster';

SELECT proname, proargtypes
FROM pg_proc
JOIN pg_namespace ON pg_namespace.oid = pg_proc.pronamespace
WHERE proname LIKE 'st_f%' AND pg_namespace.nspname = 'public';

-- 查看扩展
SELECT postgis_full_version();

确保返回的版本信息显示PostGIS包含栅格支持

2、读取栅格数据、保存数据到数据库

添加依赖

        <gt.version>20.0</gt.version>

        <!-- 添加GeoTools依赖 -->
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-opengis</artifactId>
            <version>${gt.version}</version>
        </dependency>

        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-api</artifactId>
            <version>${gt.version}</version>
        </dependency>

        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-data</artifactId>
            <version>${gt.version}</version>
        </dependency>

        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-jdbc</artifactId>
            <version>${gt.version}</version>
        </dependency>

        <dependency>
            <groupId>org.geotools.jdbc</groupId>
            <artifactId>gt-jdbc-postgis</artifactId>
            <version>${gt.version}</version>
        </dependency>

        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-main</artifactId>
            <version>${gt.version}</version>
        </dependency>

        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-metadata</artifactId>
            <version>${gt.version}</version>
        </dependency>

        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-referencing</artifactId>
            <version>${gt.version}</version>
        </dependency>

        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-render</artifactId>
            <version>${gt.version}</version>
        </dependency>

        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-shapefile</artifactId>
            <version>${gt.version}</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-coverage</artifactId>
            <version>${gt.version}</version>
        </dependency>
        <!-- 如果使用的 GeoTools 功能需要额外的依赖,如坐标转换,可能还需要添加这个 -->
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-epsg-hsql</artifactId>
            <version>${gt.version}</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-geojson</artifactId>
            <version>${gt.version}</version>
        </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.7.15</version>
        </dependency>


<!-- 1 栅格相关依赖 -->
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-image</artifactId>
            <version>${gt.version}</version>
        </dependency>

        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-swing</artifactId>
            <version>${gt.version}</version>
        </dependency>

        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-process</artifactId>
            <version>${gt.version}</version>
        </dependency>

        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-process-raster</artifactId>
            <version>${gt.version}</version>
        </dependency>

        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-geotiff</artifactId>
            <version>${gt.version}</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.geotools/gt-swing -->
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-swing</artifactId>
            <version>${gt.version}</version>
        </dependency>

        <!--<dependency>
            <groupId>org.jdal</groupId>
            <artifactId>jdal-core</artifactId>
            <version>2.0.0</version>
        </dependency>
-->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-imaging</artifactId>
            <version>1.0-alpha3</version>
        </dependency>

        <!--        <dependency>
                    <groupId>org.geotools</groupId>
                    <artifactId>gt-netcdf</artifactId>
                    <version>20.0</version>
                </dependency>-->

        <!-- https://mvnrepository.com/artifact/edu.ucar/netcdf -->
        <dependency>
            <groupId>edu.ucar</groupId>
            <artifactId>netcdf</artifactId>
            <version>4.3.22</version>
        </dependency>

        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-geometry</artifactId>
            <version>20.0</version>
        </dependency>

        <!-- TwelveMonkeys ImageIO TIFF -->
        <dependency>
            <groupId>com.twelvemonkeys.imageio</groupId>
            <artifactId>imageio-tiff</artifactId>
            <version>3.8.0</version>
        </dependency>

        <!-- Maven example for JAI TIFF plugin -->
        <dependency>
            <groupId>javax.media</groupId>
            <artifactId>jai-core</artifactId>
            <version>1.1.3</version>
        </dependency>

        <!--gdal-->
        <dependency>
            <groupId>org.gdal</groupId>
            <artifactId>gdal</artifactId>
            <version>3.9.0</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/net.postgis/postgis-jdbc -->
        <dependency>
            <groupId>net.postgis</groupId>
            <artifactId>postgis-jdbc</artifactId>
            <version>2024.1.0</version>
        </dependency>



        <!-- 11 栅格相关依赖 -->

实现类 


    public String importRasterData(GridDataDto gridDataDto) throws IOException {
        // 1. 连接数据库,创建模式、表相关内容 实现导入栅格数据的逻辑
        GridData gridData = gridDataDto.getParameter();
        String sourceFilePath = gridData.getSourceFilePath();
        String targetDatasource = gridData.getTargetDatasource();
        String targetDatasetName = gridData.getTargetDatasetName().toLowerCase();
        String importMode = gridData.getImportMode();
        // 解析 PostgreSQL 数据库 连接参数
        Map<String, Object> dataSourceMap = parseDatabaseParameters(targetDatasource);
        log.info("dataSourceMap = " + dataSourceMap);
        // 创建 PostgreSQL/PostGIS 表
        JDBCDataStoreFactory dsf = new PostgisNGDataStoreFactory();
        JDBCDataStore datastore = dsf.createDataStore(dataSourceMap);
        // 如果不存该模式,则创建模式schema 确保 schema 存在
        String schemaName = dataSourceMap.get("schema").toString();
        try (Connection connection = datastore.getDataSource().getConnection()) {
            Statement stmt = connection.createStatement();
            // 创建依赖扩展
            String[] extensions = {"postgis", "postgis_raster"};
            for (String extension : extensions) {
                String createExtensionSql = "CREATE EXTENSION IF NOT EXISTS " + extension;
                stmt.execute(createExtensionSql);
            }
            log.info("Extensions created successfully");

            // 检查 schema 是否存在
            String checkSchemaSql = "SELECT schema_name FROM information_schema.schemata WHERE schema_name = '" + schemaName + "'";
            ResultSet rs = stmt.executeQuery(checkSchemaSql);
            if (!rs.next()) {
                // 如果 schema 不存在,创建 schema
                String createSchemaSql = "CREATE SCHEMA " + schemaName;
                stmt.execute(createSchemaSql);
                log.info("schema created successfully");
            }
            // 确保表存在 根据importMode的值NONE、OVERWRITE、APPEND进行相关操作
            if ("NONE".equals(importMode) || "OVERWRITE".equals(importMode)) {
                // 删除表
                String dropTableSql = "DROP TABLE IF EXISTS " + schemaName + "." + targetDatasetName;
                stmt.execute(dropTableSql);
                // 如果表不存在,创建表
                // String createTableSql = "CREATE TABLE IF NOT EXISTS " + schemaName + "." + targetDatasetName + " (rid INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY, rast raster, srid text, filename text)";
                // 如果表不存在,创建表
                String createTableSql = "CREATE TABLE IF NOT EXISTS " + schemaName + "." + targetDatasetName +
                        " (rid SERIAL PRIMARY KEY, rast raster, srid text, filename text)";
                stmt.execute(createTableSql);
                log.info("Table created successfully");
            } else if ("APPEND".equals(importMode)) {
                // 检查表是否存在,不存在则创建
                String checkTableSql = "SELECT to_regclass('" + schemaName + "." + targetDatasetName + "')";
                rs = stmt.executeQuery(checkTableSql);
                if (!rs.next() || rs.getString(1) == null) {
                    // 如果表不存在,创建表
                    // String createTableSql = "CREATE TABLE IF NOT EXISTS " + schemaName + "." + targetDatasetName +" (rid INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY, rast raster, srid text)";
                    String createTableSql = "CREATE TABLE IF NOT EXISTS " + schemaName + "." + targetDatasetName + " (rid SERIAL PRIMARY KEY, rast raster, srid text)";
                    stmt.execute(createTableSql);
                    log.info("Table created successfully");
                }
            }
        } catch (SQLException e) {
            log.error("Failed to ensure schema exists", e);
            throw new IOException("Failed to ensure schema exists", e);
        }

        // 保存到记录表中
        ServerImportInfo serverImportInfo = new ServerImportInfo();
        BeanUtils.copyProperties(gridData, serverImportInfo);
        Date now = new Date();
        serverImportInfo.setCreateTime(now);
        serverImportInfo.setStartTime(now);
        serverImportInfo.setUpdateTime(now);
        serverImportInfo.setState("RUNNING");
        serverImportInfo.setDataType("栅格-导入");
        serverImportInfoService.save(serverImportInfo);
        // 数据库相关连接和判断完成,下面实现
        // 2. 读取栅格数据
        try {
            File file = new File(gridData.getSourceFilePath());
            GeoTiffReader reader = new GeoTiffReader(file);
            GridCoverage2D coverage = reader.read(null);
            System.out.println("coverage = " + coverage);
            log.info("栅格数据读取完成");
            if (coverage != null) {
                // 获取和打印坐标参考系统信息
                CoordinateReferenceSystem crs = coverage.getCoordinateReferenceSystem();
                System.out.println("CRS: " + crs);
                // 获取栅格图像
                RenderedImage image = coverage.getRenderedImage();
                System.out.println("image = " + image);
                // 获取栅格的范围(Envelope)
                Envelope2D envelope = coverage.getEnvelope2D();
                System.out.println("Raster bounds: " + envelope.toString());
                System.out.println("Raster read successfully!");
            } else {
                System.err.println("Failed to read raster data.");
            }
            // 3. 导入栅格数据
            Integer saveRaster = storeRasterIntoDatabase(datastore, sourceFilePath, schemaName, targetDatasetName);
            System.out.println("saveRaster = " + saveRaster);
            log.info("栅格数据导入完成");
            // 4. 更新导入状态 判断是否大于0
            if (saveRaster > 0) {
                serverImportInfo.setState("FINISHED");
            } else {
                serverImportInfo.setState("FAILED");
            }
            // 5. 保存导入信息
            saveGridInfo(serverImportInfo);
            log.info("导入信息保存完成");

        } catch (Exception e) {
            log.error("导入栅格数据失败", e);
        } finally {
            // 关闭数据源
            datastore.dispose();
            log.info("数据源已关闭");
        }
        return String.valueOf(serverImportInfo.getId());
    }
public Integer storeRasterIntoDatabase(JDBCDataStore dataSource, String filePath, String schemaName, String targetDatasetName) throws IOException, SQLException, FactoryException {
        File file = new File(filePath);
        GeoTiffReader reader = new GeoTiffReader(file);
        GridCoverage2D coverage = reader.read(null);
        if (coverage == null) {
            throw new IOException("Failed to read raster data.");
        }
        RenderedImage image = coverage.getRenderedImage();
        Envelope2D envelope = coverage.getEnvelope2D();
        CoordinateReferenceSystem crs = coverage.getCoordinateReferenceSystem();
        int width = image.getWidth();
        int height = image.getHeight();
        double xPixelSize = envelope.getWidth() / width;
        double yPixelSize = envelope.getHeight() / height;
        double upperLeftX = envelope.getMinimum(0);
        double upperLeftY = envelope.getMaximum(1);
        // 获取srid
        int srid = CRS.lookupEpsgCode(crs, true);
        log.info("srid = " + srid);

        log.info("Raster size: " + width + " x " + height);
        log.info("Pixel size: " + xPixelSize + " x " + yPixelSize);
        log.info("Upper-left corner: " + upperLeftX + ", " + upperLeftY);
        String tableName = schemaName + "." + targetDatasetName;
        // Convert GridCoverage2D to image
        File tempFile = File.createTempFile("raster", ".tif");
        GeoTiffWriter writer = null;
        try {
            writer = new GeoTiffWriter(tempFile);
            writer.write(coverage, null);
        } finally {
            if (writer != null) {
                // Dispose of the writer to release resources
                writer.dispose();
            }
        }
        byte[] rasterData = convertCoverageToByteArray(coverage);
        //System.out.println("rasterData1 = " + Arrays.toString(rasterData));
        // 将栅格数据转换为字节数组
        Integer saveraster = 0;
        // Insert into PostGIS
        try (Connection connection = dataSource.getDataSource().getConnection()) {
            // raster ST_FromGDALRaster(bytea gdaldata, integer srid=NULL);
            //String sql = "INSERT INTO " + tableName + " (rast) VALUES (st_fromgdalraster(?::bytea,?))";
            String sql = "INSERT INTO " + tableName + " (rast) VALUES (st_fromgdalraster(?,?))";
            try (PreparedStatement stmt = connection.prepareStatement(sql)) {
                // 将字节数组作为二进制数据插入
                stmt.setBinaryStream(1, new ByteArrayInputStream(rasterData));
                // 设置栅格数据的SRID(可选)
                stmt.setInt(2, srid);
                log.info("stmt = " + stmt);
                stmt.executeUpdate();
                ++saveraster;
            }
            log.info("Inserted {} raster(s) into {}", saveraster, tableName);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            reader.dispose();
            dataSource.dispose();
        }

        return saveraster;
    }
    private byte[] convertCoverageToByteArray(GridCoverage2D coverage) throws IOException {
        // Create a temporary file to store the GeoTIFF
        File tempFile = File.createTempFile("coverage", ".tif");
        tempFile.deleteOnExit();

        GeoTiffWriter writer = null;
        try {
            writer = new GeoTiffWriter(tempFile);
            writer.write(coverage, null);
        } finally {
            if (writer != null) {
                // Dispose of the writer to release resources
                writer.dispose();
            }
        }
        // Read GeoTIFF file into byte array
        try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
            Files.copy(tempFile.toPath(), baos);
            return baos.toByteArray();
        }
    }

这个是整体导入的示例,拓展一下也可以切片导入

既然可以导入栅格,那么反过来也是可以导出栅格数据变成栅格文件的,示例代码如下:

public String exportRasterData(GridDataDto gridDataDto) throws IOException {
        GridData gridData = gridDataDto.getParameter();
        // 导出目标文件的路径信息
        String targetFilePath = gridData.getTargetFilePath();
        // 导出的源数据集
        String sourceDataset = gridData.getSourceDataset();
        // 解析 PostgreSQL 数据库 连接参数
        Map<String, Object> dataSourceMap = parseDatabaseParameters(sourceDataset);
        log.info("Data source map: {}", dataSourceMap);
        // 创建 PostgreSQL/PostGIS 表
        JDBCDataStoreFactory dsf = new PostgisNGDataStoreFactory();
        JDBCDataStore datastore = dsf.createDataStore(dataSourceMap);
        // 如果不存该模式,则给出提示
        String schemaName = dataSourceMap.get("schema").toString();
        String tableName = dataSourceMap.get("dataset").toString();
        try (Connection connection = datastore.getDataSource().getConnection()) {
            Statement stmt = connection.createStatement();
            String checkSchemaSql = "SELECT schema_name FROM information_schema.schemata WHERE schema_name = '" + schemaName + "'";
            ResultSet rs = stmt.executeQuery(checkSchemaSql);
            if (!rs.next()) {
                log.error("schema notexist, create schema: {}", schemaName);
            }
            // 检查表是否存在,不存在则给出提示
            String checkTableSql = "SELECT to_regclass('" + schemaName + "." + tableName + "')";
            rs = stmt.executeQuery(checkTableSql);
            if (!rs.next() || rs.getString(1) == null) {
                log.error("Table notexist, create table: {}", tableName);
            }
            // 把数据库中的栅格数据导出成一个文件
            exportRasterFromDatabaseToImageFile(connection, schemaName, tableName, targetFilePath);

            // 保存到记录表中
            ServerImportInfo serverImportInfo = new ServerImportInfo();
            BeanUtils.copyProperties(gridData, serverImportInfo);
            Date now = new Date();
            serverImportInfo.setCreateTime(now);
            serverImportInfo.setStartTime(now);
            serverImportInfo.setUpdateTime(now);
            serverImportInfo.setState("RUNNING");
            serverImportInfo.setDataType("栅格-导出");
            serverImportInfo.setState("FINISHED");
            serverImportInfoService.save(serverImportInfo);
            log.info("导出信息保存完成");

            return String.valueOf(serverImportInfo.getId());

        } catch (SQLException e) {
            log.error("Failed to ensure schema exists", e);
            throw new IOException("Failed to ensure schema exists", e);
        } finally {
            datastore.dispose();
        }

    }
public void exportRasterFromDatabaseToImageFile(Connection connection, String schemaName, String targetDatasetName, String imagePath) {
        try {
            // Retrieve raster data from the database
            byte[] rasterData = getRasterDataFromDB(connection, schemaName, targetDatasetName);
            // log.info("rasterData = " + Arrays.toString(rasterData));
            log.info("Converting raster data to images...");
            convertRasterDataToImages(rasterData, imagePath);
            log.info("Conversion complete.");
        } catch (SQLException | IOException e) {
            e.printStackTrace();
        }
    }

  private byte[] getRasterDataFromDB(Connection connection, String schemaName, String targetDatasetName) throws SQLException, IOException {
        String tableName = schemaName + "." + targetDatasetName;
        String sql = "SELECT ST_AsGDALRaster(rast, 'GTiff') FROM " + tableName + " LIMIT 1";
        log.info("Executing SQL: " + sql);
        try (PreparedStatement stmt = connection.prepareStatement(sql);
             ResultSet rs = stmt.executeQuery()) {
            if (rs.next()) {
                log.info("Retrieved raster data from database.");
                try (InputStream is = rs.getBinaryStream(1); ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
                    byte[] buffer = new byte[1024];
                    int bytesRead;
                    while ((bytesRead = is.read(buffer)) != -1) {
                        baos.write(buffer, 0, bytesRead);
                    }
                    return baos.toByteArray();
                }
            } else {
                throw new SQLException("No raster data found.");
            }
        }
    }
 private void convertRasterDataToImages(byte[] rasterData, String outTiffPath) throws IOException {
        File tempFile = File.createTempFile("raster", ".tif");
        tempFile.deleteOnExit();
        try (FileOutputStream fos = new FileOutputStream(tempFile)) {
            fos.write(rasterData);
        }
        AbstractGridFormat format = GridFormatFinder.findFormat(tempFile);
        GridCoverage2DReader reader = format.getReader(tempFile, null);
        GridCoverage2D coverage = reader.read(null);
        log.info("Coverage name: {}", coverage.getName());
        writeTiff(coverage, outTiffPath);
    }
 public static void writeTiff(Coverage coverage, String outTiffPath) throws IOException {
        File file = new File(outTiffPath);
        GeoTiffWriter geoTiffWriter = new GeoTiffWriter(file);
        final GeoTiffFormat format = new GeoTiffFormat();
        final GeoTiffWriteParams wp = new GeoTiffWriteParams();
        // 设置写出参数
        wp.setCompressionMode(GeoTiffWriteParams.MODE_DEFAULT);
        wp.setTilingMode(GeoToolsWriteParams.MODE_DEFAULT);
        ParameterValueGroup paramWrite = format.getWriteParameters();
        paramWrite.parameter(AbstractGridFormat.GEOTOOLS_WRITE_PARAMS.getName().toString()).setValue(wp);
        geoTiffWriter.write((GridCoverage) coverage, paramWrite.values().toArray(new GeneralParameterValue[4]));
        geoTiffWriter.dispose();
    }

至此!即可实现栅格数据通过代码进行导入导出了!

标签:info,gt,java,log,栅格数据,栅格,org,new,String
From: https://blog.csdn.net/qq_43544074/article/details/141055638

相关文章

  • 【Java】若依(ruoyi)——5.代码生成
    参考地址:http://doc.ruoyi.vip/ruoyi/document/htsc.html#%E4%BB%A3%E7%A0%81%E7%94%9F%E6%88%90仔细关注,发现若依真的太好用了。主要是使用的人数众多,文档齐全。而且里面的技术齐全,就算不使用该框架,也可以以此为例,学习学习。这里,最有效的功能算是代码生成了,(这里使用的是前后端......
  • Java基础-学习笔记17
    17IO流1.IO流文件文件在程序中是以流的形式来操作的。流:数据在数据源(文件)和程序(内存)之间经历的路径输入流:数据从数据源(文件)到程序(内存)的路径输出流:数据从程序(内存)到数据源(文件)的路径常用的文件操作获取文件的相关信息IO流原理及流的分类I/O(Input/Output......
  • 2-3Java继承
    Java继承继承的概念继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类。继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。生活中的继承:兔子和羊属于食草动物类,狮子和豹属于食肉......
  • JavaScript 基础知识
    概述        在Web前端开发中,JavaScript是一种脚本语言,主要用于实现网页的动态功能和交互效果。与HTML和CSS主要关注网页的结构和样式不同,JavaScript可以用于以下方面:动态内容更新:通过JavaScript,可以在不重新加载页面的情况下更新网页上的内容。例如,用户点击......
  • Java----字符串(String)
    一、什么是字符串?定义:字符串是一个或多个字符的序列在java中用char数组来表示字符串,我们可以从源码看到:java对char数组进行了封装,并用String类型来表达字符串,也就是说java程序中所有字符串的文字都被成为此类的对象。#java8源码/**Thevalueisusedforcharacterst......
  • java 多态
    面向对象三大特性:封装、继承、多态,今天我们来讲解多态定义:同类型的对象表现出不同的形态    这听起来有点抽象,我们举个具体的例子:    假设你开了一家宠物店,提供宠物寄养的服务,于是你规定可以给寄养所有的波斯猫,附近的居民都把宠物寄养在这里://参数是哈......
  • JavaScript 事件循环
    0x01事件循环JavaScript是单线程的,即同一时间内仅能执行一个操作在单线程中,当一段代码中存在需要等待或触发的任务时,会阻塞线程,影响后续代码的执行,因此需要将代码分为同步和异步,其执行过程如下:flowchartLR代码--同步-->JS引擎-->执行栈--立即执行-->执行栈代码--异步-......
  • [Javascript] Function.prototype.call
    .callmethodexitsonanyfunction,whichwillreferto Function.prototype.callforexample:console.log.call===Function.prototype.call//call AlsoitmeansthatFunction.prototype.call===Function.prototype.call.call Question:console.log.call.cal......
  • JVM(Java Virtual Machine,Java 虚拟机)
    JVM(JavaVirtualMachine,Java虚拟机)是Java程序运行的虚拟计算机,它是一个抽象计算机的概念,为Java程序提供了一个与平台无关的执行环境。JVM负责加载Java类文件,执行字节码,并提供运行时环境,包括内存管理、垃圾回收等。JVM主要由四大部分组成:ClassLoader(类加载器):负责加载......
  • 【高级编程】实用类详解(下)万字整理Java时间日期类 JDK8新日期
    文章目录日期时间DateSimpleDateFormatCalendarJDK8新日期LocalDateTime&LocalDate&LocalTimeDateTimeFormater计算Period&DurationzonedDateTimeInstant类型转换注意事项日期时间Datejava.util.Date类:表示日期和时间。提供操作日期和时间各组成部分的方法。......