用好java中的String类,这些OJ题你还怕吗?

简介: 用好java中的String类,这些OJ题你还怕吗?

提到oj刷题,可能很多人的第一反映就是头疼😂。但没关系今天我们就要介绍String类(这里给帮助我们实现了很多方法、我们就不用再造轮子了)它极大的提升我们刷题的效率,一起来看看吧😁

一、String类常用方法

引用类型的比较

我们知道在Java中两个引用遍历是不能用" == "号来比较的,而String类重写了父类objects的equals方法, 实现了引用类型的比较

🌰栗子

import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        String str1 = "hello world";
        String str2 = "hello world";
        String str3 = "hello xiao_yu_er";
        // equals方法返回值是boolean类型,相等返回true,不等返回false
        System.out.println(str1.equals(str2)); // true
        System.out.println(str1.equals(str3)); // false
    }
}

除了equals,String还为我们提供了一些其他的字符串比较方法

🍑compareTo方法:按照字典序进行比较


📝与equals不同的是,equals返回的是boolean类型,而compareTo返回的是int类型。具体比较方式:


1. 先按照字典次序大小比较,如果出现不等的字符,直接返回这两个字符的大小差值

2. 如果前k个字符相等(k为两个字符长度最小值),返回值两个字符串长度差值


🌰栗子

import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        String str1 = "hello a";
        String str2 = "hello z";
        String str3 = "hello anna";
        // 返回类型是int,前几个字符都相同,最后一个不同——返回'a'和'z'字符的Ascii码的差值
        System.out.println(str1.compareTo(str2));    // -25
        // str1所有的字符和str3都相同,但str3多了几个不同的字符,返回值str1和str3两个字符串长度差值
        System.out.println(str1.compareTo(str3));   // -3
    }
}

🍑 compareToIgnoreCase:与compareTo方式相同,但是忽略大小写比较


字符串查找方法

7371053e49642b304e63cc7f32e8afa.png

🌰栗子

import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        String str1 = "hello world!";
        char ch = str1.charAt(0); // 获取0下标的字符
        System.out.println("该字符串中0下标的字符为:" + ch);
        int index1 = str1.indexOf("l"); // 记录字符串”l“在str1中第一次出现的位置,从前往后找,没有返回-1
        System.out.println("从前往后找,字符串”l“第一次出现的位置是:" + index1);
        int index2 = str1.lastIndexOf("l"); // 从后往前找,返回“l”第一次出现的位置,没有返回-1
        System.out.println("从后往前找,字符串“l”第一次出现的位置是:" + index2);
    }
}

ded57e202716424fb2d42155f0c5d573.png

字符串与数组、数字之间的转换

方法介绍都在代码中:

import java.util.Locale;
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        // 数字和字符串之间的转换
        String str1 = String.valueOf(1234); // 将数字1234转换成字符串"1234"
        double date1 = Double.parseDouble("76.2"); // 将字符串"76.2"转换成double类型的数字:76.2
        System.out.println(str1);
        System.out.println(date1);
        // 大小写转换
        String s1 = "XIAO YU ER";
        String s2 = "student";
        String s3 = s1.toLowerCase(); // 大写转小写
        System.out.println("大写转小写的转换结果是:" + s3);
        System.out.println("小写转大写的转换结果是:" + s2.toUpperCase()); // 小写转大写
        // 字符串和字符数组之间的转换
        String str2 = "hello word";
        char[] ch1 = str2.toCharArray(); // 字符串转字符数组
        for (char tmp:
             ch1) {
            System.out.print(tmp + " ");
        }
        System.out.println("======我是分割线=======");
        char[] ch2 = new char[]{'a','b', 'c', 'd', 'e'};
        String str3 = new String(ch2); // 字符数组转字符串
        System.out.println("字符数组转字符串的转换结果是:" + str3);
    }

4e03290d31194b4ca24ce7978970dad0.png

字符串替换

🍑使用一个指定的新的字符串替换掉已有的字符串数据,可用的方法如下

4b9bb27544e7f8fc550141a96baf9f1.png

🌰栗子

public class String_method_Test {
    public static void main(String[] args) {
        String str1 = "hello world!";
        System.out.println("替换全部的”l“后的结果是:" + str1.replaceAll("l", "*"));
        System.out.println("替换掉第一个”l“后的结果是:" + str1.replaceFirst("l", "&"));
    }
}

3b028e384c9e405aa3c3ae09bff65b2f.png

🔔注意事项: 由于字符串是不可变对象, 替换不修改当前字符串, 而是产生一个新的字符串

 

字符串的拆分

🍑可以将一个完整的字符串按照指定的分隔符划分为若干个子字符串

12140baf8ca2a90e068b2b4bc42accd.png

🌰栗子

public class String_method_Test {
    public static void main(String[] args) {
        String str1 = "hello xiao yu";
        String[] s1 = str1.split(" "); // 以空格,来进行全部拆分
        for (String tmp :
                s1) {
            System.out.println(tmp);
        }
        System.out.println("=====我是分割线======");
        String[] s2 = str1.split(" ", 2); // 按空格,拆分为两组
        for (int i = 0; i < s2.length; ++i) {
            System.out.println(s2[i]);
        }
    }
}

01a071cc29b948f2a37e653f3377a717.png

📝 拆分是特别常用的操作. 一定要重点掌握. 另外有些特殊字符作为分割符可能无法正确切分, 需要加上转义.


🌰栗子: 拆分IP地址

public class String_method_Test {
    public static void main(String[] args) {
        String str1 = "127.0.0.1";
        String[] s = str1.split("\\."); // 注意一定要加上转义字符
        for (int i = 0; i < s.length; ++i) {
            System.out.println(s[i]);
        }
        System.out.println("====我是分割线====");
        String str2 = "name=小鱼儿&age=19";
        String[] s2 = str2.split("&");
        // 多次拆分
        for (int i = 0; i < s2.length; ++i) {
            String[] tmp = s2[i].split("=");
            for (int j = 0; j < tmp.length; ++j) {
                System.out.println(tmp[j]);
            }
        }
    }
}

d1578c059c5640a882a002f44bbcbb7d.png

🔔注意事项:

1. 字符"|","*","+"都得加上转义字符,前面加上 "\\" .
2. 而如果是 "\" ,那么就得写成 "\\\\" .
3. 如果一个字符串中有多个分隔符,可以用"|"作为连字符


字符串截取

从一个完整的字符串之中截取部分内容:

a4ece6f923693ea4eda120bb6ca57b7.png🌰栗子

public class String_method_Test {
    public static void main(String[] args) {
        String str1 = "hello xiaoyu";
        // 从指定索引截取到结尾
        String s1 = str1.substring(6);
        System.out.println(s1);
        // 截取部分内容
        String s2 = str1.substring(6, 10);
        System.out.println(s2);
    }
}

a1fa599f6b724a43b1bc511397c9bef2.png

🔔注意事项:

1. 索引从0开始

2. 注意前闭后开区间的写法, substring(0, 5) 表示包含 0 号下标的字符, 不包含 5 号下标

 

其他一些操作方法

image.png

trim 会去掉字符串开头和结尾的空白字符(空格, 换行, 制表符等)

 

二、OJ实战演练

🌻字符串中的第一个唯一字符

45c688a5a56844fea045049292459e56.png

代码

class Solution {
    public int firstUniqChar(String s) {
        char[] str = s.toCharArray();
        int[] h = new int[26]; // 用一个数组来记录下来字符串中每个字符出现的次数
        for (int i = 0; i < str.length; ++i) {
            h[str[i] - 'a']++;
        }
        // 然后接着遍历该字符串,如果找到了一个只出现一次的字符,之间返回它的索引
        for (int i = 0; i < str.length; ++i) {
            if (h[str[i] - 'a'] == 1) return i;
        }
        return -1; // 如果代码能走到这里,说明在字符串s中没找到只出现一次的字符
    }
}

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

d1ae74ef33e84a208146639ead759f35.png

代码

import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()) {
            String str = sc.nextLine();
//             int ret = str.length() - str.lastIndexOf(" ") - 1; // 思路1:String类中的字符串查找方法
//             System.out.println(ret);
//             int index = -1;
//             for (int i = str.length() - 1; i >= 0; --i) {   // 思路2:从后往前遍历
//                 if (str.charAt(i) == ' ') {
//                     index = i;
//                     break;
//                 }
//             }
//             System.out.println(str.length() - 1 - index);
            String[] s = str.split(" ");                    // 思路3:String类中的字符串截取
            System.out.println(s[s.length - 1].length());
        }
    }
}

🌻验证回文串

 dfce7aa9aa8746f5b8e16e255a591df8.png

代码(思路都再代码中)

class Solution {
    // 判断当前字符是否为字母或数字字符
    public boolean charge(char ch) {
        if ( (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9') ) return true;
        else return false;
    }
    public boolean isPalindrome(String s) {
        if (s == null) return true;
        String str1 = s.toLowerCase();  // 把字符串都转成小写形式,便于处理(题目说可以忽略大小写)
        char[] chs = str1.toCharArray(); // 将字符串转换为字符数组,因为字符串不便于对单个字符操作
        StringBuilder tmp = new StringBuilder("");
        // 通过append方法将str字符数组添加到tmp2中,同时只添加了字符和数字字符
        for (int i = 0; i < chs.length; ++i) {
            if (charge(chs[i])) {  // 只要当前字符是数字或字母才进行添加,这样就保证我们tmp字符串中格式的统一
                tmp.append(chs[i]);
            }
        }
        // 程序到了这一步,此时我们的字符串tmp都是小写的字母或数字,没有其他的字符(这时候再反转判断就符合题目要求了)
        String before = tmp.toString(); // 保留反转前的字符串
        tmp.reverse();  // 字符串反转
        String after = tmp.toString();  // 这是反转之后的字符串
        if (after.equals(before)) return true;
        else return false;
    }
}

📝对String和StringBuilder的一些说明:

String和StringBuilder最大的区别在于String的内容无法修改,而StringBuilder的内容可以修改。频繁修改字符串的情况考虑使用StringBuilder。

🔔注意:String和StringBuilder类不能直接转换。如果要想互相转换,可以采用如下原则

一、String变为StringBuilder: 利用StringBuilder的构造方法(StringBuilder sb1 = new StringBuilder("hello这里面就放的是String类型的");)或append()方法

二、StringBuilder变为String: 调用toString()方法


💖上面的代码中我们用到了reverse这个字符串反转方法,但如果在面试的时候面试官不让我们用reverse怎么办呢? 那么我们就用双指针的思想自己来自己实现反转

1.class Solution {
    // 判断当前字符是否为字母或数字字符,这样的字符才合法
    public boolean charge(char ch) {
        if ( (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9') ) return true;
        else return false;
    }
    public boolean isPalindrome(String s) {
        if (s == null) return true;
        String str1 = s.toLowerCase();  // 把字符串都转成小写形式,便于处理(题目说可以忽略大小写)
        char[] chs = str1.toCharArray();
        int left = 0, right = str1.length() - 1;
        while (left < right) {
            // 通过两个while,让左右指针分别指向字符串两侧的合法字符上
            // 1. 从左侧找到一个有效的字符
            while (left < right && !charge(chs[left])) { // 注意这里的left<right的条件,如果字符串中没有一个是合法的字符,总不能一直加吧!
                ++left;
            }
            // 2. 从右侧找到一个有效的字符
            while (left < right && !charge(chs[right])) {
                --right;
            }
            if (chs[left] != chs[right]) return false;
            else {
                ++left; // 不要忘记更新,要不然会陷入死循环
                --right;
            }
        }
        return true;
    }
}


相关文章
|
7天前
|
存储 JavaScript Java
Java 中的 String Pool 简介
本文介绍了 Java 中 String 对象及其存储机制 String Pool 的基本概念,包括字符串引用、构造方法中的内存分配、字符串文字与对象的区别、手工引用、垃圾清理、性能优化,以及 Java 9 中的压缩字符串特性。文章详细解析了 String 对象的初始化、内存使用及优化方法,帮助开发者更好地理解和使用 Java 中的字符串。
Java 中的 String Pool 简介
|
13天前
|
缓存 安全 Java
java 为什么 String 在 java 中是不可变的?
本文探讨了Java中String为何设计为不可变类型,从字符串池的高效利用、哈希码缓存、支持其他对象的安全使用、增强安全性以及线程安全等方面阐述了不可变性的优势。文中还通过具体代码示例解释了这些优点的实际应用。
java 为什么 String 在 java 中是不可变的?
|
24天前
|
JSON Java 关系型数据库
Java更新数据库报错:Data truncation: Cannot create a JSON value from a string with CHARACTER SET 'binary'.
在Java中,使用mybatis-plus更新实体类对象到mysql,其中一个字段对应数据库中json数据类型,更新时报错:Data truncation: Cannot create a JSON value from a string with CHARACTER SET 'binary'.
37 4
Java更新数据库报错:Data truncation: Cannot create a JSON value from a string with CHARACTER SET 'binary'.
|
7天前
|
存储 Java
Java 11 的String是如何优化存储的?
本文介绍了Java中字符串存储优化的原理和实现。通过判断字符串是否全为拉丁字符,使用`byte`代替`char`存储,以节省空间。具体实现涉及`compress`和`toBytes`方法,前者用于尝试压缩字符串,后者则按常规方式存储。代码示例展示了如何根据配置决定使用哪种存储方式。
|
23天前
|
存储 缓存 安全
java 中操作字符串都有哪些类,它们之间有什么区别
Java中操作字符串的类主要有String、StringBuilder和StringBuffer。String是不可变的,每次操作都会生成新对象;StringBuilder和StringBuffer都是可变的,但StringBuilder是非线程安全的,而StringBuffer是线程安全的,因此性能略低。
42 8
|
23天前
|
Java
在Java中如何将基本数据类型转换为String
在Java中,可使用多种方法将基本数据类型(如int、char等)转换为String:1. 使用String.valueOf()方法;2. 利用+运算符与空字符串连接;3. 对于数字类型,也可使用Integer.toString()等特定类型的方法。这些方法简单高效,适用于不同场景。
47 7
|
20天前
|
存储 编译器 C语言
【c++丨STL】string类的使用
本文介绍了C++中`string`类的基本概念及其主要接口。`string`类在C++标准库中扮演着重要角色,它提供了比C语言中字符串处理函数更丰富、安全和便捷的功能。文章详细讲解了`string`类的构造函数、赋值运算符、容量管理接口、元素访问及遍历方法、字符串修改操作、字符串运算接口、常量成员和非成员函数等内容。通过实例演示了如何使用这些接口进行字符串的创建、修改、查找和比较等操作,帮助读者更好地理解和掌握`string`类的应用。
29 2
|
23天前
|
Java 开发者
在 Java 中,一个类可以实现多个接口吗?
这是 Java 面向对象编程的一个重要特性,它提供了极大的灵活性和扩展性。
44 1
|
1月前
|
安全 Java
Java多线程集合类
本文介绍了Java中线程安全的问题及解决方案。通过示例代码展示了使用`CopyOnWriteArrayList`、`CopyOnWriteArraySet`和`ConcurrentHashMap`来解决多线程环境下集合操作的线程安全问题。这些类通过不同的机制确保了线程安全,提高了并发性能。
|
1月前
|
存储 Java 程序员
Java基础的灵魂——Object类方法详解(社招面试不踩坑)
本文介绍了Java中`Object`类的几个重要方法,包括`toString`、`equals`、`hashCode`、`finalize`、`clone`、`getClass`、`notify`和`wait`。这些方法是面试中的常考点,掌握它们有助于理解Java对象的行为和实现多线程编程。作者通过具体示例和应用场景,详细解析了每个方法的作用和重写技巧,帮助读者更好地应对面试和技术开发。
105 4