首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Java 開發高頻小技巧持續集錦:集合遍歷、反射操作、屬性加載與 Ant 路徑匹配

     編輯:Java 綜合教學

Java 開發高頻小技巧持續集錦:提效神器與避坑指南

工作中積累的「小而美」技巧,往往能瞬間解決棘手問題。本文持續更新,記錄集合統一遍歷、反射操作數組、Properties 批量加載、Ant 路徑通配符等高頻實用技巧。

技巧 1:<c:forEach> 統一遍歷 Map、List、Array、Set

JSTL 核心標簽庫 `` 內部適配了 `java.util.Collection`、`java.util.Map` (遍歷 `entrySet`)、數組 (`Object[]`/`基本類型[]`)、`Iterator`、`Enumeration`。一個標簽搞定所有可迭代結構。

<%-- 1. List/Set/Array --%>
<c:forEach var="item" items="${listOrArray}">
    ${item} <br/>
</c:forEach>

<%-- 2. Map (varStatus 可獲取索引) --%>
<c:forEach var="entry" items="${map}" varStatus="status">
    Key: ${entry.key}, Value: ${entry.value}, Index: ${status.index} <br/>
</c:forEach>

<%-- 3. 固定次數循環 --%>
<c:forEach var="i" begin="1" end="10" step="2">
    ${i} <br/>
</c:forEach>

注意:Map 遍歷時 `${entry}` 是 `Map.Entry` 對象,用 `${entry.key}` / `${entry.value}` 取值。

技巧 2:反射通用操作數組 (無需判斷類型)

場景:方法參數為 `Object`,實際可能是 `String[]`、`int[]`、`Object[]`、`List` 轉數組等。使用 `java.lang.reflect.Array` 統一獲取長度、讀取元素、設置元素,**完全屏蔽基本類型/引用類型數組差異**。

import java.lang.reflect.Array;

public static void processArray(Object arrayObj) {
    // 1. 校驗是否為數組
    if (arrayObj == null || !arrayObj.getClass().isArray()) {
        throw new IllegalArgumentException("參數必須是數組");
    }
    
    // 2. 獲取長度 (統一 API)
    int length = Array.getLength(arrayObj);
    System.out.println("數組長度: " + length);
    
    // 3. 遍歷讀取元素 (統一返回 Object,基本類型自動裝箱)
    for (int i = 0; i < length; i++) {
        Object element = Array.get(arrayObj, i);
        System.out.println("Index " + i + ": " + element);
    }
    
    // 4. 設置元素 (需類型匹配,否則 ArrayStoreException)
    // Array.set(arrayObj, 0, "newValue"); 
}

// 測試
String[] strs = {"a", "b"};
int[] nums = {1, 2, 3};
processArray(strs); // 正常
processArray(nums); // 正常,自動裝箱為 Integer
processArray(new ArrayList<>()); // 拋異常

核心 API:Array.getLength(Object)、Array.get(Object, int)、Array.set(Object, int, Object)、Array.newInstance(Class, int) (動態創建數組)。

技巧 3:Spring PropertiesLoaderUtils.loadAllProperties() 批量加載屬性文件

場景:項目中有多個 `*.properties` 文件 (如 `config.properties`, `db.properties`, `redis.properties`),需合併加載到單一 `Properties` 對象,支持 classpath 下多文件匹配、覆蓋策略。

import org.springframework.core.io.support.PropertiesLoaderUtils;
import java.io.IOException;
import java.util.Properties;

public Properties loadAllConfigs() throws IOException {
    // 加載 classpath 下所有以 config- 開頭的 .properties 文件
    // 返回合併後的 Properties,後加載的覆蓋先加載的同名鍵
    Properties props = PropertiesLoaderUtils.loadAllProperties("config-*.properties");
    
    // 也可指定具體文件列表
    // Properties props = PropertiesLoaderUtils.loadProperties(new ClassPathResource("db.properties"));
    return props;
}

// 用法
String dbUrl = props.getProperty("jdbc.url");

優勢:自動處理資源流關閉、編碼 (默認 ISO-8859-1,建議文件存為 UTF-8 並配合 `new EncodedResource(resource, "UTF-8")`)、多文件合併邏輯。

技巧 4:Ant 路徑通配符語法精通 (Spring ResourceLoader、@Value、Logback、MyBatis mapper 掃描通用)

Ant 風格路徑匹配是 Spring 生態標準,三大通配符:

符號含義匹配示例不匹配示例
?匹配單個字符 (不含路徑分隔符)`file?.txt` → `file1.txt``file12.txt`, `dir/file.txt`
*匹配任意字符 (不含路徑分隔符 `/` `\`)`*.properties` → `a.properties``dir/a.properties` (跨目錄)
**匹配任意字符含路徑分隔符 (遞歸匹配多級目錄)`**/mapper/*.xml` → `com/dao/UserMapper.xml`無 (最強通配)

實戰組合模式

// 1. 掃描所有子包下的 Mapper XML (MyBatis mapper-locations)
classpath*:mapper/**/*.xml
classpath*:com/**/mapper/*.xml

// 2. 加載多環境配置文件 (Spring @PropertySource)
classpath:config/application-${spring.profiles.active}.properties

// 3. Logback 掃描配置變更

 // 非 Ant 路徑

// 4. Spring @Value 注入文件內容
@Value("classpath:templates/email/*.ftl")
private Resource[] emailTemplates; // 注入數組

技巧 5:快速判斷對象為空的通用方法 (工具類)

public static boolean isEmpty(Object obj) {
    if (obj == null) return true;
    if (obj instanceof CharSequence) return ((CharSequence) obj).length() == 0;
    if (obj.getClass().isArray()) return Array.getLength(obj) == 0;
    if (obj instanceof Collection) return ((Collection) obj).isEmpty();
    if (obj instanceof Map) return ((Map) obj).isEmpty();
    return false; // 其他對象視為非空
}

技巧 6:JDK 8+ Map 合併與計算 (原子操作)

Map counts = new HashMap<>();

// merge: key 存在則應用函數合併值,不存在則插入值
counts.merge("apple", 1, (oldVal, newVal) -> oldVal + newVal); // 計數器神器

// computeIfAbsent: 緩存模式 (線程安全需 ConcurrentHashMap)
Map> cache = new ConcurrentHashMap<>();
List list = cache.computeIfAbsent("key", k -> new ArrayList<>());
list.add("value");

// computeIfPresent: 值存在時重新計算
counts.computeIfPresent("apple", (k, v) -> v + 1);

持續更新中...

歡迎在評論區分享你的「壓箱底」小技巧,我將整合進後續版本。關注不迷路,下期預告:Stream 流式編程避坑指南、CompletableFuture 異步編排實戰、Arthas 線上診斷命令速查表。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved