DAY05--字符串

字符串

版本历史:最早出的是String,然后是StringBuffer(线程安全),然后是StringBuilder(非线程安全)

不可变的String

Strings are constant(是字符串常量)

常用方法:

  • length
  • charAt(int index):获取指定下标的char
  • toLowerCase,toUpperCase:转小写,转大写
  • String.valueOf():有很多重载,能够返回表示参数内容的String

使用场景

  • 简单字符串操作

优缺点

  • 产生大量中间对象,速度慢
StringBuilder

a mutable sequence of characters(可变字符串),非线程安全

常用方法

  • append方法,里面放一个字符串就好,别再做字符串拼接
  • toString,将StringBuilder转成String

使用场景

  • 在为一个类重写toString方法时,如果字符串操作比较简单,则可以直接用“+”进行拼接,如果需要使用循环则是使用StringBuilder
  • 多次修改字符串且有速度要求时使用

优缺点

  • 速度快
  • 线程不安全

什么时候会调用toString?

  • 就是当this要转换成String的时候,如做字符串拼接的时候,“hello world"+this
  • 还有打印的时候
StringBuffer

A thread-safe, mutable sequence of characters(线程安全的可变字符串)

常用方法:

  • 也是append,toString方法

使用场景:

  • 多次修改字符串且需要线程安全时使用

优缺点

  • 线程安全
  • 速度较慢
Formatter

格式化打印可通过java.util.Formatter类来提供

构造器

  • new Formatter(System.out),往构造器传参表示把结果输出到哪里

格式化字符串

格式化说明符

%[arg_index$][flags][width][.precision]conversion
其中flags中“-”表示左对齐,默认右对齐,width是宽度,而precision是精度
而precision作用于字符串时表示显示的字符的最大数量,宽度设置这么大有什么用,我不显示,哈哈

常用方法:

  • formatter.format(),直接会打印结果

正则表达式

为什么需要正则?

  • 正则表达式可用来定义文本查找,替换的规则

正则表达式工具

  • matches():需要完全匹配才返回true
  • split():将字符串从正则表达式匹配的地方开始切割,默认是空格
  • replaceFirst():第一个匹配的地方替换
  • replace():仅支持字符和字符串替换(不支持正则)
  • replaceAll():基于正则的字符串替换
public class RegularExpress {
    public static void main(String[] args) {
        String s = "this is test";
        System.out.println(s.matches("this is test"));//最简单的匹配表达式,
        System.out.println(s.matches("this\\s+is\\s+test"));//匹配一个或多个空格
        String s1 = "afa1.51abc";
        System.out.println(s1.matches(".*\\d+\\.\\d+.*"));//判断里面是否有浮点数
    }
}


public class RegularExpress {
    public static void main(String[] args) {
        String s = "hello,world,!";
        System.out.println(Arrays.toString(s.split(",")));//[hello, world, !]
        System.out.println(s.replace(","," "));//hello world !
        String s1 = "1hello22world333!";
        System.out.println(s1.replaceFirst("\\d+"," "));//hello22world333!
        System.out.println(s1.replaceAll("\\d+"," "));// hello world !
    }
}
字符类

常见的几个字符类(口诀:问新疆 ?*+,点任何.)

  • . 表示匹配除换行符之外的任何单个字符,你要匹配字符,要用\S\s来
  • \s表示空白符(如空格,tab,换行,换页,回车),\S则是非空白符
  • \d是数字[0-9],\D则是非数字
  • \w是词字符[a-zA-Z0-9](即字母数字下划线),\W是非词字符
  • [],方括号表示“或”的意思,与|作用相同,在[]中,点号失去作用,变成普通的小数点了,|也变成普通的竖线了

修饰匹配次数的符号

  • ?表示零次或一次匹配前面的字符或表达式,如{0,1}

  • *表示零次或多次匹配前面的字符或表达式,如{0,}

  • +表示一次多次匹配前面的字符或表达式,如{1,}

  • {n}表示匹配正好匹配n次

  • {n,}表示匹配至少匹配n次

  • {n,m}表示匹配在n,m次之间

  • ? 发在匹配次数后面是指明是“懒惰模式”

  • -,中划线表示范围,如2-8

  • ^表示除什么外的

选择符和分组

  • 用|来表示分支
  • 用()来组织结构,来分组

匹配模式

  • 忽略大小写
  • 单行模式
  • 多行模式
逻辑操作符
  • XY 即Y在X后面
  • X|Y即X或Y
  • (X)即捕获组
边界匹配符

它是零宽的,故他是匹配位置,而非字符的

  • ^ 一行的起始,$一行的结束,\b表示词边界(即找这样一个位置,他前面的字符与后面的字符不全是\w,即换个要换个单词了,故称词边界),\B表示非词边界(则是要在同个单词内,只要是用字母数字下划线连在一起就是同个单词内)
量词

贪婪型(最大匹配模式)

贪婪型(最小匹配模式)

独占型(全部匹配模式)

原文链接:https://blog.csdn.net/renfufei/article/details/79029624

  • 使用圆括号来分割组
Pattern和Matcher

Pattern表示一个正则表达式的编译表示,要通过调用Pattern.compile(regx),生成一个Pattern对象

Matcher是对字符串进行操作的引擎,Pattern.matcher则是生成一个matcher对象

常用方法:

  • matcher对象的常用方法
    • find():相当于迭代器的hasNext方法
    • group():返回上次匹配的子字符串
    • start(),end():返回上次匹配的开始,结束+1的下标
public class RegularExpress {
    public static void main(String[] args) {
        Formatter formatter = new Formatter(System.out);
        Matcher m = Pattern.compile("\\w+").matcher("Evening is full of the light of planets");
        while (m.find()) {
            formatter.format("%-10.10s at the positions \t%s-%s\n",m.group(),m.start(),m.end()-1);
        }
    }
}
/* output */
Evening    at the positions 	0-6
is         at the positions 	8-9
full       at the positions 	11-14
of         at the positions 	16-17
the        at the positions 	19-21
light      at the positions 	23-27
of         at the positions 	29-30
planets    at the positions 	32-38

扫描输入Scanner

为什么需要Scanner?

  • 之前的扫描输入需要读取一行文本然后进行分割,转换类型,才能得到切确的类型,Scanner解决了这个问题:他可以直接得到切确的类型

构造器

  • new Scanner(),可以传入任何输入对象,如File,Reader
public class ScannerTest {
    public static void main(String[] args) {
        System.out.println("how old are you? what is your favorite double");
        System.out.println("(input:<age><double>");
        Scanner scanner = new Scanner(System.in);
        int age = scanner.nextInt();
        double favorite = scanner.nextDouble();
        System.out.println("in 5 years you will\t"+(age+5));
        System.out.println("you favorite double is\t"+favorite);
    }
}
/* output */
how old are you? what is your favorite double
input:<age><double>
22
1.3
in 5 years you will	27
you favorite double is	1.3

scanner的分界符

默认是空格,也可以可以设置成自定义的

public class ScannerDelimiter {
    public static void main(String[] args) {
        Scanner scanner = new Scanner("1,2, 3 ,  4  ,5");
        scanner.useDelimiter("\\s*,\\s*");
        while (scanner.hasNext()) {
            System.out.println(scanner.nextInt());
        }
    }
}
使用正则进行扫描
public class ScannerDelimiter {
    public static void main(String[] args) {
//模拟扫描录入文本
    Scanner s =new Scanner(
            "192.168.0.1@11/02/2020\n" +
            "192.168.0.2@11/02/2020\n\t" +
            "192.168.0.3@11/02/2020\n\t" +
            "192.168.0.4@11/02/2020\n\t" +
            "192.168.0.5@11/02/2020\n\t" );
    String pattern="(\\d+[.]\\d+[.]\\d+[.]\\d+)@(\\d{2}/\\d{2}/\\d{4})";
    while (s.hasNext(pattern)) {//没想到hasNext和next都要用上pattern
        s.next(pattern);
        MatchResult match = s.match();
        String ip=match.group(1);//用上了分组
        String time=match.group(2);
        System.out.println("ip: "+ip+"\ttime: "+time
                +"\t--positions:"+match.start()
                +"--"+(match.end()-1));
    	}
    }
}

在这里插入图片描述

注意

哪些放栈里面,哪些东西放堆里,方法区?哪些东西放对象池里面?哪些东西放常量池里?

  • 常量池是独立于栈和堆的内存内存空间,相同内容的在常量池只有一份
  • 基本数据类型,对象的引用都在栈里面
  • new出来的对象都是存储在堆中
  • 类的加载信息,常量池,静态域都是放在方法区
    • String是特殊的引用类型,直接用 =“ ”; 创建的数据都是放常量池,除非用new创建的就会另外申请
  • Byte,Short,Integer,Long,Character这5种整型的包装类只是在对应值小于等于127时才可使用对象池,超过127会自动申请空间创建对象,放在堆中,
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值