本人码云(建议pc端打开,手机可能会出现字体过小问题。)
本人会不定期在码云上更新一些算法或数据结构的基础程序,后期也会学习进阶程序,也会更新大厂的面试题。
如果您有好的建议和想法,欢迎在本人码云相应代码评论区评论哦。希望大家都能在编程这条路上越走越远。也祝看到这篇博客的人,能真正搞懂这方面知识,当然,若有错误,请提出改正,谢谢大家啦。
本人后续会在这里更新操作系统和计组的笔记,敬请期待!
有赞必回,评论必回,顺着网线回访!
Java字符串
引入
JDK中String类的声明:
被 final
修饰的类无法被继承,String类不存在子类。
这样的话就可以保证所有使用JDK的人,大家用到的String类仅此一个,大家都相同。
假设现在String允许继承,每个人都可以继承String类,修改它的方法等实现。MyString1和MyString2、3都是完全不同的子类,都可以向上转型变为String。
String str = new MyString1();
String str = new MyString2();
String str = new MyString3();
假设每个人都扩展、每个人都自己覆写equals方法、那么就会有歧义、从而导致String类使用不统一、因为String是一个非常常见的类、总不能在你的电脑上可以正常运行的代码,在别人那里就不行了,对吧~~
这就说明:继承和方法覆写在带来灵活的同时,也会带来很多子类行为不一致导致的问题。
什么时候会用到 final
修饰类
你希望这个类不要有别的版本,那么就到此为止,所有使用者的这个类完全相同,没有别的实现。
1.创建字符串
方式一:直接赋值
方式二:通过构造方法产生对象
方式三:通过字符数组产生对象
方式四:通过String的静态方法valueOf
(任意数据类型)转为字符串
字面量:直接写出来的数值就是字面量
10 int字面量
3.14 double字面量
true boolean字面量
“abc” 字符串字面量
2.字符串比较相等
所有引用数据类型
在比较数值相等时,使用equals方法
比较,JDK常用类,都已经覆写了equals方法,直接使用即可。例如:String、Integer
如果是自己写的类,如Student类,Person类等,都要自己覆写equals方法。
引用数据类型如果使用 “==” 运算符、比较的仍然是数值,不过是比较
地址值
是否相等,地址值代表的是它们在内存、即堆上是否在同一个位置上
。
字符串除了比较值相等(equals)、比较地址相等(==)以外,
字符串String也实现了Comparable接口,覆写了compareTo方法
3.字符串常量池
为什么引用常量池?
所谓的 “ 池 ” – 都是类似的思想
共享设计
模式、节省空间
(内存是一个紧俏的资源!)
字符串产生之后大部分情况下都是用来进行输出处理、打印它的内容
“hello”,为啥不整一个就行了~
数据库的连接池 线程池都是类似的思想
手工入池方法:String类提供的intern方法
调用intern方法会将当前字符串引用指向的对象保存到字符串常量池中。
a.若当前常量池中已经存在了该对象,则不再产生新的对象,返回常量池中的String对象地址。
b.若当前常量池中不存在该对象,则将该对象入池,返回入池后的地址。
再比如:
字符串牵扯用户输入,判空
//这个变量由用户由浏览器输入
String userName = null;
//a
System.out.println(userName.equals("小树"));
//b
System.out.println("小树".equals(userName));
//哪种方法好?
//牵扯到用户输入、一定要判空
//如果采用a方法、userName可能为空
//用一个null去点一个方法、会产生空指针异常
//推荐采用b方法、把待比较的特定内容放在前面
//这样非常好,方便处理userName为空的情况
4.字符串的不可变性
为何字符串对象无法修改内容,而其他类的对象能修改内容呢?
字符串就是一个字符数组 ==> char[],字符串保存的值实际上在数组中保存
。
String外部无法访问这个value数组
String并没有提供关于value属性的getter和setter方法
对于String类的外部而言,value数组完全无法使用。
因此字符串对象的内容无法修改(String类的外部拿不到这个value数组)
5.如何修改字符串的内容
a.在运行时通过反射破坏value数组的封装(了解,非常不推荐!ds部分讲反射就会了,反射是所有框架的基础)
b.更换使用
StringBuilder
或者StringBuffer
类 ==> 已经不是同一个类型了若需要频繁进行字符串的拼接,使用StringBuilder类的
append
方法
StringBuilder类可以修改对象的内容。
StringBuffer与StringBuilder使用方法完全一样、但是StringBuffer线程安全、支持多线程、性能较差。
6.StringBuilder类具体使用
StringBuilder和String类是两个独立的类,因为String的对象无法修改内容,为了方便字符串的拼接操作,产生了StringBuilder类。
StringBuilder类的对象是可以修改内容的。
请解释String、StringBuilder、StringBuffer的区别:
1.String的对象无法修改,俩sb的对象的内容可以修改;
2.StringBuffer是线程安全的操作,性能较差;StringBuilder是线程不安全,性能较高。
关于本节的两个重点:
a.关于字符串常量池以及intern方法的理解问题;
b.理解啥是个字符串不可变;
c.StringBuilder的使用。
7.字符和字符串的转换
字符串的内部实际上就是使用字符数组来存储的。
将字符数组转换为字符串
public String ( char[] ch )
其实在valueOf内部、和构造方法是一样的。
那么能不能用toString呢?
对于char[]这个字符数组对象、它的内部没有覆写toString这个方法、所以它是继承了Object的toString方法、返回地址值、所以不太合适。
将部分字符数组转换为字符串
public String ( char[] value, int offset, int count )
如果count大于了ch.length-1、越界了、会报错
取出字符串中指定索引的字符
public char charAt( int index )
返回值char类型
将字符串的内容转为字符数组
public char[] toCharArray()
此时产生了一个新的字符数组
,将字符串的内容复制过去。
字符串String对象不可变!!
isNumber
自己写一个方法:判断某个字符串是否由纯数字组成
public static boolean isNumber( String str )
{
//"123" ==> 转为字符数组
//1.str == > char[]
char[] data = str.toCharArray();
//2.循环遍历data中的每个字符,判断这个字符是否是数字字符
//['0' ... '9']
for( char c : data )
{
if( c < '0' || c > '9' )
return false; //找反例
}
return true;
}
系统自带的方法:
8.String常用方法
1.三个布朗
str.contains("world")判断str中是否包含字串"world"
str.startsWith("hello")str是否以指定字符串开头
str.endsWith("world")str是否以指定字符串结尾
这三个返回值都是布朗
代码:
2.字符串替换操作
public String replaceAll(String regex, String replacement)
替换所有的指定内容
public String replaceFirst(String regex, String replacement)
替换首个内容
代码
public class StringReplace
{
public static void main(String[] args)
{
String str = "wowowowowo";
System.out.println( str.replaceAll("w","_") );
System.out.println( str.replaceAll("wo","ha") );
System.out.println( str.replaceFirst("wo","ha"));
/*
此时的修改是否会修改原字符串的内容?
不会!
字符串类中所有针对字符串的操作,都是产生了一个新的字符串
(字符串的不可变性)只有StringBuilder可以修改
*/
System.out.println(str);
}
}
3.字符串拆分操作(拆分成字符数组)
public String[] split( String regex ) 全部拆分
public String[] split( String regex, int limit ) 部分拆分
代码
public class StringSplit
{
public static void main(String[] args)
{
// String str = "Hello Java Hello Rocket";
// String[] data1 = str.split(" ");
//
// //按照空格将str拆分,拆分后的字符串数组长度为2
// String[] data2 = str.split(" ", 2);
//
// System.out.println(Arrays.toString(data1));
// System.out.println(Arrays.toString(data2));
// [Hello, Java, Hello, Rocket]
// [Hello, Java Hello Rocket]
//Web开发,经常拆分ip地址
String str = "192.168.1.1";
String []data = str.split(".");
System.out.println(Arrays.toString(data));
//[] 居然没拆成功
/*
当按照指定的格式拆分字符串得到了一个空数组
原因是:
你的这个格式是个特殊字符,需要转义处理"\\"
*/
String []data1 = str.split("\\.");
System.out.println(Arrays.toString(data1));
//有时候,拆分之后,得到的字符串和原字符串长得一样
//这是因为,这个字符在原字符串中不存在
String[] data2 = str.split( ",");
String str2 = Arrays.toString(data2);
System.out.println( str2 );//[192.168.1.1]
//这是将一个字符数组转换为字符串了,当然有两个框
//就像将数字1转换为字符串还是长这样:1
System.out.println( str == str2 );
}
}
4.字符串的截取处理
public String substring( int beginIndex ) 从指定索引截取到结尾
public String substring( int beginIndex, int endIndex) 截取部分内容
左闭右开,包含开头,不包含结束,只要记住截取的字符长度为 end-begin 就行了。
代码
5.其他常用方法
使用:
注意:
既然不能用,那么怎么判断一个字符串是否是空或者是null呢?
if( str == null || str.isEmpty() )
return true;
6.练习
写一个方法,将一个字符串的首字母大写,并返回
方法:
public static String firstUpper(String str)
{
//1.判空
if(str == null || str.isEmpty())
return null;
//2.边界
if(str.length() == 1)
return str.toUpperCase();
//3.str长度大于1
//其实就是一个截取 + 大写操作
return str.substring(0,1).toUpperCase() + str.substring(1);
}
应用: