字符串
通用的理论:
对于非基本类型(对象类型|引用类型)
只定义,不new(实例化):默认值都是Null
new实例化:Xxx xx = new Xxx();
xx值:不是null
xx内部的值都是数据类型的默认值
String s3 = new String(); s3 : ""
常用的String方法
以下是一些使用常用的String方法的示例代码:
String str = "Hello, World!";
// 使用length()方法获取字符串的长度
int length = str.length();
System.out.println("字符串的长度为:" + length);
// 使用charAt()方法获取指定索引位置的字符
char ch = str.charAt(7);
System.out.println("索引位置为7的字符为:" + ch);
// 使用substring()方法获取子字符串
String subStr = str.substring(7, 12);
System.out.println("从索引位置7到12的子字符串为:" + subStr);
// 使用concat()方法将字符串连接到末尾
String newStr = str.concat(" Welcome!");
System.out.println("连接后的字符串为:" + newStr);
// 使用toUpperCase()方法将字符串转换为大写
String upperCaseStr = str.toUpperCase();
System.out.println("转换为大写后的字符串为:" + upperCaseStr);
// 使用toLowerCase()方法将字符串转换为小写
String lowerCaseStr = str.toLowerCase();
System.out.println("转换为小写后的字符串为:" + lowerCaseStr);
// 使用trim()方法去除字符串两端的空格
String trimmedStr = " Hello, World! ".trim();
System.out.println("去除空格后的字符串为:" + trimmedStr);
// 使用startsWith()方法判断字符串是否以指定前缀开头
boolean startsWithHello = str.startsWith("Hello");
System.out.println("字符串是否以Hello开头:" + startsWithHello);
// 使用endsWith()方法判断字符串是否以指定后缀结尾
boolean endsWithWorld = str.endsWith("World!");
System.out.println("字符串是否以World!结尾:" + endsWithWorld);
// 使用indexOf()方法获取指定字符串第一次出现的索引位置
int indexOfComma = str.indexOf(",");
System.out.println("逗号第一次出现的索引位置为:" + indexOfComma);
// 使用lastIndexOf()方法获取指定字符串最后一次出现的索引位置
int lastIndexOfSpace = str.lastIndexOf(" ");
System.out.println("空格最后一次出现的索引位置为:" + lastIndexOfSpace);
// 使用replace()方法将指定字符替换为新的字符
String replacedStr = str.replace("o", "e");
System.out.println("将字符o替换为e后的字符串为:" + replacedStr);
// 使用split()方法根据指定正则表达式拆分字符串为字符串数组
String[] splitStr = str.split(",");
System.out.println("拆分后的字符串数组为:");
for (String s : splitStr) {
System.out.println(s);
}
// 使用equals()方法判断字符串是否与指定对象相等
boolean isEqual = str.equals("Hello, World!");
System.out.println("字符串是否与指定对象相等:" + isEqual);
// 使用compareTo()方法按字典顺序比较两个字符串
int compareResult = str.compareTo("Hello");
System.out.println("字符串与Hello比较的结果为:" + compareResult);
字符串常量池
字符串常量池是Java中的一个特殊的内存区域,用于存储字符串常量。在Java中,字符串是不可变的,即一旦创建就不能被修改。为了提高性能和节省内存,Java使用了字符串常量池来重用字符串对象。
当我们创建一个字符串常量时,Java会首先检查字符串常量池中是否已经存在相同值的字符串。如果存在,则返回常量池中的字符串对象的引用;如果不存在,则在常量池中创建一个新的字符串对象,并返回其引用。
字符串常量池的特点如下:
字符串常量池中的字符串对象是唯一的,即相同值的字符串只会在常量池中存在一份。
字符串常量池中的字符串对象是不可变的,一旦创建就不能被修改。这是因为字符串常量池的设计初衷是为了提高性能和节省内存,如果允许修改字符串对象,可能会导致其他引用到该对象的地方出现问题。
字符串常量池中的字符串对象是全局可见的,即可以在整个程序中访问到。这是因为字符串常量池是在Java虚拟机启动时就创建的,而且所有的类共享同一个字符串常量池。
在Java中,有多种方式可以将字符串放入字符串常量池:
直接使用双引号创建字符串常量,例如:
String str = "Hello";调用String类的intern()方法,该方法会将字符串添加到常量池中,并返回常量池中的字符串引用。例如:
String str = new String("Hello").intern();
需要注意的是,使用new String()方式创建的字符串对象不会放入常量池中,而是在堆内存中创建一个新的字符串对象。如果需要将其放入常量池中,可以调用intern()方法。
字符串常量池的使用可以提高性能和节省内存,特别是在频繁创建相同值的字符串时。但是需要注意的是,过度使用字符串常量池可能会导致内存泄漏问题,因为常量池中的字符串对象是全局可见的,一旦被引用,就不会被垃圾回收器回收。因此,在使用字符串常量池时,需要注意合理使用和及时释放不再使用的字符串对象。
字符串对象的创建
面试题:
String str4 = new String(“abc”) 创建多少个对象?
1、在常量池中查找是否有“abc”对象。
1)有则返回对应的引用实例;
2)没有则创建对应的实例对象。
2、在堆中 new 一个 String("abc") 对象。
3、将对象地址赋值给str4,创建一个引用。
所以,常量池中没有“abc”字面量则创建两个对象,否则创建一个对象,以及创建一个引用。
根据字面量,往往会提出这样的变式题:
String str1 = new String("A"+"B") ; 会创建多少个对象?
String str2 = new String("ABC") + "ABC"; 会创建几个对象?
str1:
字符串常量池:"A","B","AB" : 3个
堆:new String("AB") :1个
引用: str1 :1个
总共 : 5个
str2 :
字符串常量池:"ABC" “ABCABC”: 2个
堆:new String("ABC") :1个
引用: str2 :1个
总共 : 4个
String s = new String("1")+new String("1")的,会创建几个对象?
intern()的作用
intern() 方法是 String 类的一个方法,它的作用是将字符串对象添加到字符串常量池中,并返回常量池中的字符串引用。
当调用 intern() 方法时,Java 会首先检查字符串常量池中是否已经存在相同值的字符串。如果存在,则返回常量池中的字符串对象的引用;如果不存在,则在常量池中创建一个新的字符串对象,并返回其引用。
使用 intern() 方法可以实现字符串的重用,即相同值的字符串只会在常量池中存在一份。这样可以节省内存空间,并提高程序的性能。
需要注意的是,调用 intern() 方法并不会改变原始字符串对象的值,而是返回一个新的字符串对象的引用。因此,如果需要使用 intern() 方法的返回值,应该将其赋给一个新的字符串引用。
以下是 intern() 方法的示例代码:
String str1 = new String("Hello");
String str2 = str1.intern();
System.out.println(str1 == str2); // false
System.out.println(str1.equals(str2)); // true
在上面的示例中,首先创建了一个字符串对象 str1,并调用 intern() 方法将其添加到字符串常量池中。然后,将 intern() 方法的返回值赋给 str2。最后,通过比较引用和比较值的方式验证了 intern() 方法的作用。
需要注意的是,由于字符串常量池是在 Java 虚拟机启动时就创建的,并且所有的类共享同一个字符串常量池,因此 intern() 方法只能将字符串添加到当前类所在的字符串常量池中。如果需要将字符串添加到其他类所在的字符串常量池中,可以使用其他类的类名调用 intern() 方法。
StringBuffer使用
StringBuffer
StringBuffer 是 Java 中一个用于处理字符串的可变对象,它的主要作用是在需要频繁对字符串进行修改时,提供了高效的字符串操作方式。与 String 不同的是,StringBuffer 是可变的,可以动态修改其内容而不会创建新的对象。
StringBuffer 的特点
可变性:StringBuffer 对象的内容可以被修改,可以进行插入、追加、删除等操作,而不会创建新的对象。
线程安全:StringBuffer 是线程安全的,即多个线程可以同时访问一个 StringBuffer 对象而不会出现数据不一致的情况。这是因为 StringBuffer 的方法都是使用 synchronized 关键字进行同步的。
性能:由于 StringBuffer 是可变的,对字符串的修改操作不会频繁创建新的对象,因此在需要频繁操作字符串时,使用 StringBuffer 可以提高性能。
StringBuffer 的常用方法
以下是一些常用的 StringBuffer 方法:
append():追加字符串到当前 StringBuffer 对象的末尾。
insert():在指定位置插入字符串到当前 StringBuffer 对象中。
delete():删除指定位置范围内的字符。
deleteCharAt():删除指定位置的字符。
replace():替换指定位置范围内的字符序列。
reverse():反转当前 StringBuffer 对象中的字符序列。
charAt():获取指定位置的字符。
substring():获取指定位置范围内的子字符串。
示例代码
以下是一个使用 StringBuffer 的示例代码:
// 创建一个空的 StringBuffer 对象
StringBuffer sb = new StringBuffer();
// 使用 append() 方法追加字符串
sb.append("Hello");
sb.append("World");
// 使用 insert() 方法在指定位置插入字符串
sb.insert(5, ", ");
// 使用 delete() 方法删除指定位置范围内的字符
sb.delete(5, 7);
// 使用 replace() 方法替换指定位置范围内的字符序列
sb.replace(5, 10, "Java");
// 使用 reverse() 方法反转字符串
sb.reverse();
// 使用 charAt() 方法获取指定位置的字符
char ch = sb.charAt(0);
// 使用 substring() 方法获取指定位置范围内的子字符串
String subStr = sb.substring(0, 5);
System.out.println(sb.toString()); // 输出结果为:avaJ, olleH
System.out.println(ch); // 输出结果为:a
System.out.println(subStr); // 输出结果为:avaJ,
在上面的示例中,首先创建了一个空的 StringBuffer 对象 sb,然后通过不同的方法对其内容进行了追加、插入、删除、替换、反转、获取字符等操作,最后通过 toString() 方法将 StringBuffer 对象转换为字符串并输出。
使用 StringBuffer 可以方便地进行字符串的修改和操作,特别适用于需要频繁修改字符串内容的场景。
String 和 StringBuffer 互相转换
在 Java 中,可以通过以下方法实现 String 和 StringBuffer 之间的互相转换:
String 转换为 StringBuffer
使用构造方法: 可以通过 StringBuffer 的构造方法将 String 转换为 StringBuffer。示例代码如下:
String str = "Hello, World!";
StringBuffer sb = new StringBuffer(str);
使用 append 方法: 可以通过 StringBuffer 的 append 方法将 String 转换为 StringBuffer。示例代码如下:
String str = "Hello, World!";
StringBuffer sb = new StringBuffer();
sb.append(str);
StringBuffer 转换为 String
使用 toString 方法: 可以通过 StringBuffer 的 toString 方法将 StringBuffer 转换为 String。示例代码如下:
StringBuffer sb = new StringBuffer("Hello, World!");
String str = sb.toString();
2.StringBuffer + “” 强转String
StringBuffer sb = new StringBuffer("Hello, World!");
String str = sb + "";
通过以上方法,可以方便地在 String 和 StringBuffer 之间进行互相转换,根据实际需求选择合适的方法进行转换。
package和访问修饰符
package
在Java中,package是一种用于组织和管理类的机制。它可以将相关的类放在同一个包中,以便更好地组织和管理代码。
package的作用
命名空间管理:package可以将类组织在不同的命名空间中,避免类名冲突。
访问控制:package可以限制类的访问范围,只有在同一个包中的类才能访问包中的类。
代码组织:package可以将相关的类放在同一个包中,方便代码的组织和管理。
package的命名规范
在命名package时,应遵循以下规范:
小写字母:package的名称应使用小写字母。
全限定名:package的名称应使用全限定名,即使用点号(.)将各级包名分隔开。
有意义:package的名称应具有一定的意义,能够反映出所包含的类的功能或用途。
package的声明
在Java源文件的开头,可以使用package关键字声明所属的包。例如:
package com.example.myapp;
在声明package时,应将源文件放在与package对应的目录结构中。例如,上述的package声明应将源文件放在com/example/myapp目录下。
package的导入
在Java源文件中,可以使用import关键字导入其他包中的类。例如:
import com.example.myapp.MyClass;
导入类后,就可以直接使用类名来引用该类,而不需要使用完整的包名。
访问修饰符
在Java中,访问修饰符用于控制类、方法和变量的访问权限。Java提供了四种访问修饰符:
public:公共的,可以被任何类访问。
protected:受保护的,可以被同一个包中的类和子类访问。
default:默认的,没有修饰符,可以被同一个包中的类访问。
private:私有的,只能被当前类访问。
访问修饰符的使用
访问修饰符可以用于类、方法和变量的声明。以下是访问修饰符的使用规则:
类的访问修饰符:类的访问
修饰符可以是public或默认(包访问权限)。
方法的访问修饰符:方法的访问修饰符可以是public、protected、default或private。这些修饰符决定了方法可以被哪些类访问。
变量的访问修饰符:变量的访问修饰符可以是public、protected、default或private。这些修饰符决定了变量可以被哪些类访问。
访问修饰符的作用
public:公共的访问修饰符表示该类、方法或变量可以被任何类访问,没有访问限制。
protected:受保护的访问修饰符表示该类、方法或变量可以被同一个包中的类和子类访问,但不能被其他包中的类访问。
default:默认的访问修饰符表示该类、方法或变量可以被同一个包中的类访问,但不能被其他包中的类访问。如果没有指定访问修饰符,默认为default。
private:私有的访问修饰符表示该类、方法或变量只能被当前类访问,其他类无法访问。
访问修饰符的选择取决于设计的需要,合理使用访问修饰符可以提高代码的安全性和可维护性。
// 定义一个公共类
public class PublicClass {
public void publicMethod() {
System.out.println("This is a public method.");
}
}
// 定义一个受保护类
class ProtectedClass {
protected void protectedMethod() {
System.out.println("This is a protected method.");
}
}
// 定义一个默认类
class DefaultClass {
void defaultMethod() {
System.out.println("This is a default method.");
}
}
// 定义一个私有类
class PrivateClass {
private void privateMethod() {
System.out.println("This is a private method.");
}
}
// 在同一个包中使用不同访问修饰符的类
public class AccessModifiersExample {
public static void main(String[] args) {
PublicClass publicObj = new PublicClass();
publicObj.publicMethod(); // 可以访问公共方法
ProtectedClass protectedObj = new ProtectedClass();
protectedObj.protectedMethod(); // 可以访问受保护方法
DefaultClass defaultObj = new DefaultClass();
defaultObj.defaultMethod(); // 可以访问默认方法
PrivateClass privateObj = new PrivateClass();
// privateObj.privateMethod(); // 无法访问私有方法,会编译错误
}
}
Comments