java中String类详解


前言


一、Sting类型简介

字符串定义

字符串类型:String。这个类不可以被继承(被final修饰),支持比较大小。
三种初始化方式:

public class Test04 {
    String str="hello";//1
    String str1=new String("hello");//2
    char[] chars={'a','j','d'};
    String str3=new String(chars);//3
}

java中没有说过字符串是以’\0’结尾的。
用string.length可以得到字符串长度。
注意:str指向的对象没有任何数据
str5代表不指向任何对象。

字符串空串和空指针

public class Test04 {
    public static void main(String[] args) {
        String str="";//1
        String str1=null;//2
        System.out.println(str.isEmpty());
        System.out.println(str1.isEmpty());
    }
}

在这里插入图片描述
对应未知的字符串,或是字符串传参,要记得判断是否为空或是长度是否为0.

	if(str==null){return 0}
	if(str.length==0){return 0}

字符串的等价比较

因为new的指向不同对象空间,存的地址不同,而后面是指向同一个“abc”,存的相同。使用 == 比较字符串是比较对象的地址, 而不是字符串的具体内容是否相同。equal是比较值是否相同。

public class Test04 {
    public static void main(String[] args) {
        String str=new String("abc");//1
        String str1=new String("abc");//2
        System.out.println(str==str1);
        String str2="bcd";
        String str3="bcd";
        System.out.println(str2==str3);

    }

}


二、String类各种方法

字符串的不可变性:所有对字符串的操作或修改都不是在原来值的基础上,而是new了一个新的对象。主要是它被private修饰。
要修改就要用到反射。(后面会讲到)

1.字符串比较

compareTo

比较大小:

 String str=new String("abcds");//1
        String str1=new String("ahc");//2
        System.out.println(str.compareTo(str1));

1<2返回负数;1>2返回正数;1=2返回0.

忽略大小写比较compareToIgnoreCase

相等为0

String str=new String("abcds");//1
        String str1=new String("aBCds");//2
        System.out.println(str.compareToIgnoreCase(str1));

2.字符串查找

1.charAt()

String str=new String("abcds");
        System.out.println(str.charAt(1));//b

2.indexof()

返回指定的字符第一次出现的位置

 String str=new String("abcds");
        System.out.println(str.indexOf("c"));//2
        
        System.out.println(str.indexOf("c",3));//-1.没找到,从3开始找
        
        System.out.println(str.indexOf("cds"));//2,查找字符串
        
        String str=new String("abcsss");
        System.out.println(str.lastIndexOf("s"));//数的是最后一个的S,从后往前走。
lastIndexof
 String str=new String("abcsss");
        System.out.println(str.lastIndexOf("s"));//数的是最后一个的S,从后往前走。//5

		 System.out.println(str.lastIndexOf("s",4));//从4坐标往前数。//4

3.将其他数据类型转为字符串(valueof)

1.整形等基本数据类型

int str2=222233;
        System.out.println(String.valueOf(str2));

2.类的对象

class Animal {
    int age;
    String name;
    int sex;

    public Animal(int age, String name, int sex) {
        this.age = age;
        this.name = name;
        this.sex = sex;
    }

    @Override
    public String toString() {
        return "Animal{" +
                "age=" + age +
                ", name='" + name + '\'' +
                ", sex=" + sex +
                '}';
    }
}
public class Test05{
    public static void main(String[] args) {
        Animal animal=new Animal(3,"红花",2);
        System.out.println(String.valueOf(animal));
    }
}

未重写toString输出:
在这里插入图片描述
重写后输出:因为valueof有继承tostring,所以可以调用重写的toString。
在这里插入图片描述

4.String类型转数组类型(toCharArray())

		String str=new String("AbCDddFSss");
        char[] ret=str.toCharArray();
        System.out.println(Arrays.toString(ret));//[A, b, C, D, d, d, F, S, s, s]

5.String大小写转换

变大写toUpperCase

		String str=new String("abcsss");
        String ret=str.toUpperCase();
        System.out.println(ret);//ABCSSS

变小写toLowerCase

String str=new String("AbCDddFSss");
        String ret=str.toLowerCase();
        System.out.println(ret);//abcdddfsss

6.字符串替换

replace

		String str=new String("AbssCsfdsDddFSss");
        String ret=str.replace("s","u");
        System.out.println(ret);//AbuuCufduDddFSuu

replaceFirst

替换出现的第一个字符段。

    String str=new String("AbssssCsfdsDddFSssCc");
        String ret=str.replaceFirst("ssC","uh");
        System.out.println(ret);//AbssuhsfdsDddFSssCc

replaceAll

所有的字段都用另一个字段来替换

 String str=new String("AbssssCsfdsDddFSssCc");
        String ret=str.replaceAll("ssC","uh");
        System.out.println(ret);//AbssuhsfdsDddFSuhc

7.字符串拆分(split)

根据指定的字符对字符串进行分割,分割之后的返回值就是数组。

 String str=new String("Absss sCs fds Ddd FSs sCc");
        String[] ret=str.split(" ");
        for (int i = 0; i < ret.length; i++) {
            System.out.print(ret[i]+",");//Absss,sCs,fds,Ddd,FSs,sCc,222233
        }
如果限定了只分两组,就不会均分。
        String[] ret=str.split(" ",2);
        for (int i = 0; i < ret.length; i++) {
            System.out.print(ret[i]+",");//Absss,sCs fds Ddd FSs sCc,
        }

注意:拆分时如果是有特殊字符要注意转义及其规则:
在这里插入图片描述
\的分和写

    String str=new String("Absss\\sCs\\fds\\Ddd\\FSs\\sCc");//两个斜杠才能表示1个
        System.out.println(str);//Absss\sCs\fds\Ddd\FSs\sCc
        String[] ret=str.split("\\\\");
        for (int i = 0; i < ret.length; i++) {
            System.out.print(ret[i]+",");//Absss,sCs,fds,Ddd,FSs,sCc,
        }

以|可以按多个分割符划分

   String str=new String("Absss&sCs=fds=Ddd&FS&sCc");
         String[] ret=str.split("&|=");
        for (int i = 0; i < ret.length; i++) {
            System.out.print(ret[i]+",");//Absss,sCs,fds,Ddd,FS,sCc,
        }

如果有多个分割符也可每一个分隔符拆分一次,进行多次拆分。

8.字符串的截取

1.可以截取指定位置开始的剩余字符串
2.截取指定位置到指定位置的字符串,左闭右开

substring()

 String str=new String("Absss&sCs=fds=Ddd&FS&sCc");
         String ret=str.substring(1);//截取指定位置开始的剩余字符串
        System.out.println(ret);//bsss&sCs=fds=Ddd&FS&sCc

         String ret=str.substring(1,6);//截取指定位置到指定位置的字符串,左闭右开
        System.out.println(ret);//bsss&//[1,6)

trim()

去除字符串左右空格

 String str=new String("                 Absss ss= fds  =DFS&s    Cc            ");
         String ret=str.trim();//去除左右空格
        System.out.println(ret);//Absss ss= fds  =DFS&s    Cc
        System.out.println(str);//                 Absss ss= fds  =DFS&s    Cc   

三、字符串的修改

String类型的字符串,不能够修改,每次增加拼接或则改动字符串都要重新new一个新的对象,因此很占内存,而且耗时。
而StringBuffer和StringBuilder是可以对字符串直接进行修改的。

StringBuilder与StringBuffer

StringBuilder与StringBuffer有很多都是相同的。这里相同用法的就只写其中之一了。在它们上对字符串进行改变就是对原来对象的改动,不会自动产生新的对象。

 public static void main(String[] args) {
        StringBuffer str=new StringBuffer("abcabcabcabc");
        str.insert(1,"jrhfbh");
        System.out.println(str);//ajrhfbhbcabcabcabc//将字符插入1

        str.delete(1,5);
        System.out.println(str);//abhbcabcabcabc//删除[1,5)的字符


        System.out.println(str.reverse());//cbacbacbacbhba//字符串逆置
        
		System.out.println(str.append("hdghxsh"));//cbacbacbacbhbahdghxsh//字符串增加
		
		String str2=str.toString();//将StringBuffer类型以String类型返回
    }

区别:
synchronized(同步锁)–>多线程下使用,为了线程的安全性,相当于一把锁。–》保证在同一时刻被修饰的代码块或方法只会有一个线程执行,以达到保证并发安全的效果。但是每次频繁的加锁和解锁很浪费资源。
StringBuffer的append被synchronized修饰,属于线程安全操作,但是StringBuilder没有。因此在不考虑线程安全的情况下,使用StringBuilder更好。

三种字符串类型相互转换

将String类型转变为StringBuilder,利用StringBuilder的构造方法或append()方法。

 StringBuilder str2=new StringBuilder("udwcwghd");
        str2.append("shbs");

将StringBuffer转变为String

String str2=str.toString();//将StringBuffer类型以String类型返回

四、String题

引用指向对象问题

指出下列程序运行的结果()good and gbc

public class Example{
    String str = new String("good");
    char[ ] ch = { 'a' , 'b' , 'c' };
    public static void main(String args[]){
        Example ex = new Example();
        ex.change(ex.str,ex.ch);
        System.out.print(ex.str + " and ");
        System.out.print(ex.ch);
    }
    public void change(String str,char ch[ ]){
        str = "test ok";
        ch[0] = 'g';
    }
}

在这里插入图片描述

字符串的不可变

下面代码将输出什么内容:()false

public class SystemUtil{
	public static boolean isAdmin(String userId){
		return userId.toLowerCase()=="admin";
	}
	public static void main(String[] args){
		System.out.println(isAdmin("Admin"));
	}
}

==号两边的是引用数据类型,那么比较的是"地址相不相同"。“admin”,存放在常量池当中,但是通过方法,userId.toLowerCase()。返回的是一个新的对象。通过字符串的不可变性,可知新的肯定和原来的地址不同。

大写转小写

给你一个字符串 s ,将该字符串中的大写字母转换成相同的小写字母,返回新的字符串。
示例 1:输入:s = "Hello"输出:“hello”
分析:
大写A:65
小写a: 97
相差32

public class  Test07{
    public static void main(String[] args) {
        String str1="FdhkAbsDFWSFceKLfk";
        char [] arr=str1.toCharArray();
        for (int i = 0; i < arr.length; i++) {
            char ch=arr[i];
            if(ch>='A'&&ch<'a'){
                ch+=32;
                arr[i]=ch;//直接赋值取代
            }

        }
        String str2=new String(arr);//初始化
        System.out.println(str2);//fdhkabsdfwsfceklfk

    }
}

这道用一个toLowerCase就能解决,但是极度不推荐。

找第一个只出现字符

该字符串全小写,找第一个只出现字符。
1.统计每个单词的次数
2.遍历字符串,看每个字符的次数。

 public static void main(String[] args) {
        String str="shbbhsjsl";
        int []count=new int[26];
        for (int i = 0; i < str.length(); i++) {
            char ch=str.charAt(i);
            count[ch-'a']++;
        }
        for (int i = 0; i < 26; i++) {
            if(count[i]==1)
            {
                System.out.println((char)(i+97));
                break;
            }
        }
        
    }

还有更优法,用哈希表,以后会写到。与次数,频率相关的都能够用哈希表最好。

计算字符串最后一个单词的长度

每个单词以空格隔开。

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

        while (sc.hasNextLine()){
            String str=sc.nextLine();
            int index=str.lastIndexOf(" ");//最后一个空格为已知元素,可以为此求下标。
            String tmp=str.substring(index+1);//利用下标直接截取最后一个单词
            System.out.println(tmp);
        }
    }

回文串

如果将所有大写字符转换为小写字符,并移除所有非字母非数字字符之后,短语正反读一样为回文串(只有字母和数字)。
Character.isLetter(char ch)//判断是否是字符
Character.isDigit(char ch)//判断是否是数字

import java.util.Scanner;
class Solution{
    public boolean isPalindrome(String s){
        s=s.toLowerCase();
        int left=0;
        int right=s.length()-1;
        while(left<right){
            while(left<right&&!isVaildChar(s.charAt(left))){
                left++;
            }
            while (left<right&&isVaildChar(s.charAt(right))){
                right--;
            }
            if(s.charAt(left)!=s.charAt(right)){
                return false;
            }
            else{
                left++;
                right++;
            }
        }
        return true;
    }
    private boolean isVaildChar(char ch){
        if(Character.isDigit(ch)||Character.isLetter(ch)){
            return true;
        }
        else{
            return false;
        }
    }
}

总结

1.笔试时除非时间非常紧张,没有时间思考可以直接调用库方法完成,否则就自己正常写。
2.在面试时发现一个库方法就能解决,往往不能用库方法。
因为直接调用库方法就能解决体现不出自己的逻辑。
可以借用库方法,但不能完成靠库方法。
面试,手写代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值