欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringBoot實現(xiàn)Excel讀取的實例教程

 更新時間:2020年12月23日 15:09:28   作者:喜歡了一個人四年  
這篇文章主要給大家介紹了關(guān)于SpringBoot實現(xiàn)Excel讀取的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

前言

這是本人寫的一個SpringBoot對Excel讀取的方法,實測能用,待提升的地方有很多,有不足之處請多多指點。

Excel2003版(后綴為.xls)最大行數(shù)是65536行,最大列數(shù)是256列。

Excel2007以上的版本(后綴為.xlsx)最大行數(shù)是1048576行,最大列數(shù)是16384列。

提供2種方法讀取:

1.根據(jù)指定的開始和結(jié)束行數(shù)讀取返回結(jié)果,結(jié)果格式為List<Map<String, Object>>

2.根據(jù)指定的開始和結(jié)束行數(shù)讀取返回結(jié)果,結(jié)果格式為List<POJO(傳入的實體類)>

請根據(jù)實際內(nèi)存堆可用大小進(jìn)行讀取,太多可進(jìn)行分段讀?。愃品猪摰脑恚?/p>

讀取Excel所需要的幾個類

Excel

1.在pom.xml加上依賴

</dependencies>
 <dependency>
  <groupId>org.apache.poi</groupId>
  <artifactId>poi</artifactId>
  <version>4.0.1</version>
 </dependency>
 <dependency>
  <groupId>org.apache.poi</groupId>
  <artifactId>poi-ooxml</artifactId>
  <version>4.0.1</version>
 </dependency>
</dependencies>

2.ExcelPOJO實體類

package com.cly.utils.Excel;

/**
 * @author : CLy
 * @ClassName : ExcelPOJO
 * @date : 2020/7/9 17:13
 * 實體類所有成員變量都需要有GET,SET方法
 * 所有成員變量都要加上注解@excelRescoure(value = "?"),?為Excel真實列名,必須一一對應(yīng)
 * @excelRescoure(value = "?"),?可為空,需要用到才賦值
 * 成員變量目前只允許String,Double,Interge,Float
 **/

public class ExcelPOJO {
 public String getName() {
 return name;
 }
 public void setName(String name) {
 this.name = name;
 }
 public String getPasswork() {
 return passwork;
 }
 public void setPasswork(String passwork) {
 this.passwork = passwork;
 }
 public String getLook() {
 return look;
 }
 public void setLook(String look) {
 this.look = look;
 }
 
 @excelRescoure(value = "XM")
 private String name;
 @excelRescoure(value = "SFZH")
 private String passwork;
 @excelRescoure()
 private String look;
 
 @Override
 public String toString(){
 return "name:"+this.getName()+",passwork:"+this.getPasswork()+",look:"+this.getLook();
 }
 public ExcelPOJO() {}
}

3.@interface自定義注解(用于實體類讀取)

package com.cly.utils.Excel;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @author : CLy
 * @ClassName : myRescoure
 * @date : 2020/7/10 9:31
 **/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface excelRescoure {
 String value() default "";//默認(rèn)為空
}

4.excelRead類(讀取Excel數(shù)據(jù)類)有很多冗余的代碼,可抽離出來

package com.cly.utils.Excel;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.sun.org.apache.bcel.internal.generic.NEW;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.formula.functions.T;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.xml.transform.Source;
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.*;
import java.text.DecimalFormat;
import java.util.*;

/**
 * @author : CLy
 * @ClassName : excelRead
 * @date : 2020/7/9 11:08
 **/
public class excelRead {
 //日志輸出
 private static Logger logger = LoggerFactory.getLogger(excelRead.class);
 //定義excel類型
 private static final String XLS = "xls";
 private static final String XLSX = "xlsx";

 /**
 * 根據(jù)文件后綴名類型獲取對應(yīng)的工作簿對象
 * @param inputStream 讀取文件的輸入流
 * @param fileType 文件后綴名類型(xls或xlsx)
 * @return 包含文件數(shù)據(jù)的工作簿對象
 */
 private static Workbook getWorkbook(InputStream inputStream, String fileType) throws IOException {
 //用自帶的方法新建工作薄
 Workbook workbook = WorkbookFactory.create(inputStream);
 //后綴判斷有版本轉(zhuǎn)換問題
 //Workbook workbook = null;
 //if (fileType.equalsIgnoreCase(XLS)) {
 // workbook = new HSSFWorkbook(inputStream);
 //} else if (fileType.equalsIgnoreCase(XLSX)) {
 // workbook = new XSSFWorkbook(inputStream);
 //}
 return workbook;
 }


 /**
 * 將單元格內(nèi)容轉(zhuǎn)換為字符串
 * @param cell
 * @return
 */
 private static String convertCellValueToString(Cell cell) {
 if (cell == null) {
  return null;
 }
 String returnValue = null;
 switch (cell.getCellType()) {
  case NUMERIC: //數(shù)字
  Double doubleValue = cell.getNumericCellValue();
  // 格式化科學(xué)計數(shù)法,取一位整數(shù),如取小數(shù),值如0.0,取小數(shù)點后幾位就寫幾個0
  DecimalFormat df = new DecimalFormat("0");
  returnValue = df.format(doubleValue);
  break;
  case STRING: //字符串
  returnValue = cell.getStringCellValue();
  break;
  case BOOLEAN: //布爾
  Boolean booleanValue = cell.getBooleanCellValue();
  returnValue = booleanValue.toString();
  break;
  case BLANK: // 空值
  break;
  case FORMULA: // 公式
  returnValue = cell.getCellFormula();
  break;
  case ERROR: // 故障
  break;
  default:
  break;
 }
 return returnValue;
 }

 /**
 * 處理Excel內(nèi)容轉(zhuǎn)為List<Map<String,Object>>輸出
 * workbook:已連接的工作薄
 * StatrRow:讀取的開始行數(shù)(默認(rèn)填0,0開始,傳過來是EXcel的行數(shù)值默認(rèn)從1開始,這里已處理減1)
 * EndRow:讀取的結(jié)束行數(shù)(填-1為全部)
 * ExistTop:是否存在頭部(如存在則讀取數(shù)據(jù)時會把頭部拼接到對應(yīng)數(shù)據(jù),若無則為當(dāng)前列數(shù))
 */
 private static List<Map<String, Object>> HandleData(Workbook workbook, int StatrRow, int EndRow, boolean ExistTop) {
 //聲明返回結(jié)果集result
 List<Map<String, Object>> result = new ArrayList<>();
 //聲明一個Excel頭部函數(shù)
 ArrayList<String> top = new ArrayList<>();
 //解析sheet(sheet是Excel腳頁)
 /**
 *此處會讀取所有腳頁的行數(shù)據(jù),若只想讀取指定頁,不要for循環(huán),直接給sheetNum賦值,腳頁從0開始(通常情況Excel都只有一頁,所以此處未進(jìn)行進(jìn)一步處理)
 */
 for (int sheetNum = 0; sheetNum < workbook.getNumberOfSheets(); sheetNum++) {
  Sheet sheet = workbook.getSheetAt(sheetNum);
  // 校驗sheet是否合法
  if (sheet == null) {
  continue;
  }
  //如存在頭部,處理頭部數(shù)據(jù)
  if (ExistTop) {
  int firstRowNum = sheet.getFirstRowNum();
  Row firstRow = sheet.getRow(firstRowNum);
  if (null == firstRow) {
   logger.warn("解析Excel失敗,在第一行沒有讀取到任何數(shù)據(jù)!");
  }
  for (int i = 0; i < firstRow.getLastCellNum(); i++) {
   top.add(convertCellValueToString(firstRow.getCell(i)));
  }
  }
  //處理Excel數(shù)據(jù)內(nèi)容
  int endRowNum;
  //獲取結(jié)束行數(shù)
  if (EndRow == -1) {
  endRowNum = sheet.getPhysicalNumberOfRows();
  } else {
  endRowNum = EndRow <= sheet.getPhysicalNumberOfRows() ? EndRow : sheet.getPhysicalNumberOfRows();
  }
  //遍歷行數(shù)
  for (int i = StatrRow - 1; i < endRowNum; i++) {
  Row row = sheet.getRow(i);
  if (null == row) {
   continue;
  }
  Map<String, Object> map = new HashMap<>();
  //獲取所有列數(shù)據(jù)
  for (int y = 0; y < row.getLastCellNum(); y++) {
   if (top.size() > 0) {
   if (top.size() >= y) {
    map.put(top.get(y), convertCellValueToString(row.getCell(y)));
   } else {
    map.put(String.valueOf(y + 1), convertCellValueToString(row.getCell(y)));
   }
   } else {
   map.put(String.valueOf(y + 1), convertCellValueToString(row.getCell(y)));
   }
  }
  result.add(map);
  }
 }
 return result;
 }

 /**
 * 方法一
 * 根據(jù)行數(shù)和列數(shù)讀取Excel
 * fileName:Excel文件路徑
 * StatrRow:讀取的開始行數(shù)(默認(rèn)填0)
 * EndRow:讀取的結(jié)束行數(shù)(填-1為全部)
 * ExistTop:是否存在頭部(如存在則讀取數(shù)據(jù)時會把頭部拼接到對應(yīng)數(shù)據(jù),若無則為當(dāng)前列數(shù))
 * 返回一個List<Map<String,Object>>
 */
 public static List<Map<String, Object>> ReadExcelByRC(String fileName, int StatrRow, int EndRow, boolean ExistTop) {
 //判斷輸入的開始值是否少于等于結(jié)束值
 if (StatrRow > EndRow && EndRow != -1) {
  logger.warn("輸入的開始行值比結(jié)束行值大,請重新輸入正確的行數(shù)");
  List<Map<String, Object>> error = null;
  return error;
 }
 //聲明返回的結(jié)果集
 List<Map<String, Object>> result = new ArrayList<>();
 //聲明一個工作薄
 Workbook workbook = null;
 //聲明一個文件輸入流
 FileInputStream inputStream = null;
 try {
  // 獲取Excel后綴名,判斷文件類型
  String fileType = fileName.substring(fileName.lastIndexOf(".") + 1);
  // 獲取Excel文件
  File excelFile = new File(fileName);
  if (!excelFile.exists()) {
  logger.warn("指定的Excel文件不存在!");
  return null;
  }
  // 獲取Excel工作簿
  inputStream = new FileInputStream(excelFile);
  workbook = getWorkbook(inputStream, fileType);
  //處理Excel內(nèi)容
  result = HandleData(workbook, StatrRow, EndRow, ExistTop);
 } catch (Exception e) {
  logger.warn("解析Excel失敗,文件名:" + fileName + " 錯誤信息:" + e.getMessage());
 } finally {
  try {
  if (null != workbook) {
   workbook.close();
  }
  if (null != inputStream) {
   inputStream.close();
  }
  } catch (Exception e) {
  logger.warn("關(guān)閉數(shù)據(jù)流出錯!錯誤信息:" + e.getMessage());
  return null;
  }
 }
 return result;
 }


/**==============================================================================================================================**/

 /**
 * 方法二
 * 根據(jù)給定的實體類中賦值的注解值讀取Excel
 * fileName:Excel文件路徑
 * StatrRow:讀取的開始行數(shù)(默認(rèn)填0)
 * EndRow:讀取的結(jié)束行數(shù)(填-1為全部)
 * Class<T>:傳過來的實體類類型
 * 返回一個List<T>:T為實體類
 */
 public static List<Object> ReadExcelByPOJO(String fileName, int StatrRow, int EndRow, Class t) throws InvocationTargetException, IntrospectionException, InstantiationException, IllegalAccessException, NoSuchFieldException {
 //判斷輸入的開始值是否少于等于結(jié)束值
 if (StatrRow > EndRow && EndRow != -1) {
  logger.warn("輸入的開始行值比結(jié)束行值大,請重新輸入正確的行數(shù)");
  List<Object> error = null;
  return error;
 }
 //聲明返回的結(jié)果集
 List<Object> result = new ArrayList<>();
 //聲明一個工作薄
 Workbook workbook = null;
 //聲明一個文件輸入流
 FileInputStream inputStream = null;
 try {
  // 獲取Excel后綴名,判斷文件類型
  String fileType = fileName.substring(fileName.lastIndexOf(".") + 1);
  // 獲取Excel文件
  File excelFile = new File(fileName);
  if (!excelFile.exists()) {
  logger.warn("指定的Excel文件不存在!");
  return null;
  }
  // 獲取Excel工作簿
  inputStream = new FileInputStream(excelFile);
  workbook = getWorkbook(inputStream, fileType);
  //處理Excel內(nèi)容
  result = HandleDataPOJO(workbook, StatrRow, EndRow, t);
 } catch (Exception e) {
  logger.warn("解析Excel失敗,文件名:" + fileName + " 錯誤信息:" + e.getMessage());
 } finally {
  try {
  if (null != workbook) {
   workbook.close();
  }
  if (null != inputStream) {
   inputStream.close();
  }
  } catch (Exception e) {
  logger.warn("關(guān)閉數(shù)據(jù)流出錯!錯誤信息:" + e.getMessage());
  return null;
  }
 }
 return result;
 }


 /**
 * 處理Excel內(nèi)容轉(zhuǎn)為List<T>輸出
 * workbook:已連接的工作薄
 * StatrRow:讀取的開始行數(shù)(默認(rèn)填0,0開始,傳過來是EXcel的行數(shù)值默認(rèn)從1開始,這里已處理減1)
 * EndRow:讀取的結(jié)束行數(shù)(填-1為全部)
 * Class<T>:所映射的實體類
 */
 private static <t> List<Object> HandleDataPOJO(Workbook workbook, int StatrRow, int EndRow, Class<?> t) throws IntrospectionException, NoSuchFieldException, IllegalAccessException, InstantiationException, InvocationTargetException, ClassNotFoundException {
 //聲明返回的結(jié)果集
 List<Object> result = new ArrayList<Object>();
 //解析sheet(sheet是Excel腳頁)
 for (int sheetNum = 0; sheetNum < workbook.getNumberOfSheets(); sheetNum++) {
  Sheet sheet = workbook.getSheetAt(sheetNum);
  // 校驗sheet是否合法
  if (sheet == null) {
  continue;
  }
  //獲取頭部數(shù)據(jù)
  //聲明頭部數(shù)據(jù)數(shù)列對象
  ArrayList<String> top = new ArrayList<>();
  //獲取Excel第一行數(shù)據(jù)
  int firstRowNum = sheet.getFirstRowNum();
  Row firstRow = sheet.getRow(firstRowNum);
  if (null == firstRow) {
  logger.warn("解析Excel失敗,在第一行沒有讀取到任何數(shù)據(jù)!");
  return null;
  }
  for (int i = 0; i < firstRow.getLastCellNum(); i++) {
  top.add(convertCellValueToString(firstRow.getCell(i)));
  }
  //獲取實體類的成原變量
  Map<String, Object> POJOfields = getPOJOFieldAndValue(t);
  //判斷所需要的數(shù)據(jù)列
  Map<String, Object> exceltoPOJO = new HashMap<>();
  for (int i = 0; i < top.size(); i++) {
  if (POJOfields.get(top.get(i)) != null && !"".equals(POJOfields.get(top.get(i)))) {
   exceltoPOJO.put(String.valueOf(i), POJOfields.get(top.get(i)));
  }
  }
  /*處理Excel數(shù)據(jù)內(nèi)容*/
  int endRowNum;
  //獲取結(jié)束行數(shù)
  if (EndRow == -1) {
  endRowNum = sheet.getPhysicalNumberOfRows();
  } else {
  endRowNum = EndRow <= sheet.getPhysicalNumberOfRows() ? EndRow : sheet.getPhysicalNumberOfRows();
  }
  List<Map<String, Object>> mapList = new ArrayList<>();
  //遍歷行數(shù)
  for (int i = StatrRow - 1; i < endRowNum; i++) {
  Row row = sheet.getRow(i);
  if (null == row) {
   continue;
  }
  //獲取需要的列數(shù)據(jù)
  t texcel = (t) t.newInstance();
  for (Map.Entry<String, Object> map : exceltoPOJO.entrySet()) {
   //獲取Exceld對應(yīng)列的數(shù)據(jù)
   String celldata = convertCellValueToString(row.getCell(Integer.parseInt(map.getKey())));
   //使用發(fā)射
   //獲取實體類T中指定成員變量的對象
   PropertyDescriptor pd = new PropertyDescriptor((String) map.getValue(), texcel.getClass());
   //獲取成員變量的set方法
   Method method = pd.getWriteMethod();
   //判斷成員變量的類型
   Field field = texcel.getClass().getDeclaredField((String) map.getValue());
   String object = field.getGenericType().getTypeName();
   if (object.endsWith("String")) {
   //執(zhí)行set方法
   method.invoke(texcel, celldata);
   }
   if (object.endsWith("Double")) {
   Double middata = Double.valueOf(celldata);
   //執(zhí)行set方法
   method.invoke(texcel, middata);
   }
   if (object.endsWith("Float")) {
   Float middata = Float.valueOf(celldata);
   //執(zhí)行set方法
   method.invoke(texcel, middata);
   }
   if (object.endsWith("Integer")) {
   Integer middata = Integer.parseInt(celldata);
   //執(zhí)行set方法
   method.invoke(texcel, middata);
   }
  }
  result.add(texcel);
  }
 }
 return result;
 }

 /**
 * 獲取對應(yīng)的實體類成員
 * */
 private static Map<String, Object> getPOJOFieldAndValue(Class T) {
 //聲明返回結(jié)果集
 Map<String, Object> result = new HashMap<>();
 Field[] fields = T.getDeclaredFields();//獲取屬性名
 if (fields != null) {
  for (Field field : fields) {
  excelRescoure Rescoure = field.getAnnotation(excelRescoure.class);
  if (Rescoure.value() != null && !"".equals(Rescoure.value())) {
   result.put(Rescoure.value(), field.getName());
  }
  }
 } else {
  logger.warn("實體類:" + T + "不存在成員變量");
  return null;
 }
 return result;
 }
}

5.測試類

package com.cly.utils.Excel;

import java.util.*;


/**
 * @author : CLy
 * @ClassName : Readtest
 * @date : 2020/7/9 16:31
 **/
public class Readtest {
public static void main(String[] args) throws Exception {
 /** 方法一
 * fileName:Excel文件路徑
 * StatrRow:讀取的開始行數(shù)(默認(rèn)填0)
 * EndRow:讀取的結(jié)束行數(shù)(填-1為全部)
 * ExistTop:是否存在頭部(如存在則讀取數(shù)據(jù)時會把頭部拼接到對應(yīng)數(shù)據(jù)作為KEY,若無則KEY為當(dāng)前列數(shù))
 */
 List<Map<String,Object>> result =excelRead.ReadExcelByRC("D:.xls",2,10,false);
 System.out.println(result.size());
 System.out.println(result);

 /**
 * 方法二
 * ReadExcelByPOJO(String fileName, int StatrRow, int EndRow, Class t)
 * fileName:Excel文件路徑
 * StatrRow:讀取的開始行數(shù)(默認(rèn)填0)
 * EndRow:讀取的結(jié)束行數(shù)(填-1為全部)
 * Class<T>:傳過來的實體類類型
 */
 List<Object> result2 = excelRead.ReadExcelByPOJO("D:.xls",2,10,ExcelPOJO.class);
 System.out.println(result2.size());
 System.out.println(result2);
 }
}
 

6.運行結(jié)果和說明

exce表格數(shù)據(jù)

方法一的運行結(jié)果

1.ture:key為列名

2.false:key為第幾列列數(shù)

方法二的運行結(jié)果

實體類的所有成員變量一定要加上自定義注釋@excelRescoure,不然會報錯


還有很多不足的地方,請多多指點,希望能給你帶來幫助。

SpringBoot實現(xiàn)內(nèi)存數(shù)據(jù)導(dǎo)出成Excel在另一篇文章 文章地址:http://www.dbjr.com.cn/article/202767.htm

總結(jié)

到此這篇關(guān)于SpringBoot實現(xiàn)Excel讀取的文章就介紹到這了,更多相關(guān)SpringBoot實現(xiàn)Excel讀取內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring Boot 2.x基礎(chǔ)教程之使用@Scheduled實現(xiàn)定時任務(wù)的方法

    Spring Boot 2.x基礎(chǔ)教程之使用@Scheduled實現(xiàn)定時任務(wù)的方法

    在Spring Boot中編寫定時任務(wù)是非常簡單的事,下面通過實例介紹如何在Spring Boot中創(chuàng)建定時任務(wù),實現(xiàn)每過5秒輸出一個當(dāng)前時間,感興趣的朋友跟隨小編一起看看吧
    2021-07-07
  • 一文帶你學(xué)會Java網(wǎng)絡(luò)編程

    一文帶你學(xué)會Java網(wǎng)絡(luò)編程

    網(wǎng)絡(luò)編程是指編寫運行在多個設(shè)備(計算機)的程序,這些設(shè)備都通過網(wǎng)絡(luò)連接起來。這篇文章將帶大家深入了解一下Java的網(wǎng)絡(luò)編程,需要的可以了解一下
    2022-08-08
  • java原碼補碼反碼關(guān)系解析

    java原碼補碼反碼關(guān)系解析

    這篇文章主要為大家詳細(xì)介紹了java原碼補碼反碼的關(guān)系,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-02-02
  • java事件處理模型知識點總結(jié)

    java事件處理模型知識點總結(jié)

    在本篇文章里小辮給大家分享的是一篇關(guān)于java事件處理模型知識點總結(jié)內(nèi)容,有興趣的朋友們可以學(xué)習(xí)下。
    2021-01-01
  • Springboot2.0處理自定義異常并返回json

    Springboot2.0處理自定義異常并返回json

    這篇文章主要介紹了Springboot2.0處理自定義異常并返回json,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-11-11
  • 淺談Spring @Async異步線程池用法總結(jié)

    淺談Spring @Async異步線程池用法總結(jié)

    本篇文章主要介紹了淺談Spring @Async異步線程池用法總結(jié),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • JDK10新特性之本地變量類型var的深入理解

    JDK10新特性之本地變量類型var的深入理解

    這篇文章主要給大家介紹了J關(guān)于DK10新特性之本地變量類型var的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用JDK10具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-05-05
  • Java多線程實現(xiàn)TCP網(wǎng)絡(luò)Socket編程(C/S通信)

    Java多線程實現(xiàn)TCP網(wǎng)絡(luò)Socket編程(C/S通信)

    這篇文章主要介紹了Java多線程實現(xiàn)TCP網(wǎng)絡(luò)Socket編程(C/S通信),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-10-10
  • Java并發(fā)編程之ConcurrentLinkedQueue源碼詳解

    Java并發(fā)編程之ConcurrentLinkedQueue源碼詳解

    今天帶小伙伴們學(xué)習(xí)一下Java并發(fā)編程之Java ConcurrentLinkedQueue源碼,本篇文章詳細(xì)分析了ConcurrentLinkedQueue源碼,有代碼示例,對正在學(xué)習(xí)java的小伙伴們很有幫助喲,需要的朋友可以參考下
    2021-05-05
  • application作用域?qū)崿F(xiàn)用戶登錄擠掉之前登錄用戶代碼

    application作用域?qū)崿F(xiàn)用戶登錄擠掉之前登錄用戶代碼

    這篇文章主要介紹了application作用域?qū)崿F(xiàn)用戶登錄擠掉之前登錄用戶代碼,具有一定參考價值,需要的朋友可以了解下。
    2017-11-11

最新評論