最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot通過(guò)自定義注解與異步來(lái)管理日志流程

 更新時(shí)間:2023年03月27日 09:26:33   作者:☆夜幕星河℡  
實(shí)現(xiàn)日志管理說(shuō)實(shí)話(huà)方式還挺多,個(gè)人使用過(guò)直接在Controller代碼里面寫(xiě)、AOP+自定義注解、ConstraintValidator。本文主要和大家講的是自定義注解與異步來(lái)管理日志流程,感興趣的可以了解一下

一、前言

我們?cè)谄髽I(yè)級(jí)的開(kāi)發(fā)中,必不可少的是對(duì)日志的記錄,實(shí)現(xiàn)有很多種方式,常見(jiàn)的就是基于A(yíng)OP+注解進(jìn)行保存,同時(shí)考慮到程序的流暢和效率,我們可以使用異步進(jìn)行保存!

二、基礎(chǔ)環(huán)境

1. 導(dǎo)入依賴(lài)

我這里的springboot版本是:2.7.4

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.4</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>springboot-log</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboot-log</name>
    <description>springboot-log 日志 Demo</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.2</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- Druid -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.16</version>
        </dependency>
        <!--jdbc-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <!-- mysql -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!-- mybatis-plus -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.1</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

2. 編寫(xiě)yml配置

server:
  port: 8080

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/admin?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
    username: root
    password: 123456
    druid:
      initial-size: 5
      max-active: 100
      min-idle: 5
      max-wait: 60000
      time-between-eviction-runs-millis: 60000
      min-evictable-idle-time-millis: 30000
      validation-query: SELECT 1 FROM DUAL
      test-while-idle: true
      test-on-borrow: true
      test-on-return: false

三、數(shù)據(jù)庫(kù)設(shè)計(jì)

數(shù)據(jù)庫(kù)保存日志表的設(shè)計(jì),這里一切從簡(jiǎn),一般日志多的后期會(huì)進(jìn)行分庫(kù)分表,或者搭配ELK進(jìn)行分析,分庫(kù)分表一般采用根據(jù)方法類(lèi)型!

DROP TABLE IF EXISTS `sys_log`;
CREATE TABLE `sys_log`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '日志主鍵',
  `title` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '' COMMENT '模塊標(biāo)題',
  `business_type` int(2) NULL DEFAULT 0 COMMENT '業(yè)務(wù)類(lèi)型(0其它 1新增 2修改 3刪除)',
  `method` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '' COMMENT '方法名稱(chēng)',
  `request_method` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '' COMMENT '請(qǐng)求方式',
  `oper_name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '' COMMENT '操作人員',
  `oper_url` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '' COMMENT '請(qǐng)求URL',
  `oper_ip` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '' COMMENT '主機(jī)地址',
  `oper_time` datetime(0) NULL DEFAULT NULL COMMENT '操作時(shí)間',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1585197503834284034 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '操作日志記錄' ROW_FORMAT = Dynamic;
SET FOREIGN_KEY_CHECKS = 1;

實(shí)體類(lèi):

package com.example.springbootlog.entity;
import java.util.Date;
import java.io.Serializable;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import lombok.ToString;
/**
 * 操作日志記錄(SysLog)實(shí)體類(lèi)
 *
 * @author qrxm
 * @since 2023-03-26 02:09:54
 */
@Data
@ToString
@TableName("sys_log")
public class SysLog implements Serializable {
    private static final long serialVersionUID = 811241510868515068L;
    /**
    * 日志主鍵
    */
    @TableId
    private Long id;
    /**
    * 模塊標(biāo)題
    */
    private String title;
    /**
    * 業(yè)務(wù)類(lèi)型(0其它 1新增 2修改 3刪除)
    */
    private Integer businessType;
    /**
    * 方法名稱(chēng)
    */
    private String method;
    /**
    * 請(qǐng)求方式
    */
    private String requestMethod;
    /**
    * 操作人員
    */
    private String operName;
    /**
    * 請(qǐng)求URL
    */
    private String operUrl;
    /**
    * 主機(jī)地址
    */
    private String operIp;
    /**
    * 操作時(shí)間
    */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date operTime;
}

四、主要功能

大體思路:

  • 先手寫(xiě)一個(gè)注解
  • 切面來(lái)進(jìn)行獲取要保存的數(shù)據(jù)
  • 一個(gè)發(fā)布者來(lái)發(fā)布要保存的數(shù)據(jù)
  • 一個(gè)監(jiān)聽(tīng)者監(jiān)聽(tīng)后保存(異步)

完整項(xiàng)目架構(gòu)圖如下:

1. 編寫(xiě)注解

package com.example.springbootlog.annotation;
import com.example.springbootlog.constant.BusinessTypeEnum;
import java.lang.annotation.*;
/**
 * 自定義操作日志記錄注解
 * @author qrxm
 */
@Target(ElementType.METHOD) // 注解只能用于方法
@Retention(RetentionPolicy.RUNTIME) // 修飾注解的生命周期
@Documented
public @interface Log {
    String value() default "";
    /**
     * 模塊
     */
    String title() default "測(cè)試模塊";
    /**
     * 方法名稱(chēng)
     */
    String method() default "測(cè)試方法";
    /**
     * 功能
     */
    BusinessTypeEnum businessType() default BusinessTypeEnum.OTHER;
}

2. 業(yè)務(wù)類(lèi)型枚舉

package com.example.springbootlog.constant;
public enum BusinessTypeEnum {
    /**
     * 其它
     */
    OTHER(0,"其它"),
    /**
     * 新增
     */
    INSERT(1,"新增"),
    /**
     * 修改
     */
    UPDATE(2,"修改"),
    /**
     * 刪除
     */
    DELETE(3,"刪除");
    private Integer code;
    private String message;
    BusinessTypeEnum(Integer code, String message) {
        this.code = code;
        this.message = message;
    }
    public Integer getCode() {
        return code;
    }
    public String getMessage() {
        return message;
    }
}

3. 編寫(xiě)切片

這里是以切片后進(jìn)行發(fā)起的,當(dāng)然規(guī)范流程是要加異常后的切片,這里以最簡(jiǎn)單的進(jìn)行測(cè)試哈,大家按需進(jìn)行添加??!

package com.example.springbootlog.aspect;
import com.example.springbootlog.annotation.Log;
import com.example.springbootlog.entity.SysLog;
import com.example.springbootlog.listener.EventPubListener;
import com.example.springbootlog.utils.IpUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
@Aspect
@Component
public class SysLogAspect {
    private final Logger logger = LoggerFactory.getLogger(SysLogAspect.class);
    @Autowired
    private EventPubListener eventPubListener;
    /**
     * 以注解所標(biāo)注的方法作為切入點(diǎn)
     */
    @Pointcut("@annotation(com.example.springbootlog.annotation.Log)")
    public void sysLog() {}
    /**
     * 在切點(diǎn)之后織入
     * @throws Throwable
     */
    @After("sysLog()")
    public void doAfter(JoinPoint joinPoint) {
        Log log = ((MethodSignature) joinPoint.getSignature()).getMethod()
                .getAnnotation(Log.class);
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder
                .getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        String method = request.getMethod();
        String url = request.getRequestURL().toString();
        String ip = IpUtils.getIpAddr(request);
        SysLog sysLog = new SysLog();
        sysLog.setBusinessType(log.businessType().getCode());
        sysLog.setTitle(log.title());
        sysLog.setMethod(log.method());
        sysLog.setRequestMethod(method);
        sysLog.setOperIp(ip);
        sysLog.setOperUrl(url);
        // 從登錄中token獲取登錄人員信息即可
        sysLog.setOperName("我是測(cè)試人員");
        sysLog.setOperTime(new Date());
        // 發(fā)布消息
        eventPubListener.pushListener(sysLog);
        logger.info("=======日志發(fā)送成功,內(nèi)容:{}",sysLog);
    }
}

4. ip工具類(lèi)

package com.example.springbootlog.utils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import javax.servlet.http.HttpServletRequest;
public class IpUtils {
    /**
     * 獲取客戶(hù)端IP
     *
     * @param request 請(qǐng)求對(duì)象
     * @return IP地址
     */
    public static String getIpAddr(HttpServletRequest request) {
        if (request == null) {
            return "unknown";
        }
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("X-Forwarded-For");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("X-Real-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : getMultistageReverseProxyIp(ip);
    }
    /**
     * 從多級(jí)反向代理中獲得第一個(gè)非unknown IP地址
     *
     * @param ip 獲得的IP地址
     * @return 第一個(gè)非unknown IP地址
     */
    public static String getMultistageReverseProxyIp(String ip) {
        // 多級(jí)反向代理檢測(cè)
        if (ip != null && ip.indexOf(",") > 0) {
            final String[] ips = ip.trim().split(",");
            for (String subIp : ips) {
                if (false == isUnknown(subIp)) {
                    ip = subIp;
                    break;
                }
            }
        }
        return ip;
    }
    /**
     * 檢測(cè)給定字符串是否為未知,多用于檢測(cè)HTTP請(qǐng)求相關(guān)
     *
     * @param checkString 被檢測(cè)的字符串
     * @return 是否未知
     */
    public static boolean isUnknown(String checkString) {
        return StringUtils.isBlank(checkString) || "unknown".equalsIgnoreCase(checkString);
    }
}

5. 事件發(fā)布

事件發(fā)布是由ApplicationContext對(duì)象進(jìn)行發(fā)布的,直接注入使用即可!

使用觀(guān)察者模式的目的:為了業(yè)務(wù)邏輯之間的解耦,提高可擴(kuò)展性。

這種模式在spring和springboot底層是經(jīng)常出現(xiàn)的,大家可以去看看。

發(fā)布者只需要關(guān)注發(fā)布消息,監(jiān)聽(tīng)者只需要監(jiān)聽(tīng)自己需要的,不管誰(shuí)發(fā)的,符合自己監(jiān)聽(tīng)條件即可。

package com.example.springbootlog.listener;
import com.example.springbootlog.entity.SysLog;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
@Component
public class EventPubListener {
    @Autowired
    private ApplicationContext applicationContext;
    /**
     * 事件發(fā)布方法
     * @param sysLogEvent
     */
    public void pushListener(SysLog sysLogEvent) {
        applicationContext.publishEvent(sysLogEvent);
    }
}

6. 監(jiān)聽(tīng)者

@Async:?jiǎn)为?dú)開(kāi)啟一個(gè)新線(xiàn)程去保存,提高效率!

@EventListener:監(jiān)聽(tīng)

package com.example.springbootlog.listener;
import com.example.springbootlog.entity.SysLog;
import com.example.springbootlog.service.SysLogService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
@Slf4j
@Component
public class MyEventListener {
    @Autowired
    private SysLogService sysLogService;
    // 開(kāi)啟異步
    @Async
    // 開(kāi)啟監(jiān)聽(tīng)
    @EventListener(SysLog.class)
    public void saveSysLog(SysLog event) {
        log.info("=====即將異步保存到數(shù)據(jù)庫(kù)======");
        sysLogService.saveLog(event);
    }
}

五、測(cè)試

1. controller

package com.example.springbootlog.controller;
import com.example.springbootlog.annotation.Log;
import com.example.springbootlog.constant.BusinessTypeEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
/**
 * 操作日志記錄(SysLog)表控制層
 *
 */
@Slf4j
@RestController
@RequestMapping("sysLog")
public class SysLogController {
    @Log(method = "測(cè)試添加方法", title = "測(cè)試呢", businessType = BusinessTypeEnum.INSERT)
    @GetMapping("/saveLog")
    public void saveLog() {
        log.info("我就是來(lái)測(cè)試一下是否成功!");
    }
}

2. service

package com.example.springbootlog.service;
import com.example.springbootlog.entity.SysLog;
import com.baomidou.mybatisplus.extension.service.IService;
/**
 * 操作日志記錄(SysLog)表服務(wù)接口
 */
public interface SysLogService  extends IService<SysLog> {
    Integer saveLog(SysLog sysLog);
}
package com.example.springbootlog.service.impl;
import com.example.springbootlog.entity.SysLog;
import com.example.springbootlog.service.SysLogService;
import com.example.springbootlog.dao.SysLogDao;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
 * 操作日志記錄(SysLog)表服務(wù)實(shí)現(xiàn)類(lèi)
 */
@Service("sysLogService")
public class SysLogServiceImpl  extends ServiceImpl<SysLogDao, SysLog>  implements SysLogService {
    @Autowired
    private SysLogDao sysLogDao;
    @Override
    public Integer saveLog(SysLog sysLog) {
        return sysLogDao.insert(sysLog);
    }
}

3. dao

這里使用mybatis-plus進(jìn)行保存

package com.example.springbootlog.dao;
import com.example.springbootlog.entity.SysLog;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
 * 操作日志記錄(SysLog)表數(shù)據(jù)庫(kù)訪(fǎng)問(wèn)層
 */
public interface SysLogDao extends BaseMapper<SysLog> {
}

4. 測(cè)試

訪(fǎng)問(wèn)地址:http://localhost:8080/sysLog/saveLog

5. 數(shù)據(jù)庫(kù)

六、總結(jié)

這個(gè)實(shí)戰(zhàn)在企業(yè)級(jí)必不可少的,每個(gè)項(xiàng)目搭建人不同,但是結(jié)果都是一樣的,保存日志到數(shù)據(jù),這樣可以進(jìn)行按鈕的點(diǎn)擊進(jìn)行統(tǒng)計(jì),分析那個(gè)功能是否經(jīng)常使用,那些東西需要優(yōu)化。只要是有數(shù)據(jù)的東西,分析一下總會(huì)有收獲的!后面日志多了就行分庫(kù)分表,ELK搭建。

代碼已上傳到 Gitee 上面了,地址:https://gitee.com/afoams/springboot-log

到此這篇關(guān)于SpringBoot通過(guò)自定義注解與異步來(lái)管理日志流程的文章就介紹到這了,更多相關(guān)SpringBoot自定義注解內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 分析Netty直接內(nèi)存原理及應(yīng)用

    分析Netty直接內(nèi)存原理及應(yīng)用

    Netty作為一個(gè)流行的應(yīng)用框架,它的強(qiáng)悍之處是性能強(qiáng)悍,可以輕松承載數(shù)萬(wàn)并發(fā); 其編程模型簡(jiǎn)單,容易上手; 這就給大家打開(kāi)了一扇通向高性能的大門(mén)。高效io模型略去不說(shuō),我們今天主要來(lái)看看內(nèi)存控制這塊的強(qiáng)大之處
    2021-06-06
  • springAI結(jié)合ollama簡(jiǎn)單實(shí)現(xiàn)小結(jié)

    springAI結(jié)合ollama簡(jiǎn)單實(shí)現(xiàn)小結(jié)

    本文主要介紹了springAI結(jié)合ollama簡(jiǎn)單實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2025-03-03
  • 分布式醫(yī)療掛號(hào)系統(tǒng)Nacos微服務(wù)Feign遠(yuǎn)程調(diào)用數(shù)據(jù)字典

    分布式醫(yī)療掛號(hào)系統(tǒng)Nacos微服務(wù)Feign遠(yuǎn)程調(diào)用數(shù)據(jù)字典

    這篇文章主要為大家介紹了分布式醫(yī)療掛號(hào)系統(tǒng)Nacos微服務(wù)Feign遠(yuǎn)程調(diào)用數(shù)據(jù)字典,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪<BR>
    2022-04-04
  • 淺析java中asList的使用詳解

    淺析java中asList的使用詳解

    Java中的asList方法是數(shù)組工具類(lèi) Arrays中的一個(gè)靜態(tài)方法,asList()方法把數(shù)組轉(zhuǎn)換成集合時(shí),不能使用其修改集合相關(guān)的方法,本文通過(guò)示例代碼給大家介紹java asList使用,感興趣的朋友一起看看吧
    2021-10-10
  • Java Swing程序設(shè)計(jì)實(shí)戰(zhàn)

    Java Swing程序設(shè)計(jì)實(shí)戰(zhàn)

    今天教大家怎么用JavaSwing工具包實(shí)現(xiàn)一個(gè)程序的界面設(shè)計(jì),文中有非常詳細(xì)的代碼示例及注釋,對(duì)正在學(xué)習(xí)Java的小伙伴們很有幫助,需要的朋友可以參考下
    2021-05-05
  • Android中Handler引起的內(nèi)存泄露問(wèn)題解決辦法

    Android中Handler引起的內(nèi)存泄露問(wèn)題解決辦法

    這篇文章主要介紹了Android中Handler引起的內(nèi)存泄露問(wèn)題解決辦法,本文講解了導(dǎo)致內(nèi)存泄露的情景,并給出了修改后的代碼,需要的朋友可以參考下
    2015-01-01
  • Springboot啟動(dòng)報(bào)錯(cuò)Input length = 2的問(wèn)題解決

    Springboot啟動(dòng)報(bào)錯(cuò)Input length = 2的問(wèn)題解決

    最近使用Springboot啟動(dòng)報(bào)錯(cuò),報(bào)錯(cuò)內(nèi)容java.nio.charset.MalformedInputException: Input length = 2,下面就來(lái)介紹一下解決方法,感興趣的可以了解一下
    2024-08-08
  • springboot+springJdbc+postgresql 實(shí)現(xiàn)多數(shù)據(jù)源的配置

    springboot+springJdbc+postgresql 實(shí)現(xiàn)多數(shù)據(jù)源的配置

    本文主要介紹了springboot+springJdbc+postgresql 實(shí)現(xiàn)多數(shù)據(jù)源的配置,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • Java中Set集合的基本使用方法舉例

    Java中Set集合的基本使用方法舉例

    在Java中可以使用不同的實(shí)現(xiàn)類(lèi)來(lái)創(chuàng)建和初始化Set集合,下面這篇文章主要給大家介紹了關(guān)于Java中Set集合的基本使用方法,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-07-07
  • Java鏈表使用解讀

    Java鏈表使用解讀

    Java中的鏈表(LinkedList)是一種動(dòng)態(tài)數(shù)據(jù)結(jié)構(gòu),由一系列節(jié)點(diǎn)組成,每個(gè)節(jié)點(diǎn)包含數(shù)據(jù)和指向下一個(gè)節(jié)點(diǎn)的引用,LinkedList實(shí)現(xiàn)了List和Deque接口,支持高效的插入和刪除操作,Java提供了.standard.util.LinkedList類(lèi)來(lái)實(shí)現(xiàn)鏈表
    2025-01-01

最新評(píng)論

资源县| 依安县| 长岭县| 南宁市| 托克逊县| 鹿邑县| 遂宁市| 海原县| 天津市| 瑞安市| 祁门县| 大港区| 桂阳县| 大兴区| 无棣县| 缙云县| 当雄县| 巴中市| 昌宁县| 稻城县| 敖汉旗| 衡山县| 青海省| 长泰县| 八宿县| 怀仁县| 克东县| 凤城市| 合肥市| 临海市| 汝南县| 威海市| 鄱阳县| 古丈县| 大悟县| 巩义市| 邵阳市| 怀集县| 绍兴市| 承德县| 广安市|