1. Java编程函数概述
Java作为一门面向对象的编程语言,其标准库提供了丰富的内置函数,这些函数是Java开发者日常工作中不可或缺的工具。根据我的开发经验,合理使用这些函数能显著提升代码质量和开发效率。Java的函数主要分布在以下几个核心包中:
- java.lang:包含最基础的类和接口,自动导入无需显式声明
- java.util:提供集合框架、日期时间处理等实用工具
- java.io:处理输入输出操作
- java.net:网络编程相关功能
- java.math:数学运算支持
提示:Java 8引入的函数式编程特性(如Lambda表达式)极大地改变了传统函数的使用方式,建议优先掌握java.util.function包中的函数式接口。
2. 字符串处理函数精要
2.1 基础字符串操作
String类是Java中使用最频繁的类之一,其核心方法包括:
java复制// 字符串比较
boolean equals = "Java".equals("java"); // false - 区分大小写
boolean equalsIgnoreCase = "Java".equalsIgnoreCase("java"); // true
// 字符串拼接
String concat = "Hello".concat(" World"); // "Hello World"
String format = String.format("PI: %.2f", Math.PI); // "PI: 3.14"
// 子字符串处理
String substring = "HelloWorld".substring(5); // "World"
在实际项目中,我经常遇到的一个坑是substring的索引越界问题。特别是在处理用户输入时,一定要先检查字符串长度:
java复制String safeSubstring(String str, int beginIndex) {
return str.length() > beginIndex ? str.substring(beginIndex) : "";
}
2.2 正则表达式应用
Pattern和Matcher类提供了强大的正则处理能力:
java复制Pattern pattern = Pattern.compile("\\d{3}-\\d{2}-\\d{4}");
Matcher matcher = pattern.matcher("123-45-6789");
boolean matches = matcher.matches(); // 验证SSN格式
// 分组提取示例
Pattern emailPattern = Pattern.compile("(\\w+)@(\\w+\\.\\w+)");
Matcher emailMatcher = emailPattern.matcher("user@example.com");
if (emailMatcher.find()) {
String username = emailMatcher.group(1); // "user"
String domain = emailMatcher.group(2); // "example.com"
}
注意:复杂的正则表达式会显著影响性能,在循环中使用时建议预编译Pattern对象。
3. 集合框架核心函数
3.1 List和Map操作
java复制// List常用操作
List<String> list = new ArrayList<>();
list.add("Java");
list.add(0, "Python"); // 指定位置插入
list.remove("Python"); // 元素删除
list.sort(String.CASE_INSENSITIVE_ORDER); // 排序
// Map高效使用
Map<String, Integer> map = new HashMap<>();
map.put("Java", 1);
map.computeIfAbsent("Python", k -> 2); // 不存在时计算值
map.merge("Java", 1, Integer::sum); // 合并值
在并发环境下,我推荐使用ConcurrentHashMap的原子操作方法:
java复制ConcurrentHashMap<String, Long> counter = new ConcurrentHashMap<>();
counter.compute("visits", (k, v) -> v == null ? 1 : v + 1);
3.2 Java 8 Stream API
Stream API极大简化了集合处理:
java复制List<String> languages = Arrays.asList("Java", "Python", "C++", "JavaScript");
// 过滤和转换
List<String> filtered = languages.stream()
.filter(s -> s.startsWith("J"))
.map(String::toUpperCase)
.collect(Collectors.toList());
// 分组统计
Map<Integer, List<String>> byLength = languages.stream()
.collect(Collectors.groupingBy(String::length));
// 并行处理
long count = languages.parallelStream()
.filter(s -> s.length() > 3)
.count();
实测发现,当数据量超过1000条时,parallelStream才能体现性能优势,小数据集反而可能更慢。
4. 文件与IO操作函数
4.1 传统IO操作
java复制// 文件读写
try (BufferedReader reader = new BufferedReader(new FileReader("input.txt"));
BufferedWriter writer = new BufferedWriter(new FileWriter("output.txt"))) {
String line;
while ((line = reader.readLine()) != null) {
writer.write(line.toUpperCase());
writer.newLine();
}
} // 自动关闭资源
// 文件系统操作
Files.createDirectories(Paths.get("logs/2023")); // 创建多级目录
long size = Files.size(Paths.get("data.bin")); // 获取文件大小
4.2 NIO高效处理
Java NIO提供了更高效的IO操作:
java复制// 文件快速复制
Path source = Paths.get("source.txt");
Path target = Paths.get("target.txt");
Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);
// 内存映射文件
try (RandomAccessFile file = new RandomAccessFile("large.bin", "rw");
FileChannel channel = file.getChannel()) {
MappedByteBuffer buffer = channel.map(
FileChannel.MapMode.READ_WRITE, 0, channel.size());
while (buffer.hasRemaining()) {
byte b = buffer.get();
// 处理字节数据
}
}
在处理大文件时,NIO的内存映射技术可以提升数倍性能,但要注意内存消耗。
5. 日期时间处理函数
5.1 Java 8时间API
java复制// 当前时间
LocalDateTime now = LocalDateTime.now();
LocalDate today = LocalDate.now();
// 日期计算
LocalDate nextWeek = today.plusWeeks(1);
Period period = Period.between(today, nextWeek);
// 时间格式化
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
String formatted = now.format(formatter);
LocalDateTime parsed = LocalDateTime.parse("2023-07-15 14:30", formatter);
// 时区处理
ZonedDateTime zoned = ZonedDateTime.now(ZoneId.of("America/New_York"));
Instant instant = zoned.toInstant();
5.2 与传统Date的互操作
java复制// 新旧API转换
Date legacyDate = Date.from(instant);
Instant newInstant = legacyDate.toInstant();
// 兼容处理
Calendar calendar = Calendar.getInstance();
LocalDateTime fromCalendar = LocalDateTime.ofInstant(
calendar.toInstant(), ZoneId.systemDefault());
在实际项目中,我建议尽早将遗留代码迁移到java.time API,它解决了传统Date类的诸多线程安全问题。
6. 并发编程关键函数
6.1 线程基础操作
java复制// 线程创建
Thread thread = new Thread(() -> {
System.out.println("Running in thread: " + Thread.currentThread().getName());
});
thread.start();
// 线程池使用
ExecutorService executor = Executors.newFixedThreadPool(4);
Future<String> future = executor.submit(() -> {
Thread.sleep(1000);
return "Result";
});
String result = future.get(2, TimeUnit.SECONDS); // 带超时获取
6.2 并发工具类
java复制// CountDownLatch示例
CountDownLatch latch = new CountDownLatch(3);
for (int i = 0; i < 3; i++) {
new Thread(() -> {
// 执行任务
latch.countDown();
}).start();
}
latch.await(); // 等待所有线程完成
// CompletableFuture链式调用
CompletableFuture.supplyAsync(() -> fetchData())
.thenApply(data -> processData(data))
.thenAccept(result -> saveResult(result))
.exceptionally(ex -> {
System.err.println("Error: " + ex.getMessage());
return null;
});
在微服务架构中,CompletableFuture可以优雅地处理多个异步调用的组合。
7. 反射与动态代理
7.1 反射基础应用
java复制// 获取类信息
Class<?> clazz = Class.forName("com.example.User");
Constructor<?> constructor = clazz.getConstructor(String.class, int.class);
Object user = constructor.newInstance("Alice", 25);
// 方法调用
Method method = clazz.getMethod("getName");
String name = (String) method.invoke(user);
// 字段访问
Field field = clazz.getDeclaredField("age");
field.setAccessible(true); // 突破私有限制
int age = (int) field.get(user);
警告:反射会破坏封装性并影响性能,仅在必要时使用,如框架开发。
7.2 动态代理实现
java复制interface Service {
void serve();
}
Service realService = new Service() {
public void serve() { System.out.println("Real service"); }
};
Service proxy = (Service) Proxy.newProxyInstance(
Service.class.getClassLoader(),
new Class<?>[] { Service.class },
(proxyObj, method, args) -> {
System.out.println("Before service");
Object result = method.invoke(realService, args);
System.out.println("After service");
return result;
}
);
proxy.serve();
Spring等框架大量使用动态代理实现AOP,理解其原理对框架学习很有帮助。
8. 函数式编程实践
8.1 常用函数式接口
java复制// Predicate示例
Predicate<String> isLong = s -> s.length() > 10;
boolean test = isLong.test("HelloWorld"); // false
// Function链式调用
Function<String, Integer> parse = Integer::parseInt;
Function<Integer, String> toHex = Integer::toHexString;
Function<String, String> pipeline = parse.andThen(toHex);
String hex = pipeline.apply("255"); // "ff"
// Supplier延迟计算
Supplier<Double> randomSupplier = Math::random;
double value = randomSupplier.get();
8.2 Optional避免空指针
java复制Optional<String> optional = Optional.ofNullable(getPossiblyNullString());
String result = optional
.map(String::toUpperCase)
.filter(s -> s.length() > 3)
.orElse("DEFAULT");
optional.ifPresent(System.out::println);
在项目实践中,我建议将Optional主要用于方法返回值,而不是作为字段或参数类型。
9. 性能优化函数
9.1 数组操作
java复制// 数组排序
int[] numbers = {3, 1, 4, 1, 5, 9};
Arrays.sort(numbers); // 快速排序
Arrays.parallelSort(numbers); // 并行排序(大数据量更优)
// 数组填充
int[] filled = new int[10];
Arrays.fill(filled, 1); // 全部填充为1
// 二分查找
int index = Arrays.binarySearch(numbers, 4);
9.2 系统级操作
java复制// 内存管理
Runtime runtime = Runtime.getRuntime();
long freeMemory = runtime.freeMemory();
long totalMemory = runtime.totalMemory();
runtime.gc(); // 建议JVM进行垃圾回收
// 环境变量
String path = System.getenv("PATH");
Properties props = System.getProperties();
在性能敏感的场景中,System.arraycopy()是比循环更高效的数组复制方式。
10. 实用工具函数
10.1 数学计算
java复制// 基本运算
double sqrt = Math.sqrt(2);
double pow = Math.pow(2, 10);
long max = Math.max(10L, 20L);
// 随机数
Random random = new Random();
int randInt = random.nextInt(100); // 0-99
double randDouble = random.nextDouble(); // 0.0-1.0
// 精确计算
BigDecimal decimal = new BigDecimal("0.1");
BigDecimal sum = decimal.add(new BigDecimal("0.2")); // 0.3(精确)
10.2 对象工具
java复制// 对象比较
boolean nullSafeEquals = Objects.equals(null, "test"); // false
int hash = Objects.hash("Java", 8, true); // 生成哈希码
// 默认值处理
String name = Objects.requireNonNullElse(
getName(), "Unknown"); // 空值替换
在实现equals和hashCode方法时,使用Objects工具类可以简化代码并减少错误。
11. 编码实践建议
-
函数选择原则:
- 优先使用标准库函数而非自己实现
- 注意函数的线程安全性
- 考虑函数的时空复杂度
-
性能陷阱:
- String的+操作在循环中会创建大量对象
- Random实例重复创建会导致随机性下降
- 未关闭的IO流会导致资源泄漏
-
代码可读性:
- 使用方法引用替代简单Lambda
- 保持函数链式调用的合理长度
- 为复杂操作添加注释
-
异常处理:
- 区分检查异常和非检查异常
- 使用try-with-resources管理资源
- 避免在finally块中抛出异常
在实际项目中,我通常会创建一个Utils类来封装常用函数的组合操作,提高代码复用性。例如:
java复制public class StringUtils {
public static boolean isBlank(String str) {
return str == null || str.trim().isEmpty();
}
public static String truncate(String str, int maxLength) {
return str != null && str.length() > maxLength
? str.substring(0, maxLength) + "..."
: str;
}
}
掌握这些常用函数不仅能提高开发效率,还能写出更健壮、更易维护的代码。建议定期查阅Java官方文档,了解API的最新变化。
