Java StringTokenizer 类 & Scanner 类详解

Java StringTokenizer 类介绍

概述

StringTokenizer 是一个遗留类,用于将字符串分割成标记(tokens)。

但在现代 Java 开发中已被更强大的 String.split() 和 Scanner 类取代,新项目应使用更现代的解决方案。

基本用法

1. 构造方法

// 1. 默认分隔符(空格、制表符、换行符等)
StringTokenizer st1 = new StringTokenizer("Hello World Java");
// 2. 指定分隔符
StringTokenizer st2 = new StringTokenizer("A,B,C", ",");
// 3. 指定分隔符并返回分隔符
StringTokenizer st3 = new StringTokenizer("A,B,C", ",", true);

方法

 
方法描述
hasMoreTokens() 是否还有更多标记
nextToken() 返回下一个标记
countTokens() 返回剩余标记数量
hasMoreElements() 同 hasMoreTokens()
nextElement() 同 nextToken(),返回 Object

详细示例

示例1:基本分割

public class BasicExample {
    public static void main(String[] args) {
        String data = "Java;Python;JavaScript;C++";
        StringTokenizer st = new StringTokenizer(data, ";");
        
        System.out.println("Token数量: " + st.countTokens());
        
        while (st.hasMoreTokens()) {
            System.out.println("语言: " + st.nextToken());
        }
    }
}

示例2:CSV解析

public class CSVExample {
    public static void main(String[] args) {
        String csv = "John,25,Developer,New York";
        StringTokenizer st = new StringTokenizer(csv, ",");
        
        System.out.println("姓名: " + st.nextToken());
        System.out.println("年龄: " + st.nextToken());
        System.out.println("职业: " + st.nextToken());
        System.out.println("城市: " + st.nextToken());
    }
}

示例3:复杂分隔符

public class ComplexDelimiter {
    public static void main(String[] args) {
        String text = "Apple and Banana or Cherry but not Date";
        StringTokenizer st = new StringTokenizer(text, " andorbutnot");
        
        while (st.hasMoreTokens()) {
            System.out.println(st.nextToken());
        }
        // 输出: Apple, Banana, Cherry, Date
    }
}

现代替代方案

使用 String.split()(推荐)

public class SplitAlternative {
    public static void main(String[] args) {
        String text = "Apple,Banana,Cherry";
        
        // 简单分割
        String[] fruits = text.split(",");
        for (String fruit : fruits) {
            System.out.println(fruit);
        }
        
        // 正则表达式分割
        String complexText = "A1,B2,C3";
        String[] items = complexText.split(",\\d");
        for (String item : items) {
            System.out.println(item);
        }
    }
}

使用 Scanner 类

import java.util.Scanner;

public class ScannerAlternative {
    public static void main(String[] args) {
        String text = "Apple Banana Cherry";
        Scanner scanner = new Scanner(text);
        
        while (scanner.hasNext()) {
            System.out.println(scanner.next());
        }
        scanner.close();
    }
}

优缺点

优点

  • 简单易用。内存效率较高(不创建数组)。适合大字符串处理。

缺点

  • 功能有限。不支持正则表达式。遗留类,不推荐在新代码中使用

使用建议

不建议在新项目中使用 StringTokenizer,推荐替代方案:

// 1. 简单分割 - 使用 String.split()
String[] parts = text.split(",");

// 2. 复杂分割 - 使用 Pattern/Matcher
Pattern pattern = Pattern.compile("\\s+");
String[] words = pattern.split(text);

// 3. 流式处理 - 使用 Java 8 Stream
Arrays.stream(text.split(","))
      .map(String::trim)
      .filter(s -> !s.isEmpty())
      .forEach(System.out::println);

 

 

Java Scanner 类详解

概述

Scanner 是一个强大的文本扫描器,可以解析原始类型和字符串使用正则表达式。它提供了多种输入解析功能。

基本用法

1. 创建 Scanner 对象

import java.util.Scanner;

public class ScannerBasic {
    public static void main(String[] args) {
        // 从标准输入创建
        Scanner scanner = new Scanner(System.in);
        // 从字符串创建
        Scanner stringScanner = new Scanner("Hello 123 45.67 true");
        // 从文件创建
        Scanner fileScanner = new Scanner(new File("data.txt"));
    }
}

核心方法

读取不同类型数据

public class ScannerTypes {
    public static void main(String[] args) {
        Scanner sc = new Scanner("John 25 75000.50 true");
        // 读取不同类型
        String name = sc.next();        // John
        int age = sc.nextInt();         // 25
        double salary = sc.nextDouble(); // 75000.50
        boolean active = sc.nextBoolean(); // true
        System.out.printf("姓名: %s, 年龄: %d, 薪资: %.2f, 状态: %b%n", 
                         name, age, salary, active);
    }
}

用户输入示例

import java.util.Scanner;

public class UserInputExample {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        System.out.print("请输入姓名: ");
        String name = scanner.nextLine();
        System.out.print("请输入年龄: ");
        int age = scanner.nextInt();
        System.out.print("请输入薪资: ");
        double salary = scanner.nextDouble();

        // 清除缓冲区
        scanner.nextLine();
        System.out.print("请输入城市: ");
        String city = scanner.nextLine();
        System.out.printf("员工信息: %s, %d岁, 薪资%.2f, 城市%s%n", name, age, salary, city);
scanner.close(); } }

 

常用方法总结

 
方法描述
next() 读取下一个字符串
nextLine() 读取下一行
nextInt() 读取下一个整数
nextDouble() 读取下一个双精度数
nextBoolean() 读取下一个布尔值
hasNext() 检查是否还有输入
hasNextInt() 检查下一个是否是整数
useDelimiter() 设置分隔符模式
close() 关闭扫描器

高级功能

1. 分隔符控制

public class DelimiterExample {
    public static void main(String[] args) {
        String data = "Apple,Banana;Cherry:Date";
        Scanner sc = new Scanner(data);
        
        // 设置自定义分隔符(正则表达式)
        sc.useDelimiter("[,;:]");
while (sc.hasNext()) { System.out.println(sc.next().trim()); } sc.close(); } }

2. 区域设置

import java.util.Locale;

public class LocaleExample {
    public static void main(String[] args) {
        String numbers = "1,234.56 7.890,12";
        
        // 使用美国区域设置
        Scanner usScanner = new Scanner(numbers);
        usScanner.useLocale(Locale.US);
        System.out.println("US: " + usScanner.nextDouble()); // 1234.56
        
        // 使用德国区域设置
        Scanner deScanner = new Scanner(numbers);
        deScanner.useLocale(Locale.GERMANY);
        deScanner.next(); // 跳过第一个数字
        System.out.println("DE: " + deScanner.nextDouble()); // 7890.12
    }
}

3. 模式匹配

import java.util.regex.Pattern;

public class PatternExample {
    public static void main(String[] args) {
        String text = "年龄:25 薪资:50000 部门:IT";
        Scanner sc = new Scanner(text);
        
        // 查找特定模式
        Pattern agePattern = Pattern.compile("年龄:(\\d+)");
        Pattern salaryPattern = Pattern.compile("薪资:(\\d+)");
        
        while (sc.hasNext()) {
            if (sc.hasNext(agePattern)) {
                String age = sc.findInLine(agePattern);
                System.out.println("找到年龄: " + age);
            } else if (sc.hasNext(salaryPattern)) {
                String salary = sc.findInLine(salaryPattern);
                System.out.println("找到薪资: " + salary);
            } else {
                sc.next(); // 跳过不匹配的内容
            }
        }
        sc.close();
    }
}

实用示例

1. 文件读取

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;

public class FileScannerExample {
    public static void main(String[] args) {
        try {
            Scanner fileScanner = new Scanner(new File("data.txt"));
            
            while (fileScanner.hasNextLine()) {
                String line = fileScanner.nextLine();
                System.out.println("行内容: " + line);
            }
            
            fileScanner.close();
        } catch (FileNotFoundException e) {
            System.out.println("文件未找到: " + e.getMessage());
        }
    }
}

2. CSV 解析

public class CSVScanner {
    public static void main(String[] args) {
        String csvData = "John,Doe,25,Developer\nJane,Smith,30,Manager";
        Scanner sc = new Scanner(csvData);
        
        while (sc.hasNextLine()) {
            String line = sc.nextLine();
            Scanner lineScanner = new Scanner(line);
            lineScanner.useDelimiter(",");
            
            String firstName = lineScanner.next();
            String lastName = lineScanner.next();
            int age = lineScanner.nextInt();
            String job = lineScanner.next();
            
            System.out.printf("%s %s, %d岁, %s%n", firstName, lastName, age, job);
            lineScanner.close();
        }
        sc.close();
    }
}

最佳实践

1. 资源管理

// 使用 try-with-resources 自动关闭
public class ResourceManagement {
    public static void main(String[] args) {
        try (Scanner scanner = new Scanner(System.in)) {
            System.out.print("请输入内容: ");
            String input = scanner.nextLine();
            System.out.println("你输入了: " + input);
        }
        // scanner 自动关闭
    }
}

2. 性能考虑

public class PerformanceTips {
    public static void main(String[] args) {
        // 对于大文件,设置合适的缓冲区
        try (Scanner sc = new Scanner(new File("large.txt"))) {
            sc.useDelimiter("\\R"); // 行分隔符
            
            while (sc.hasNext()) {
                String line = sc.next();
                // 处理每一行
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Scanner 类的优势:

  • 简单易用的输入解析。支持多种数据类型。灵活的分隔符控制。强大的正则表达式支持。

注意事项:

  • 记得关闭 Scanner 对象。注意输入缓冲区问题。大文件处理考虑性能。生产环境考虑更专业的解析库。

 
 
 

 

posted @ 2025-11-16 19:03  YukiRinLL  阅读(6)  评论(0)    收藏  举报