第13章 字符串

  1. 应当使用StringBuilder拼接字符串,而不是使用“+”号,虽然使用“+”时,编译器会自动调用StringBuilder处理,但是编译器的优化是有限的,如果你需要使用循环并用“+”拼接字符串,编译器会在每次循环都创建一个新的StringBuilder对象,效率较低;而若是自己先在循环体外新建了StringBuilder对象,然后在循环体内使用append方法拼接,就只会生成一个StringBuilder对象,而且显式地创建StringBuilder还可以预先为其指定大小,避免多次重新分配缓冲。所以如果要用循环拼接字符串,最好新建一个StringBuilder。
  2. StringBuilder对象的length方法返回的是字符的数量:
	public static void test01() {
	    // StringBuilder对象的length方法返回的是字符的数量
	    StringBuilder sb = new StringBuilder();
	    sb.append("[");
	    Random rand = new Random();
	    for (int i = 0; i < 10; i++) {
	        sb.append(rand.nextInt(10));
	        sb.append(", ");
	    }
	    sb.delete(sb.length() - 2, sb.length());
	    sb.append("]");
	    // output: [6, 9, 2, 3, 8, 5, 7, 1, 8, 7]  字符数:30
	    System.out.println(sb.toString() + "  字符数:" + sb.length());
	    sb.insert(29, "我");
	    // output: [6, 9, 2, 3, 8, 5, 7, 1, 8, 7我]  字符数:31
	    System.out.println(sb.toString() + "  字符数:" + sb.length());
	}
	public static void test02() {
		List<InfiniteRecursion> list = new ArrayList<>();
		for (int i = 0; i < 5; i++) {
		    list.add(new InfiniteRecursion());
		}
		/*
		ArrayList.toString()方法会遍历ArrayList中包含的所有对象,调用每个元素的toString()方法
		 */
		System.out.println(list);
	}
	
	static class InfiniteRecursion {
	    @Override
	    public String toString() {
	        /*
	        这样写会抛出异常:Exception in thread "main" java.lang.StackOverflowError
	        this是一个InfiniteRecursion对象,但是由于它和字符串相加,所以编译器会将this转型为
	        一个String,而这个转换依靠的正是this的toString()方法,所以会造成无限递归调用。
	         */
	        // return "InfiniteRecursion address" + this;
	        /*
	        想要使用toString()获取对象的内存地址,应该调用父类的toString()方法,
	        不应使用this。
	         */
	        return super.toString();
	    }
	}
  1. String类有许多方法,调用这些方法来改变字符串的内容时,都会返回一个新的String对象,同时,如果内容没有发生改变,就返回原对象的引用,可以节约储存空间和避免额外的开销。
  2. java的格式化输出主要有三种方法:
    ①System.out.printf( )
    ②System.out.format( )
    ③Formatter类
    前两种方式等价,后一种方式能提供更强大的功能:
	public static void test03() {
	    /*
	    Formatter语法格式:
	    %[argument_index$][flags][width][.precision]conversion
	    数据默认右对齐,使用"-"flag可以改变为左对齐;
	    width控制一个域的最小尺寸;
	    precision用于String时,表示打印字符的最大数量,
	    用于浮点数时,表示小数部分要显示的位数(默认为6),小数位数过多则四舍五入,过少则补0,
	    因为整数没有小数部分,所以不能用于整数;
	    conversion表示转换的类型:
	    d:整数(十进制) c:Unicode字符 b:Boolean值 s:String f:浮点数(十进制)
	    e:浮点数(科学计数) x:整数(十六进制) h:散列码(十六进制) %:字符"%"
	     */
	    int width1 = 12;
	    int width2 = 5;
	    int width3 = 10;
	    int precision1 = 15;
	    int precision2 = 2;
	    String format1 = "%-"+width1+"."+precision1+"s %"+width2+"d %"+width3+"."+precision2+"f\n";
	    Formatter f = new Formatter(System.out); // 传入参数,告诉formatter向哪里输出结果,这里输出到控制台。
	    f.format("%-12s %5s %10s\n", "Item", "Qty", "Price");
	    f.format("%-12s %5s %10s\n", "----", "---", "-----");
	    f.format("%-12.15s %5d %10.2f\n", "laowang", 50, 12.369);
	    // 也可用常量代替
	    f.format(format1, "laoli", 54, 12.3);
	    /* output:
	    Item           Qty      Price
	    ----           ---      -----
	    laowang         50      12.37
	    laoli           54      12.30
	     */
	}
  1. 调用String类的format( )静态方法,可以生成格式化的String对象,它接受上述format( )方法一样的参数,但返回一个String对象。
  2. 使用正则表达式的几种方式:
    ①利用String类的内建功能,String对象调用matches( )方法进行匹配:
System.out.println("911".matches("[+-]?\\d+")); // true

②使用Pattern类

    public static void test05() {
        String str = "Arline ate eight apples and one orange while Anita hadn't any";
        Pattern p = Pattern.compile("(?i)((^[aeiou])|(\\s+[aeiou]))\\w+?[aeiou]\\b");
        Matcher m = p.matcher(str);
        while (m.find()) {
            System.out.println(m.group());
        }
    }
    /* output:
    Arline
     ate
     one
     orange
     Anita
     */
  1. 使用匹配到的字符分割字符串,并返回字符串数组:
    public static void test06() {
        String str = "This!!Unusual use!!of exclamation!!points";
        System.out.println(Arrays.toString(Pattern.compile("!!").split(str))); // [This, Unusual use, of exclamation, points]
        // 还可以限制分割得到的字符串的数量:
        System.out.println(Arrays.toString(Pattern.compile("!!").split(str, 3))); // [This, Unusual use, of exclamation!!points]
    }
  1. 通过reset( )方法,可以将现有的Matcher对象应用于一个新的字符串:
    public static void test07() {
        String str1 = "fix the rug with bags";
        String str2 = "fix the rig with rags";
        Pattern p = Pattern.compile("[frb][aiu][gx]");
        Matcher m = p.matcher(str1);
        while (m.find()) {
            System.out.print(m.group() + " ");
        }
        System.out.println();
        m.reset(str2);
        while (m.find()) {
            System.out.print(m.group() + " ");
        }
    }
    /* output:
    fix rug bag 
    fix rig rag 
     */
  1. 默认情况下,Scanner根据空白字符对输入进行分词,但是你可以用正则表达式来指定自己所需的定界符:
    public static void test08() {
        String str = "11, 44, 67, 55 , 434, 79";
        // Scanner s = new Scanner(System.in); // 扫描控制台的输入
        Scanner s = new Scanner(str); // 扫描字符串str
        s.useDelimiter("\\s*,\\s*"); // 使用逗号(包括逗号前后任意的空白字符)作为定界符
        while (s.hasNextInt()) {
            System.out.print(s.nextInt() + " "); // 11 44 67 55 434 79 
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值