Java 提供了强大的网络编程能力和字符串处理工具,包括URL数据处理、StringBuffer和StringBuilder类,这些在处理网络请求和字符串操作时非常有用。
URL 数据处理基础
Java 中可以使用 URL 和 HttpURLConnection 类进行网络请求:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class URLBasicExample {
public static String fetchDataFromURL(String urlString) throws IOException {
StringBuilder result = new StringBuilder();
HttpURLConnection connection = null;
BufferedReader reader = null;
try {
// 创建URL对象
URL url = new URL(urlString);
// 打开连接
connection = (HttpURLConnection) url.openConnection();
// 设置请求方法
connection.setRequestMethod("GET");
// 设置超时时间
connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);
// 设置请求头
connection.setRequestProperty("User-Agent", "Mozilla/5.0");
connection.setRequestProperty("Accept", "application/json");
// 获取响应码
int responseCode = connection.getResponseCode();
System.out.println("响应码: " + responseCode);
if (responseCode == HttpURLConnection.HTTP_OK) {
// 读取响应数据
reader = new BufferedReader(
new InputStreamReader(connection.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
result.append(line);
result.append("\n");
}
} else {
System.out.println("请求失败,响应码: " + responseCode);
}
} finally {
// 关闭资源
if (reader != null) {
reader.close();
}
if (connection != null) {
connection.disconnect();
}
}
return result.toString();
}
public static void main(String[] args) {
try {
String url = "https://jsonplaceholder.typicode.com/posts/1";
String response = fetchDataFromURL(url);
System.out.println("获取的数据:");
System.out.println(response);
} catch (IOException e) {
e.printStackTrace();
}
}
}
StringBuffer 类详解
StringBuffer 是线程安全的可变字符串类:
public class StringBufferExample {
public static void main(String[] args) {
// 1. 创建 StringBuffer 对象
StringBuffer sb1 = new StringBuffer(); // 默认容量16
StringBuffer sb2 = new StringBuffer(50); // 指定初始容量
StringBuffer sb3 = new StringBuffer("Hello"); // 指定初始字符串
System.out.println("初始字符串: " + sb3);
System.out.println("初始容量: " + sb3.capacity());
System.out.println("当前长度: " + sb3.length());
// 2. 追加操作
sb3.append(" World");
sb3.append("!");
System.out.println("追加后: " + sb3);
// 3. 插入操作
sb3.insert(5, " Beautiful");
System.out.println("插入后: " + sb3);
// 4. 删除操作
sb3.delete(5, 15); // 删除 " Beautiful"
System.out.println("删除后: " + sb3);
// 5. 替换操作
sb3.replace(6, 11, "Java");
System.out.println("替换后: " + sb3);
// 6. 反转操作
sb3.reverse();
System.out.println("反转后: " + sb3);
sb3.reverse(); // 恢复原状
// 7. 设置字符和获取字符
sb3.setCharAt(0, 'h');
System.out.println("修改首字符后: " + sb3);
System.out.println("第1个字符: " + sb3.charAt(0));
// 8. 子字符串操作
System.out.println("子字符串(0,5): " + sb3.substring(0, 5));
// 9. 容量管理
System.out.println("当前容量: " + sb3.capacity());
sb3.ensureCapacity(100); // 确保最小容量
System.out.println("确保容量后: " + sb3.capacity());
// 10. 性能测试 - 大量字符串拼接
StringBuffer performanceTest = new StringBuffer();
long startTime = System.currentTimeMillis();
for (int i = 0; i < 10000; i++) {
performanceTest.append("Number ").append(i).append(", ");
}
long endTime = System.currentTimeMillis();
System.out.println("StringBuffer 拼接10000次耗时: " + (endTime - startTime) + "ms");
// 11. 线程安全演示
System.out.println("\n=== 线程安全测试 ===");
StringBuffer threadSafeBuffer = new StringBuffer();
Thread t1 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
threadSafeBuffer.append("A");
}
});
Thread t2 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
threadSafeBuffer.append("B");
}
});
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程安全测试完成,长度: " + threadSafeBuffer.length());
}
}
StringBuilder 类详解
StringBuilder 是非线程安全的可变字符串类,性能更高:
public class StringBuilderExample {
public static void main(String[] args) {
// 1. 创建 StringBuilder 对象
StringBuilder sb1 = new StringBuilder();
StringBuilder sb2 = new StringBuilder(50);
StringBuilder sb3 = new StringBuilder("Hello");
System.out.println("初始字符串: " + sb3);
// 2. 链式操作
sb3.append(" World")
.append("!")
.insert(5, " Amazing")
.delete(5, 13);
System.out.println("链式操作后: " + sb3);
// 3. 性能测试 - 与 StringBuffer 对比
int iterations = 100000;
// StringBuilder 性能测试
StringBuilder sbPerformance = new StringBuilder();
long startTime1 = System.currentTimeMillis();
for (int i = 0; i < iterations; i++) {
sbPerformance.append("test");
}
long endTime1 = System.currentTimeMillis();
System.out.println("StringBuilder 拼接" + iterations + "次耗时: " + (endTime1 - startTime1) + "ms");
// StringBuffer 性能测试
StringBuffer sbufPerformance = new StringBuffer();
long startTime2 = System.currentTimeMillis();
for (int i = 0; i < iterations; i++) {
sbufPerformance.append("test");
}
long endTime2 = System.currentTimeMillis();
System.out.println("StringBuffer 拼接" + iterations + "次耗时: " + (endTime2 - startTime2) + "ms");
// 4. 复杂字符串构建
StringBuilder complexBuilder = new StringBuilder();
// 构建表格数据
complexBuilder.append("=== 学生信息表 ===\n");
complexBuilder.append(String.format("%-10s %-8s %-6s\n", "姓名", "年龄", "成绩"));
complexBuilder.append("------------------------\n");
String[][] students = {
{"张三", "20", "85"},
{"李四", "19", "92"},
{"王五", "21", "78"}
};
for (String[] student : students) {
complexBuilder.append(String.format("%-10s %-8s %-6s\n",
student[0], student[1], student[2]));
}
System.out.println("\n构建的表格:");
System.out.println(complexBuilder.toString());
// 5. 字符串处理工具方法
System.out.println("\n=== 字符串处理工具 ===");
String processed = processString(" Hello, World! ");
System.out.println("处理后的字符串: " + processed + );
}
// 字符串处理工具方法
public static String processString(String input) {
StringBuilder sb = new StringBuilder(input);
// 去除首尾空格
while (sb.length() > 0 && Character.isWhitespace(sb.charAt(0))) {
sb.deleteCharAt(0);
}
while (sb.length() > 0 && Character.isWhitespace(sb.charAt(sb.length() - 1))) {
sb.deleteCharAt(sb.length() - 1);
}
// 转换为大写
for (int i = 0; i < sb.length(); i++) {
char c = sb.charAt(i);
if (Character.isLowerCase(c)) {
sb.setCharAt(i, Character.toUpperCase(c));
}
}
return sb.toString();
}
}
综合应用:URL数据处理工具
结合URL处理和字符串构建的实际应用:
import java.io.*;
import java.net.*;
import java.util.*;
public class URLDataProcessor {
// 获取URL内容并处理
public static String processURLData(String urlString) throws IOException {
StringBuilder result = new StringBuilder();
HttpURLConnection connection = null;
BufferedReader reader = null;
try {
URL url = new URL(urlString);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(10000);
connection.setReadTimeout(10000);
connection.setRequestProperty("User-Agent", "Java-URL-Processor");
int responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line;
int lineCount = 0;
while ((line = reader.readLine()) != null && lineCount < 100) {
// 处理每一行数据
String processedLine = processLine(line, lineCount + 1);
result.append(processedLine).append("\n");
lineCount++;
}
if (line != null) {
result.append("... (数据截断,只显示前100行)\n");
}
} else {
result.append("请求失败,响应码: ").append(responseCode);
}
} finally {
if (reader != null) reader.close();
if (connection != null) connection.disconnect();
}
return result.toString();
}
// 处理单行数据
private static String processLine(String line, int lineNumber) {
StringBuilder processed = new StringBuilder();
// 添加行号
processed.append(String.format("[%03d] ", lineNumber));
// 去除首尾空白
String trimmed = line.trim();
// 如果行太长,进行截断
if (trimmed.length() > 100) {
processed.append(trimmed.substring(0, 97)).append("...");
} else {
processed.append(trimmed);
}
// 统计信息(在行末添加)
processed.append(" [长度:").append(trimmed.length()).append("]");
return processed.toString();
}
// 构建URL参数
public static String buildURLWithParams(String baseURL, Map params) {
StringBuilder urlBuilder = new StringBuilder(baseURL);
if (params != null && !params.isEmpty()) {
urlBuilder.append("?");
boolean firstParam = true;
for (Map.Entry entry : params.entrySet()) {
if (!firstParam) {
urlBuilder.append("&");
}
try {
// URL编码参数
String encodedKey = URLEncoder.encode(entry.getKey(), "UTF-8");
String encodedValue = URLEncoder.encode(entry.getValue(), "UTF-8");
urlBuilder.append(encodedKey).append("=").append(encodedValue);
firstParam = false;
} catch (UnsupportedEncodingException e) {
System.err.println("URL编码错误: " + e.getMessage());
}
}
}
return urlBuilder.toString();
}
// 解析URL参数
public static Map parseURLParams(String urlString) {
Map params = new HashMap<>();
try {
URL url = new URL(urlString);
String query = url.getQuery();
if (query != null) {
String[] pairs = query.split("&");
for (String pair : pairs) {
int idx = pair.indexOf("=");
if (idx > 0) {
String key = URLDecoder.decode(pair.substring(0, idx), "UTF-8");
String value = URLDecoder.decode(pair.substring(idx + 1), "UTF-8");
params.put(key, value);
}
}
}
} catch (Exception e) {
System.err.println("解析URL参数错误: " + e.getMessage());
}
return params;
}
public static void main(String[] args) {
try {
// 测试URL构建
Map params = new HashMap<>();
params.put("q", "java programming");
params.put("page", "1");
params.put("sort", "relevance");
String testURL = buildURLWithParams("https://api.example.com/search", params);
System.out.println("构建的URL: " + testURL);
// 测试URL参数解析
Map parsedParams = parseURLParams(testURL);
System.out.println("解析的参数: " + parsedParams);
// 测试URL数据处理(使用公开的测试API)
String apiURL = "https://jsonplaceholder.typicode.com/posts";
String processedData = processURLData(apiURL);
System.out.println("\n处理后的数据:");
System.out.println(processedData);
} catch (IOException e) {
e.printStackTrace();
}
}
}
StringBuffer vs StringBuilder 对比
public class StringBufferVsStringBuilder {
public static void main(String[] args) {
final int ITERATIONS = 100000;
// 单线程性能测试
System.out.println("=== 单线程性能测试 ===");
// StringBuilder 测试
long startTime = System.nanoTime();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < ITERATIONS; i++) {
sb.append("test");
}
long sbTime = System.nanoTime() - startTime;
// StringBuffer 测试
startTime = System.nanoTime();
StringBuffer sbf = new StringBuffer();
for (int i = 0; i < ITERATIONS; i++) {
sbf.append("test");
}
long sbfTime = System.nanoTime() - startTime;
System.out.println("StringBuilder 耗时: " + sbTime + " ns");
System.out.println("StringBuffer 耗时: " + sbfTime + " ns");
System.out.println("StringBuilder 比 StringBuffer 快: " +
((double)(sbfTime - sbTime) / sbfTime * 100) + "%");
// 多线程安全性测试
System.out.println("\n=== 多线程安全性测试 ===");
// StringBuilder 多线程测试(可能产生不一致结果)
StringBuilder unsafeBuilder = new StringBuilder();
Thread t1 = new Thread(() -> appendMany(unsafeBuilder, "A", 1000));
Thread t2 = new Thread(() -> appendMany(unsafeBuilder, "B", 1000));
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("StringBuilder 最终长度: " + unsafeBuilder.length());
// StringBuffer 多线程测试(线程安全)
StringBuffer safeBuffer = new StringBuffer();
Thread t3 = new Thread(() -> appendMany(safeBuffer, "A", 1000));
Thread t4 = new Thread(() -> appendMany(safeBuffer, "B", 1000));
t3.start();
t4.start();
try {
t3.join();
t4.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("StringBuffer 最终长度: " + safeBuffer.length());
}
private static void appendMany(Appendable appender, String str, int count) {
for (int i = 0; i < count; i++) {
try {
appender.append(str);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
关键知识点总结
- URL 连接:使用 HttpURLConnection 进行网络请求,设置超时和请求头
- StringBuffer:线程安全的可变字符串,适合多线程环境
- StringBuilder:非线程安全的可变字符串,单线程环境下性能更好
- 字符串操作:append、insert、delete、replace、reverse 等方法
- 性能考虑:大量字符串操作时使用 StringBuilder/StringBuffer 而不是 String
- URL 编码:使用 URLEncoder/URLDecoder 处理URL参数
最佳实践
- 单线程环境下优先使用 StringBuilder
- 多线程环境下使用 StringBuffer
- 大量字符串拼接时避免使用 String 的 + 操作符
- 网络请求时设置合理的超时时间
- 及时关闭网络连接和流资源
- 对URL参数进行编码以防止特殊字符问题
注意:在实际项目中,对于复杂的网络请求,建议使用更高级的HTTP客户端库如 Apache HttpClient 或 OkHttp,它们提供了更好的功能和错误处理机制。
提示: 这是一个重要的概念,需要特别注意理解和掌握。
注意: 这是一个常见的错误点,请避免犯同样的错误。