常用类型 (String StringBuffer StringBuilder 包装类 日期类 日历类 )+正则表达式 (三四五未完成)

一、String

  1.简介

JVM为了提高性能,减少内存的开销,在堆中定义了一个字符串常量,用于存储字符串对象。.被final修饰的,一旦初始化就不可以修改。

在JDK1.6及1.6之前运行时常量池(包括字符串常量池)存放在方法区

JDK1.7 时,将字符串常量池从方法区转移到堆中,运行时常量池剩下的东西还在堆中

  2.字符串常量池

当使用字面量给常量池赋值时,会在字符串常量池中找有没有这个字符串,如果有将该字符串的地址赋给变量,如果没有就在字符串常量池中创建;变量最终指向的时常量池中的地址

如果调用构造器new一个新的字符串,那么该对象一定在堆中创建空间,里面维护了value属性(底层源码)变量指向堆中创建的空间,然后在字符串常量池中寻找,如果有通过value指向常量池。如果没有在堆中创建该字符串,将地址赋值给变量。变量最终指向的时堆中的地址。

练习

    1:字面量与字面量比较时候

public class StringDemo01 {
    public static void main(String[] args) {
        String s1 = "abc";
        String s2 = "abc";
        System.out.println(s1 == s2);
    }
}

      运行结果:true 

     解析:  创建s字面量1时,现在字符串常量池中查找是否有这个字符串,没有则在字符串常量池中创建该字符串。创建s2时,先在字符串常量池中找,找到了,将该字符串的地址赋值给s2.

下图为JVM内存分配图

         2.两个字面量拼接 与字面量比较

public class StringDemo01 {
    public static void main(String[] args) {
        String s3 = "abc" +"d";
        String s4 = "abcd";
        System.out.println(s3 == s4);
    }
}

      运行结果:true

      解析      :当两个字面量做拼接时 编译器会进行优化操作,会在编译期间直接计算出s3的结果 s3 = "abcd"

所以结果为true.

     3.new 一个新对象与字面量比较

public class StringDemo01 {
    public static void main(String[] args) {
         String s5 = "d";
        String s6 = new String("d");
        System.out.println(s5 == s6);//false
    }
}

运行结果:false

      解析:   

s5是在字符串常量池中创建的,而s6会在堆中新开辟一个空间,然后去字符串常量池中找,找到了将该地址赋值给新开辟的空间,然后s6指向新开辟的空间。

     4.两个新创建的对象

public class StringDemo01 {
    public static void main(String[] args) {
        
        String s10=new String("abc");
        String s11=new String("abc");
        System.out.println(s10 == s11);//false
    }
}

      运行结果:false

     解析:    

当使用new关键字时,一定新开辟了一个空间,所以堆中开辟了两个空间,s5和s6分别指向各自的地址。

   5.字面量与变量拼接

public class StringDemo01 {
    public static void main(String[] args) {
         String s5 = "d";
        String s6 = "abc" + s5;
        String s8 ="abcd";
        System.out.println(s8 == s6);//false
    }
}

      运行结果  false

     解析:   

字面量与变量拼接时候,只能在运行期间进行运算,计算后的结果存放在堆中

 String s12="h";

String s13=new String("abc"+s12+"o" + "");

问:至少开辟了几个对象

5个

"h" 一个

"abc"  一个

"o"  一个

new s13一个

abc"+s12+"o"  拼接起来的一个

3.字符串的构造器

        1.String()

初始化一个新创建的空字符序列的字符串对象,实际上底层是char[] value = new char[0];

因为是空字符串,所以长度是0 

        2.String(String str)

      3.String(byte[ ] bytes)

使用默认编码集解吗byte数组,构建一个字符串对象,也就是将字节数组转成字符串

      4.String(byte[ ] bytes, String charseName )

使用指定编码集解码byte数组,构建一个字符串对象

     5.Striing(byte[ ] bytes, int offset,int length )

构建一个字符串对象,从字节数组的下标offset开始,length个元素

注意:调用该构造器,底层将byte[ ] 转成了char[ ]

     6.String(char[ ] value) 

将字符型数组转成字符串

4.String的常用方法

      1. length()

返回字符串的长度

public class StringMethod {
    public static void main(String[] args) {
        String str1 = "Hello World";
        int len1 = str1.length();
        System.out.println("Length of String: " + len1);
    }
}

运行结果

      2 indexOf(String str):

(1)indexOf(String str):

用于检测字符串第一个字母所在的下标位置 如果找不到就返回-1

public class StringMethod {
    public static void main(String[] args) {
        String str1 = "Hello World";
      
        int index1 = str1.indexOf("Wo");
        System.out.println("Index of 'Wo' in String: " + index1);
    }
}

运行结果

(2)indexOf(String str,int index):

从下标为index处开始寻找,找不到返回-1。

public class StringMethod {
    public static void main(String[] args) {
        String str1 = "Hello World";
        int index1 = str1.indexOf("Wo",7);
        System.out.println("Index of 'Wo' in String: " + index1);
    }
}

运行结果

应用:

找到第一个"o"的下标   找到第二个"o"的下标

public class StringMethod {
    public static void main(String[] args) {
        String str1 = "Hello World";
        int index = str1.indexOf("o");
        System.out.println("Index the first of 'o' in String: " + index);
        index = str1.indexOf("o",str1.indexOf("o")+1);
        System.out.println("Index the second of 'o' in String: " + index);
    }
}

运行结果

(3) lastIndexOf()

 ----lastIndexOf(String str)  传入字符串的第一个字符最后一次出现的位置


public class StringMethod {
    public static void main(String[] args) {
        int index = str1.lastIndexOf("orl");
        System.out.println("Index of the last 'orl' in String: " + index);
    }
}

运行结果

-----lastIndexOf(String str,int endIndex)

endIndex表示在当前位置结束也就是从头匹配到endIndex,查询str在字符串中出现的位置没有找到返回-1.

检索最后一个字符串chu'xia

public class String01 {
    public static void main(String[] args) {
        String str = "aabbccaabbcc";
        int index = str.lastIndexOf("cc");
        System.out.println("cc最后一次出现的位置:"+index);
        index = str.lastIndexOf("cc",3);
        System.out.println("cc截止到下标为3最后一次出现的位置:"+index);
    }
}
   
3.subString()

         用于截取子串

(1) String subString(int beginIndex)

public class StringMethod {
    public static void main(String[] args) {

        //截取子串
        String str = "Hello World";
        String subStr = str.substring(6);
        System.out.println("从下标为6的索引开始截取的子串为 " + subStr);
    }
}

运行结果

(2)String subString(int beginIndex, int endIndex)

从下标为beginIndex 开始截取到 下标为endIndex

public class StringMethod {
    public static void main(String[] args) {

        //截取子串
        String str = "Hello World";
        String subStr = str.substring(6,10);
        System.out.println("从下标为6的索引开始截取到下标为10的索引的子串为: " + subStr);
    }
}

运行结果

     4. trim();

        截掉字符串的前后空格


public class StringMethod {
    public static void main(String[] args) {
        String s2 = " haha ";
        System.out.println("长度:"+s2.length());
        String a = s2.trim();
        System.out.println("长度:"+a.length());
    }
}

运行结果

     5.charAt(int index) 

查找下标为index的字符 

public class StringMethod {
    public static void main(String[] args) {

        //charAt()方法
        String str = "Hello World";
        System.out.println("第一个元素也就是下标为0的元素为:  " + str.charAt(0));
       }
}

运行结果

      6.startsWith()

 boolean startsWith(String str) 判断是否以str开头

public class StringMethod {
    public static void main(String[] args) {


        String str = "Hello World";
        boolean b = str.startsWith("He");
        System.out.println("是否以He开头:"+b);
        b = str.startsWith("he");
        System.out.println("是否以he开头:"+b);
     }
}

运行结果

     7.endsWith() 

          boolean endsWith(String str) 判断是否以str结尾


public class StringMethod {
    public static void main(String[] args) {
        String str = "Hello World";
        boolean b = str.endsWith("ls");
        System.out.println("是否以ls结尾:"+b);
        b = str.endsWith("ld");
        System.out.println("是否以ld结尾:"+b);
    }
}

运行结果: 

       8.toUpperCase()

         将所有的小写转成大写

public class StringMethod {
    public static void main(String[] args) {


        String str = "Hello World";
        String str1 = str.toUpperCase();
        System.out.println(str1);
    }
}

运行结果

   
    9.toLowerCase()

    将所有的大写转成小写

public class StringMethod {
    public static void main(String[] args) {
        String str = "HELLO WORLD";
        String str1 = str.toLowerCase();
        System.out.println(str1);
    }
}

运行结果: 

      10. toArrayChar()

        将字符串转成字符数组

public class StringMethod {
    public static void main(String[] args) {

        String str = "HELLO WORLD";
        char[] c = str.toCharArray();
        System.out.println("字符数组:" + Arrays.toString(c));
    }
}

运行结果 

       11.valueOf()

         静态的,使用类名调用,将参数类型转成字符串

(1)static String valueOf(int value)  将int类型转成字符串

(2)static String valueOf(double d)   将double类型转成字符串

(3)static String valueOf(char[] ch)   将char数组转成字符串

(4)static String valueOf(Object obj )

public class StringMethod {
    public static void main(String[] args) {

        String num = String.valueOf(123);
        System.out.println("num: "+num);
        String price = String.valueOf("123.45");
        System.out.println("price "+price);
        char[] chars = {'a', 'b', 'c', 'd', 'e'};
        String ch = String.valueOf(chars);
        System.out.println("ch: "+ch);
     }
}

运行结果

 

     
     12. equals和==

 equals :用于比较的是两个对象的属性是否一样,String类已经将equals方法重写了

==:比较的是地址

public class StringMethod {
    public static void main(String[] args) {

        String s10 =new String("hello");
        String s11 =new String("hello");
        System.out.println("s10和s11的地址是否一样:"+(s10==s11));//false
        System.out.println("s10和s11的内容是否一样:"+(s10.equals(s11)));//true
    }
}

运行结果: 

二、StringBuffer和StringBuilder

由于String类型在创建时,会创建大量的对象,直接操作String类型会造成大量的对象在内存中出现,所以影响JVM的性能。

可以使用StringBuffer和StringBuilder来操作字符串的拼接、替换、截断等操作,这是因为StringBuilder和StringBuffer 是一个可变的字符串类型,拼接、替换、截断都不会产生新的对象

      1.常用构造器

(1)StringBuilder()

       构造一个不带任何字符的字符串生成器,其初始容量为16个字符

(2)StringBuilder(String str)

构造一个字符串生成器,其初始化为指定的字符串内容

      2.常用方法

1.append方法

将指定字符串追加到字符串之后

StringBuilder append(String str)

StringBuilder append(boolean b) 

      2.insert方法

将指定字符串插入到字符串的指定索引处

StringBuilder insert(iint index,String str)

      3.delete方法

StringBuilder delete(int start, int end)

从下标为start 开始截至到 下标为end进行删除但是不包含 下标为end的元素

       4.reverse方法

将字符串序列进行反转

StringBuilder reverse()

       5.toString方法

String toString()

将StringBuilder转成String类型

String、SgBuilder、StringBuffer三者的区别trin

  • StringBuilder和StringBuffer非常类似,都代表可变的字符序列而且方法也一样

  • java的字符串连接的过程是利用StringBuilder实现的

  • String: 不可变序列,效率低但是复用率高

  • StringBuilder 也是final修饰的类型,不能被继承

  • StringBuilder没有重写equals方法和toString()

  • StringBuilder是非线程安全的,并发处理,性能稍快

  • StringBuffer是线程安全的,同步处理,性能稍慢

三、包装类

由于java是面向对象的,但是八大基本数据类型没有这方面的特点,所以设计师为这八大基本数据类型设计了设计了八种符合这总特征的包装类型,称为包装类

基本数据类型包装类型
byteByte
shortShort
intInteger
longLong
floatFloat
doubleDouble
booleanBoolean
charCharacter

装箱: 基本数据类型转为包装类型

调用valueOf静态方法

调用包装类的构造器

拆箱:包装类型转为基本数据类型

调用xxxValue() 非静态方法进行拆箱

四、日期类

常用构造器:

Date(): 获取的是当前系统时间

Date(Long time):  获取距离纪元指定毫秒数的时间点

方法

long getTime(): 获取日期时间对象的毫秒数,距离纪元

void setTime(long time): 设置距离纪元的毫秒数

1. Date的toString方法转成的字符串,不是我们想要的格式,

因此需要使用SimpleDateFormat类型来自定义格式 ---format(Date date) : 格式化成我们需要的字符串形式.

2. 另外一个功能就是可以将一个字符串按照指定格式转成我们需要的日期类型 ---parse(String str): 解析转换。将字符串类型转换成日期类型.

五、日历类

获取日历对象

Calendar.getInstance()

六、正则表达式

正则表达式(Regular Expressions),是一个特殊的字符串,可以对普通的字符串进行校验检测等工作。正则表达式不是Java特有的,它是一套独立的语法,可以在java,c++,python等语言中使用。

正则表达式,最基本的使用场景是用来做校验,校验一个字符串是否满足预设的规则。在校验的基础 上,又添加了若干个其他的引用场景,例如: 批量的查找、替换、切割

1. 字符集合

[ ] : 表示匹配括号里的任意一个字符。
[abc] :匹配a 或者 b 或者 c
[^abc] : 匹配任意一个字符,只要不是a,或b,或c 就表示匹配成功
[a-z] : 表示匹配所有的小写字母的任意一个。
[A-Za-z] :表示匹配所有的小写字母和大写字母的任意一个。
[a-zA-Z0-9]:表示匹配所有的小写字母和大写字母和数字的任意一个。
[a-z&&[^bc]] :表示匹配所有的小写字母除了b和c, 只要匹配上就是true.

2.预定义字符集

\d: 用于匹配数字字符中的任意一个
\w:   匹配单词字符中的任意一个      单词字符就是a-zA-Z0-9_
\D:   用于匹配非数字字符中的任意一个
\W:   用于匹配非单词字符中的任意一个
\s:  用于匹配空格,制表符,退格符,换行符等中的任意一个
\S:  用于匹配非空格,制表符,退格符,换行符等中的任意一个
.  :  用于匹配任意一个字符

3. 数量词

X?   :匹配0个或1个
X*   :匹配0个或1个以上
x+   :匹配1个以上
X{n} :匹配n个
X{m,}:匹配m个以上
X{m,n}:匹配m~n个

4. 分组()

在正则表达式上可以使用()来进行对一些字符分组,并可以使用逻辑运算符|来进行选择匹配

reg:
String regex = "(135|137)[\\d]{8}"  //匹配手机号是135或者是137开头的

常用方法

1.  boolean matches(String regex)  : 判断this字符串是否匹配正则表达式regex

2.  String[ ] split(String regex) :  对this使用匹配上正则表达式的子串进行切分成字符串数组

3.  replaceAll( String regex,String replacement) :使用replacement替换掉所有符合正则表达式的子串。

1.boolean matches(String regex)

public class Test {
    public static void main(String[] args) {
        String str1 = "abc123";
        String regex ="[a-z]";
        System.out.println(str1.matches(regex)); 
    }
}

2. String[ ] split(String regex)

使用数字将字符串分搁成数组 (开头没有数字,结尾有 / 没有数字),结果都是将字符串分成3份

public Class Test{
   public static void main(String[] agrs){
      String str = "abc123bcd34ff3";
      String regex = "\\d+";
      String[] s = str.split(regex);
      System.out.println(Arrays.toString(s));
      System.out.println(s.length);

      str = "abc123bcd34ff";
      regex = "\\d+";
      String[] s2 = str.split(regex);
      System.out.println(Arrays.toString(s2));
      System.out.println(s2.length);
   }
}

开头有数字,将字符串分成4份

public Class Test{
   public static void main(String[] agrs){
       String str = "123abc123bcd34ff";
       String regex = "\\d+";
       String[] s2 = str.split(regex);
       System.out.println(Arrays.toString(s2));
       System.out.println(s2.length);
   }
}

3.  replaceAll( String regex,String replacement)

public class RepalceAllTest {
    public static void main(String[] args) {
        String str = "hello 1 world, hello 2 java, hello 3 c++";
        String regex = "\\d";
        String info = str.replaceAll(regex, "hi");
        System.out.println(info);
    }
}

七、Patter类和Matcher类

Pattern类

其实,Pattern这个类,才是真正来操作正则表达式的类,它位于java.util.regex包下。在String类中的提供的 matches 、split 、replace等方 法,其实都是对这个类中的某些方法的封装。

在我们调用String类中的提供的 matches 、split 、replace等方法时,底层就会创建一个Pattern对象。这样的做法效率是很低的。我们何不主动创建一个pattern,然后每次需要匹配就直接用它而不需要再次创建,大大提高了程序的效率。

split()

public class Test{
public static void main(String[] args)
   String regex = "[a-z]";
   Pattern pattern = Pattern.compile(regex);
   String str = "abcd";
   String str1 = pattern.pattern();
   System.out.println("正则表达式:"+str1);
   String[] arr =str1.split(str);
   System.out.println(Arrays.toString(arr));
   }
}

Pattern类只能提供一些简单的匹配操作,要想得到更强更便捷的正则表达式就要将Pattern和Matcher一起合作

使用方法:

因为该类的构造器是优化的

先获取模式 (Pattern) 对象,再获取匹配 (Matcher) 对象。常用方法matches()、lookingAt()、find()

matches()

public class MatcherTest {
    public static void main(String[] args) {
        String s = "abcdefg";
        String regex = "[a-z]+";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(s);
        boolean matches = matcher.matches();
        System.out.println("是否匹配成功"+matches);
    }
}

lookingAt()

1. 用于匹配普通字符串开头部分是否符合正则表达式

2. 内部含有一个类似于指针的操作,匹配成功后,指针指向了匹配成功的子串;

     匹配前位于普通字符串的前面

public class MatcherTest {
    public static void main(String[] args) {
        String s = "abcdefg";
        String regex = "[a-z]"
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(s);
        boolean result = matcher.lookingAt();
        System.out.println("是否普配成功"+result);
    }
}

find()

1. 用于匹配普通字符串里是否有符合正则表达式的子串,检索到字符串的最后  如果有返回true,没有返回false

 2. 该方法也有一个指针操作,当匹配成功后,指针移动

public class MatcherTest {
    public static void main(String[] args) {
        String s = "abcdefg";
        String regex = "[a-z]";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(s);
        boolean find =matcher.find();
        System.out.println("是否找到"+find);
    }
}

下面这些方法是基于上面的三个方法匹配成功后的

group()、groupCount()、reset()、start()、end()

 group() reset()  start()   end()

public class MatchesTest02 {
    public static void main(String[] args) {
        String regex = "\\d+";
        String str = "aaa12bbbb34ccc56";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(str);

        //找到了就存在group里面
        while(matcher.find()){
            String group =  matcher.group();
            System.out.println(group);
        }
        //这时候指针已经移动到最后 所以找不到
        boolean find = matcher.find();
        System.out.println("是否找到"+find);

        //调用reset() 方法将指针重置到最开始的位置
        matcher.reset();
        while(matcher.find()){
            String group =  matcher.group();
            System.out.println(group);
        }
        matcher.reset();
        int count = 1;
        while(matcher.find()){
            System.out.println("第"+count+"个开始位置:"+matcher.start()+
                    "结束位置"+matcher.end());
            count++;
        }
    }
}

groupCount()

public class GroupCountTset {
    public static void main(String[] args) {
        String regex = "(a(a))(b)";
        String str = "aaab";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(str);
        int count = matcher.groupCount();
        matcher.find();
        for(int i=0;i<=count;i++){
            System.out.println(matcher.group(i));
        }
    }
}

 groupCouont 计算的是小括号的个数

总共有三个小括号

group(0) : 将所有的小括号拆开

group(1): 拆第一个小括号

group(2):拆第二个小括号

group(3): 拆第三个小括号

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值