自学内容网 自学内容网

Java从零到1的开始-Day13

一、String

1.String介绍

1.概述:String 类代表字符串
2.特点:
  a.Java 程序中的所有字符串字面值(如 "abc" )都作为此类的实例(对象)实现
    凡是带双引号的都是String的对象
    String s = "abc"
      String是数据类型,是一个字符串类型
      s:对象名
      "abc":就是一个对象
         
  b.字符串是常量,它们的值在创建之后不能更改
          
  c.因为 String 对象是不可变的,所以可以共享
    String s = "abc"
    String s1 = "abc"

2.String的实现原理

1.String的实现原理:String的底层原本面貌是一个被final修饰的数组
  a.jdk8之前:String底层是一个被final修饰的char数组->private final char[] value;
  b.jdk8之后:String底层是一个被final修饰的byte数组->private final byte[] value;
      
2.为啥要从char数组变成byte数组呢?省内存
  一个char类型占内存2个字节
  一个byte类型占内存1个字节

String是常量的原因:因为底层的数组被final修饰了,一旦被final修饰,数组地址值直接锁死,不能更改

3.String的创建

1.String() -> 根据无参构造创建String对象(对象创建出来了,但是字符串没有内容)
2.String(String str) ->利用String字符串创建一个String对象
3.String(char[] chars)-> 利用char数组创建一个String对象
4.String(byte[] bytes)-> 利用byte数组创建一个String对象(通过使用平台的默认字符集解码指定的 byte 数组,构造一个新的 String)
                         平台:操作系统
                         我们的操作系统默认字符集:GBK
                             
                         一个汉字在GBK中:占2个字节
                         一个汉字在UTF-8中:占3个字节

                         注意:在idea中,编写的代码都是按照UTF-8进行编码的,因为idea在执行的过程中
                             会添加一个启动参数:-Dfile.encoding=UTF-8
                                 
5.简化:String 变量名 = ""                                 

public class Demo02String {
    public static void main(String[] args) {
        //1.String() -> 根据无参构造创建String对象(对象创建出来了,但是字符串没有内容)
        String s1 = new String();
        System.out.println("s1 = " + s1);
        //2.String(String str) ->利用String字符串创建一个String对象
        String s2 = new String("abc");
        System.out.println("s2 = " + s2);
        //3.String(char[] chars)-> 利用char数组创建一个String对象
        char[] chars = {'a', 'b', 'c'};
        String s3 = new String(chars);
        System.out.println("s3 = " + s3);

        /*
        4.String(byte[] bytes)-> 利用byte数组创建一个String对象(通过使用平台的默认字符集解码指定的 byte 数组,构造一个新的 String)
                         如果我们字节传递的是负数,会代表中文(中文对应的字节都是负数)

                         平台:操作系统
                         我们的操作系统默认字符集:GBK

                         一个汉字在GBK中:占2个字节
                         一个汉字在UTF-8中:占3个字节

                         注意:在idea中,编写的代码都是按照UTF-8进行编码的,因为idea在执行的过程中
                             会添加一个启动参数:-Dfile.encoding=UTF-8
         */

        byte[] bytes = {97,98,99};
        String s4 = new String(bytes);
        System.out.println("s4 = " + s4);

        System.out.println("==========================");
        byte[] bytes1 = {-27,-101,-67};
        String s5 = new String(bytes1);
        System.out.println("s5 = " + s5);
    }
}

 扩展构造:
  1.String(byte[] bytes, int offset, int length) -> 将字节数组的一部分转成String
           bytes:要转的数组
           offset:从数组的哪个索引开始转
           length:转多少个
  2.String(char[] value, int offset, int count)-> 将字符数组的一部分转成String
           value:要转的数组
           offset:从数组的哪个索引开始转
           count:转多少个    

public class Demo03String {
    public static void main(String[] args) {
        /*
            1.String(byte[] bytes, int offset, int length) -> 将字节数组的一部分转成String
              bytes:要转的数组
              offset:从数组的哪个索引开始转
              length:转多少个
         */
        byte[] bytes = {97,98,99,100,101,102};
        String s = new String(bytes, 2, 3);
        System.out.println("s = " + s);

        System.out.println("==============================");

        /*
            2.String(char[] value, int offset, int count)-> 将字符数组的一部分转成String
              value:要转的数组
              offset:从数组的哪个索引开始转
              count:转多少个
         */
        char[] chars = {'a', 'b', 'c', 'd', 'e', 'f'};
        String s1 = new String(chars, 2, 3);
        System.out.println("s1 = " + s1);
    }
}

4.String 面试题

public class Demo04String {
    public static void main(String[] args) {
        String s1 = "abc";
        String s2 = "abc";
        String s3 = new String("abc");
        System.out.println(s1==s2);//true
        System.out.println(s1==s3);//false
        System.out.println(s2==s3);//false
    }
}

1.问题: String s = new String("abc")  共有几个对象? -> 2个 -> abc,以及new对象
    
2.问题: String s = new String("abc")  共创建了几个对象?  1个或者2个    

5.字符串常见问题

public class Demo05String {
    public static void main(String[] args) {
        String s1 = "hello";
        String s2 = "world";
        String s3 = "helloworld";
        String s4 = "hello"+"world";
        String s5 = s1+s2;
        String s6 = s1+"world";
        System.out.println(s3==s4);//true
        System.out.println(s3==s5);//false
        System.out.println(s3==s6);//false
    }
}

二、String的方法

1.判断方法

1.boolean equals(Object obj) ->比较字符串内容
2.boolean equalsIgnoreCase(String s) -> 比较字符串内容,忽略大小写  -> 常见于验证码对比使用   

public class Demo01String {
    public static void main(String[] args) {
        String s1 = "abc";
        String s2 = new String("abc");
        boolean result01 = s1.equals(s2);
        System.out.println("result01 = " + result01);

        System.out.println("===========================");
        String s3 = "ABc";
        boolean result02 = s1.equalsIgnoreCase(s3);
        System.out.println("result02 = " + result02);

        System.out.println("===========================");
        //String s4 = "壹贰叁";
        //String s5 = "一二三";
        //System.out.println(s4.equalsIgnoreCase(s5));
    }
}

2.练习1

已知用户名和密码,请用程序实现模拟用户登录。总共给三次机会,登录成功与否,给出相应的提示

public class Demo02String {
    public static void main(String[] args) {
        //1.创建Scanner对象
        Scanner sc = new Scanner(System.in);
        //2.定义两个字符串,代表已经注册过的用户名和密码
        String username = "root";
        String password = "root";
        //3.循环录入3次用户名和密码,跟已知的username和password做比较
        for (int i = 0; i < 3; i++) {
            System.out.println("请输入用户名:");
            String name = sc.next();
            System.out.println("请输入密码:");
            String pwd = sc.next();
            if (name.equals(username) && pwd.equals(password)) {
                System.out.println("登录成功");
                break;//结束循环
            } else {
                if (i == 2) {
                    System.out.println("账号冻结");
                } else {
                    System.out.println("登录失败");
                }
            }
        }
    }
}

public class Demo03String {
 public static void main(String[] args) {
     String s = null;
     method(s);
 }

 /**
     * s是一个变量,我们如果用s去调用equals,如果s接收的是null
     * 那么就会出现空指针异常
  *
     * 所以,为了防止空指针异常 -> 我们应该将确定的字符串放equals前面
  *
  *
     * 解决方案2:Objects工具类
     * boolean equals(v1,v2) -> 可以比较字符串,但是可以防空指针
     * @param s
  */
 private static void method(String s) {
 /*    if ("abc".equals(s)){
         System.out.println("是abc");
     }else{
         System.out.println("不是abc");
     }*/

     if (Objects.equals("abc",s)){
         System.out.println("是abc");
     }else {
         System.out.println("不是abc");
     }

 }
}

3.获取功能

1.String concat(String str)  拼接字符串,返回一个新串
2.char charAt(int index) 根据索引获取对应的字符
3.int indexOf(String str) 根据指定的字符串获取对应的第一次出现的索引
4.String substring(int beginIndex) 从指定的索引位置开始截取字符串到最后,返回一个新串儿
5.String substring(int beginIndex,int endIndex)从beginIndex截取到endIndex,返回一个新串儿
                                               含头不含尾
6.int length() 获取字符串长度

public class Demo04String {
    public static void main(String[] args) {
        String s = "abcdefg";
        //1.String concat(String str)  拼接字符串,返回一个新串
        String newStr1 = s.concat("hahah");
        System.out.println("newStr1 = " + newStr1);
        //2.char charAt(int index) 根据索引获取对应的字符
        char data = s.charAt(2);
        System.out.println("data = " + data);
        //3.int indexOf(String str) 根据指定的字符串获取对应的第一次出现的索引
        System.out.println(s.indexOf("c"));
        //4.String substring(int beginIndex) 从指定的索引位置开始截取字符串到最后,返回一个新串儿
        System.out.println(s.substring(2));
        //5.String substring(int beginIndex,int endIndex)从beginIndex截取到endIndex,返回一个新串儿
        //含头不含尾
        System.out.println(s.substring(2,4));
        //6.int length() 获取字符串长度
        System.out.println(s.length());
    }
}

4.练习

遍历字符串

public class Demo05String {
    public static void main(String[] args) {
        String s = "abcdefg";
       for (int i = 0;i<s.length();i++){
           System.out.println(s.charAt(i));
       }
    }
}

     

5.转换功能

1.char[] toCharArray() -> 将字符串转成char数组
2.byte[] getBytes() -> 将字符串转成byte数组
3.String replace(CharSequence target, CharSequence replacement)->将target指定的字符串替换成replacement指定的串儿
                 String类是CharSequence接口的实现类
    
4.byte[] getBytes(String charsetName)->将字符串按照指定的编码规则去转成byte数组
                  charsetName:不区分大小写

public class Demo06String {
    public static void main(String[] args) throws UnsupportedEncodingException {
        String s = "abcdefg";
        //1.char[] toCharArray() -> 将字符串转成char数组
        char[] chars = s.toCharArray();
        /*
           println是一个方法,是PrintStream类中的一个方法
           System.out其实返回的对象就是PrintStream对象
           PrintStream中的print方法以及println方法
           有直接输出char数组的方法
         */
        System.out.println(chars);
        //2.byte[] getBytes() -> 将字符串转成byte数组
        byte[] bytes = "abcdefg".getBytes();
        System.out.println(Arrays.toString(bytes));
        byte[] bytes1 = "你".getBytes();
        System.out.println(Arrays.toString(bytes1));

        //3.String replace(CharSequence target, CharSequence replacement)->将target指定的字符串替换成replacement指定的串儿
        //String类是CharSequence接口的实现类
        String newStr = s.replace("a", "z");
        System.out.println("newStr = " + newStr);

        //4.byte[] getBytes(String charsetName)->将字符串按照指定的编码规则去转成byte数组
        //charsetName:不区分大小写
        byte[] bytes2 = "你".getBytes("GBK");
        System.out.println(Arrays.toString(bytes2));
    }
}

6.分割功能

1.String[] split(String regex) -> 按照指定规则(正则表达式)分割字符串,返回的是字符串数组

public class Demo08String {
    public static void main(String[] args) {
        /*
          1.String[] split(String regex) -> 按照指定规则(正则表达式)分割字符串,返回的是字符串数组
         */
        String s = "abc,java,txt";
        String[] split = s.split(",");
        /*
            增强for
            1.格式:
              for(元素类型 变量名 : 要遍历的集合名或者数组名){
                 变量名:代表每一个元素
              }

            2.快捷键:
              数组名或者集合名.for
         */
        for (String element : split) {
            System.out.println(element);
        }

        System.out.println("======================");

        /*
           split方法参数位置其实传递的是正则表达式
           1.所谓的正则表达式其实就是字符串的一种规则
           2.正则作用: 对字符串进行校验, 比如校验邮箱,手机号,用户名等

           .在正则表达式中代表的是任意字符
           需要转义:  \\.
         */

        String s1 = "java.txt";
        String[] split1 = s1.split("\\.");
        for (String element : split1) {
            System.out.println(element);
        }
    }
}

三、其他方法

boolean contains(CharSequence s)  -> 判断字符串中是否包含指定的串儿
boolean endsWith(String suffix)  -> 判断字符串是否以指定的串儿结尾
boolean startsWith(String prefix)  -> 判断字符串是否以指定的串儿开头
String toLowerCase()  -> 将大写字母转成小写
String toUpperCase() -> 将小写字母转成大写
String trim() -> 去掉字符串两端空格    

public class Demo09String {
    public static void main(String[] args) {
        String s = "abcdefg";
        //boolean contains(CharSequence s)  -> 判断字符串中是否包含指定的串儿
        System.out.println(s.contains("ab"));
        //boolean endsWith(String suffix)  -> 判断字符串是否以指定的串儿结尾
        System.out.println(s.endsWith("g"));
        //boolean startsWith(String prefix)  -> 判断字符串是否以指定的串儿开头
        System.out.println(s.startsWith("a"));
        //String toLowerCase()  -> 将大写字母转成小写
        System.out.println("SDFADS".toLowerCase());
        //String toUpperCase() -> 将小写字母转成大写
        System.out.println(s.toUpperCase());
        //String trim() -> 去掉字符串两端空格
        String s1 = " a  b c ";
        System.out.println(s1);
        System.out.println(s1.trim());
        System.out.println(s1.replace(" ",""));
    }
}

四、String新特性_文本块

预览的新特性文本块在Java 15中被最终确定下来,Java 15之后我们就可以放心使用该文本块了。

JDK 12引入了Raw String Literals特性,但在其发布之前就放弃了这个特性。这个JEP与引入多行字符串文字(文本块)在意义上是类似的。Java 13中引入了文本块(预览特性),这个新特性跟Kotlin中的文本块是类似的。

现实问题

在Java中,通常需要使用String类型表达HTML,XML,SQL或JSON等格式的字符串,在进行字符串赋值时需要进行转义和连接操作,然后才能编译该代码,这种表达方式难以阅读并且难以维护。

文本块就是指多行字符串,例如一段格式化后的XML、JSON等。而有了文本块以后,用户不需要转义,Java能自动搞定。因此,文本块将提高Java程序的可读性和可写性。

目标

  • 简化跨越多行的字符串,避免对换行等特殊字符进行转义,简化编写Java程序。

  • 增强Java程序中字符串的可读性。

举例

会被自动转义,如有一段以下字符串:

<html>
  <body>
      <p>HelloWorld</p>
  </body>
</html>

将其复制到Java的字符串中,会展示成以下内容:

"<html>\n" +
"    <body>\n" +
"        <p>Hello, 尚硅谷</p>\n" +
"    </body>\n" +
"</html>\n";

即被自动进行了转义,这样的字符串看起来不是很直观,在JDK 13中,就可以使用以下语法了:

"""
<html>
  <body>
      <p>Hello, world</p>
  </body>
</html>
""";

使用“”“作为文本块的开始符和结束符,在其中就可以放置多行的字符串,不需要进行任何转义。看起来就十分清爽了。

文本块是Java中的一种新形式,它可以用来表示任何字符串,并且提供更多的表现力和更少的复杂性。

(1)文本块由零个或多个字符组成,由开始和结束分隔符括起来。

  • 开始分隔符由三个双引号字符表示,后面可以跟零个或多个空格,最终以行终止符结束。

  • 文本块内容以开始分隔符的行终止符后的第一个字符开始。

  • 结束分隔符也由三个双引号字符表示,文本块内容以结束分隔符的第一个双引号之前的最后一个字符结束。

以下示例代码是错误格式的文本块:

String err1 = """""";//开始分隔符后没有行终止符,六个双引号最中间必须换行

String err2 = """  """;//开始分隔符后没有行终止符,六个双引号最中间必须换行

如果要表示空字符串需要以下示例代码表示:

String emp1 = "";//推荐
String emp2 = """
   """;//第二种需要两行,更麻烦了

(2)允许开发人员使用“\n”“\f”和“\r”来进行字符串的垂直格式化,使用“\b”“\t”进行水平格式化。如以下示例代码就是合法的。

String html = """
    <html>\n
      <body>\n
        <p>Hello, world</p>\n
      </body>\n
    </html>\n
    """;

(3)在文本块中自由使用双引号是合法的

String story = """
Elly said,"Maybe I was a bird in another life."

Noah said,"If you're a bird , I'm a bird."
 """;

五、StringBuilder类

1.StringBuilder的介绍

1.概述:和StringBuffer一样都是一个可变的字符序列(底层自带缓冲区,说白就是没有被final修饰的byte数组),此类提供一个与 StringBuffer 兼容的 API
2.作用:主要是为了拼接字符串
3.问题:拼接字符串我们可以直接用String拼接,那么为啥还要学StringBuilder呢?
  a.String每拼接一次,都会产生一个新的字符串对象,如果拼接次数多,会占用内存,而且拼接效率比较低
  b.StringBuilder底层自带一个缓冲区,拼接的字符串内容都会在这个缓冲区中保存,在拼接的过程中不会随意产生新的对象 
    
4.StringBuilder的特点:
  a.底层是一个没有被final修饰的数组(自带的缓冲区),没有被final修饰为了好扩容
  b.底层的缓冲区默认长度为16,拼接的字符串内容都会在这个缓冲区中存储
  c.如果超出了缓冲区长度,会自动扩容(创建一个新的数组,指定新长度,将老数组中的元素复制到新数组中去,然后将新数组地址值给老数组)
  d.扩容多少倍呢?  -> 默认是2倍+2
    如果一次性拼接存储的字符个数没有超过默认的扩容机制,就按照2倍+2去扩容
    如果一次性拼接存储的字符个数超过了默认的扩容机制,就按照实际拼接存储的字符个数来扩容  

2.StringBuilder的使用

1.构造:
  a.StringBuilder()
  b.StringBuilder(String str)    

public class Demo01StringBuilder {
    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder();
        System.out.println(sb);
        System.out.println("======================");

        StringBuilder sb1 = new StringBuilder("abc");
        System.out.println("sb1 = " + sb1);
    }
}

1.常用方法:
  a.StringBuilder append(任意类型) 字符串拼接,返回的是StringBuilder自己
  b.StringBuilder reverse() -> 将StringBuilder中的内容翻转,返回的还是StringBuilder自己
  c.String toString() -> 将StringBuilder转成String
                         因为用StringBuilder主要是拼接字符串快,省空间,拼接完之后,如果我们需要对拼接好的字符串内容进行操作,就需要调用String中的方法,所以我们需要将StringBuilder对象转成String对象

public class Demo02StringBuilder {
    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder();
        //StringBuilder sb1 = sb.append("张无忌");
        //System.out.println(sb);
        //System.out.println(sb1);
        //System.out.println(sb==sb1);
        sb.append("张无忌");

        /*
          链式调用
         */
        sb.append("赵敏").append("周芷若").append("涛哥").append("柳岩");

        /*
           System.out -> 返回的是PrintStream对象
           在这个基础上就可以继续调用PrintStream对象中的println方法
           也是链式调用
         */
        System.out.println(sb);


        sb.reverse();
        System.out.println(sb);

        String s = sb.toString();
        System.out.println(s.length());
    }
}

练习:键盘录入一个字符串,判断此字符串是否为"回文内容"  
    上海自来水来自海上
    山西运煤车煤运西山

    蝶恋花香花恋蝶
    鱼游水美水游鱼
    
    abcba

public class Demo03StringBuilder {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String data = sc.next();

        //1.创建StringBuilder对象
        StringBuilder sb = new StringBuilder();
        //2.拼接数据
        sb.append(data);
        //3.数据翻转
        sb.reverse();
        //4.将StringBuilder转成字符串
        String s = sb.toString();
        //5.判断翻转之前和翻转之后的内容是否相等
        if (data.equals(s)){
            System.out.println("是回文内容");
        }else{
            System.out.println("不是回文内容");
        }
    }
}

String,StringBuilder,StringBuffer区别:

1.相同点:都可以字符串拼接

2.不同点:

a.String:每拼接一次都会产生新的对象,占用内存,拼接效率低

b.StringBuilder:不会随意产生新对象,效率高,线程不安全

c.StringBuffer:不会随意产生新对象,效率低,线程安全

3.从拼接效率来说:

StringBuilder>StringBuffer>String


原文地址:https://blog.csdn.net/NJG1013/article/details/145260846

免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!