java中的StringTokenzier和Scanner类的使用方法和区别

正则表达式:
正则表达式是一个String对象的字符序列,该字符序列中具有特殊意义的字符,这些特殊字符称作正则表达式的元字符
常用正则表达式及其意义
在正则表达式中可以用方括号括起来若干字符来表示一个元字符,该元字符代表方括号中的任何一个字符,例如:
[abc];代表a、b、c、中的任何一个
由于"."代表任何一个字符,所以在正则表达式中如果想要使用普通意义的点字符,必须使用[.]或\56表示普通意义的点字符。
正则表达式中可以使用限定修饰符

带限定修饰符模式 意义
x? x出现0次或1次
x* x出现0次或多次
x+ x出现1次或多次
x{n} x恰好出现n次
x{n,} x恰好出现n次
x{n,m} x出现n次至m次
xy x的后缀是y
x y

基础代码:

import java.util.InputMismatchException;
import java.util.Scanner;
import java.util.*;

public class Test {
    public static void main(String[] args) {
    String regex="[a-zA-Z|0-9]+";
    Scanner scanner=new Scanner(System.in);
    String str=scanner.nextLine();
    if(str.matches(regex)){
        System.out.println(str+"是由英文字母、数字、下划线构成");
    }
    else
        System.out.println(str+"中有非法字符");


    }
}
class GetPrice {
    public static double givePriceSum(String cost) {
        Scanner scanner = new Scanner(cost);
        scanner.useDelimiter("[^0123456789.]+");
        double sum = 0;
        while (scanner.hasNext()) {
            try {
                double price = scanner.nextDouble();
                sum += price;

            } catch (InputMismatchException exp) {
                String t = scanner.next();
            }
        }
        return sum;
    }
}

字符串的替换
String对象调用public String replaceAll(String regex,String replacement)方法返回一个新的String对象,这个新的String对象的字符序列是把当前String对象的字符序列中所有和参数regex匹配的子字符序列,用参数replacement的字符序列替换后得到字符序列
String对象调用replaceAll()方法返回一个新的String对象,但不会改变当前String对象的字符序列。
字符序列的分解:
public String[] split(String regex),String对象调用该方法时,使用参数指定的正则表达式regex作为分隔标记分解出当前String对象的字符序列中的单词,并将分解出的单词存放在String数组中。
但需要注意的是split()方法认为分隔标记的左侧应该是单词,因此如果和当前String对象的字符序列的前缀和regex匹配,那么split方法分解出来的第一个单词是不包含任何字符的字符序列即“”。
StringTokenizer类
和split()方法不同的是,StringTokenizer对象不使用正则表达式作为分隔标记。
StringTokenizer(String s):为String对象s构造一个分析器,使用默认的分割标记,即空格符、换行符、回车符、tab符、进纸符作分隔标记。
StringTokenizer(String s,String delim)参数delim中的任意字符排列被作为分隔标记。
基础代码:

import java.util.InputMismatchException;
import java.util.Scanner;
import java.util.*;

public class Test {
    public static void main(String[] args) {
    String shoppingReceipt="牛奶:8.5,香蕉 3.6,酱油:2.8";
    PriceToken lookPriceMess=new PriceToken();
    System.out.println(shoppingReceipt);
    double sum=lookPriceMess.getPriceSum(shoppingReceipt);
    System.out.printf("购物总价格:%-7.2f",sum);
    int amount=lookPriceMess.getGoodsAmount(shoppingReceipt);
    double aver=lookPriceMess.getAverPrice(shoppingReceipt);
    System.out.printf("\n商品数目:%d,平均价格:%-7.2f",amount,aver);
    }
}

class PriceToken {
    public double getPriceSum(String shoppingReceipt) {
        String regex = "[^(0-9|.)]+";
        shoppingReceipt = shoppingReceipt.replaceAll(regex, "#");
        StringTokenizer fenxi = new StringTokenizer(shoppingReceipt, "#");
        double sum = 0;
        while (fenxi.hasMoreTokens()) {
            String item = fenxi.nextToken();
            double price = Double.parseDouble(item);
            sum += price;
        }
        return sum;
    }

    public double getAverPrice(String shoppingReceipt) {
        double priceSum = getPriceSum(shoppingReceipt);
        int goodsAmount = getGoodsAmount(shoppingReceipt);
        return priceSum / goodsAmount;
    }

    public int getGoodsAmount(String shoppingReceipt) {
        String regex = "[^(1-9|.)]+";
        shoppingReceipt = shoppingReceipt.replaceAll(regex, "#");
        StringTokenizer fenxi = new StringTokenizer(shoppingReceipt, "#");
        int amount = fenxi.countTokens();
        return amount;
    }
}

Scanner类:
Scannerd对象可以解析字符序列中的单词。
Scanner可以调用useDelimiter(正则表达式)。
将正则表达式作为分隔标记,如果不指定标记,则默认调用空白符。
Scanner对象调用next()方法以此返回被解析的字符序列中的单词,如果最后一个单词已被next()返回,Scannerd对象调用hasNext()将返回false否则返回true.
对于被解析的数字型单词,可以调用nextInt()nextDouble()方法将数字型单词转化为int或double数据返回。
如果单词不是数字型单词,Scannr对象调用nextInt()或nextDouble()方法将会发生inputMismatchException异常,在处理异常时可以调用next()方法返回非数字化单词。
基础代码:

import java.util.InputMismatchException;
import java.util.Scanner;
import java.util.*;

public class Test {
    public static void main(String[] args) {
        String cost = "市话76.8元,长途:167.38元,短信 12.68元";
        double priceSum = GetPrice.givePriceSum(cost);
        System.out.printf("%s\n总价:%.2f元\n", cost, priceSum);
        cost = "牛奶:8.5,香蕉 3.6元,酱油:2.8元";
        priceSum = GetPrice.givePriceSum(cost);
        System.out.printf("%s\n总价:%.2f元\n", cost, priceSum);
    }
}
class GetPrice {
    public static double givePriceSum(String cost) {
        Scanner scanner = new Scanner(cost);
        scanner.useDelimiter("[^0123456789.]+");
        double sum = 0;
        while (scanner.hasNext()) {
            try {
                double price = scanner.nextDouble();
                sum += price;

            } catch (InputMismatchException exp) {
                String t = scanner.next();
            }
        }
        return sum;
    }
}

StringTokenzier和Scanner的区别:
StringTokenzier类把分解出的全部单词都存放到StringTokenzier对象的实体中,,因此,StringTokenzier对象能较快速度获取单词,即StringTokenzier对象的实体占用较多的内存(即用空间换取内存)
Scanner类不把单词存放到Scanner对象实体中,而是仅仅存放怎样获取单词的分隔标记,即Scanner获取单词的速度相对较慢,但节省内存空间(即以速度换取空间
StringTokenzier对象一旦诞生就立刻可以知道单词的数目,既可以用countTokens()返回单词数目,而Scanner不提供这样的方法,因为Scanner类不把单词存放到Scanner对象的实体中,如果想要知道单词的数目,就必须一个一个去或取。

发布了73 篇原创文章 · 获赞 81 · 访问量 9998

猜你喜欢

转载自blog.csdn.net/qq_41910353/article/details/101631905
今日推荐