常需從完整 URL(如 https://example.com/api?user=john&id=123&tag=java)中提取參數鍵值對,轉為 Map<String, String> 供後續業務使用。本文提供兩種實作:標準切割法與單次遍歷法。
import java.util.*;
public class UrlParamParser {
/** 移除協定、域名、路徑,只保留查詢字串部分 */
private static String extractQueryString(String url) {
if (url == null) return null;
int idx = url.indexOf('?');
return (idx >= 0) ? url.substring(idx + 1) : null;
}
/** 解析查詢字串為 Map */
public static Map<String, String> parse(String url) {
Map<String, String> params = new LinkedHashMap<>();
String query = extractQueryString(url);
if (query == null || query.isEmpty()) return params;
String[] pairs = query.split("&");
for (String pair : pairs) {
String[] kv = pair.split("=", 2); // 限制切成 2 份,值中可含 '='
String key = kv[0];
String value = (kv.length > 1) ? kv[1] : "";
params.put(key, value);
}
return params;
}
}
public static Map<String, String> parseFast(String query) {
Map<String, String> params = new LinkedHashMap<>();
if (query == null || query.isEmpty()) return params;
StringBuilder key = new StringBuilder();
StringBuilder value = new StringBuilder();
boolean parsingKey = true;
for (int i = 0; i < query.length(); i++) {
char c = query.charAt(i);
if (parsingKey) {
if (c == '=') {
parsingKey = false;
} else {
key.append(c);
}
} else { // parsing value
if (c == '&') {
params.put(key.toString(), value.toString());
key.setLength(0);
value.setLength(0);
parsingKey = true;
} else {
value.append(c);
}
}
}
// 最後一組
if (key.length() > 0) {
params.put(key.toString(), value.toString());
}
return params;
}
String url = "https://shop.com/item?id=1001&name=phone&color=black&color=blue";
Map<String, String> map = UrlParamParser.parse(url);
// 輸出: {id=1001, name=phone, color=blue} // 注意:重複 key 後者覆蓋前者
// 若需保留多值,請改用 Map<String, List<String>>
%20 等編碼,建議搭配 URLDecoder.decode(value, StandardCharsets.UTF_8)。List<String> 並在 put 邏輯中累加。方法一程式碼簡潔、易維護,適合大多數業務場景;方法二適合高併發、大量解析的效能敏感場景。根據專案需求選擇即可。