前言:
在之前的学习中,学习了和了解了一些类的基本使用,例如object类等等,但是我们用String这个引用或者说这个类其实我们已经用了好久,只不过没有具体分析过!
对于String类,它可以引用一个字符串,在C语言中没有一个类型是字符串类型。
接下来就来探究一下String类带给我们的一些方法。
常用方法:
1、构造方法:
字符串的构造方法常见的有三种:
public class Test1 {
public static void main(String[] args) {
//方式一:
String str = "abcd";
//方式二:
String str1 = new String("abcd");
//方式三:
char[] arr = {'a','b','c','d'};
String str2 = new String(arr);
}
}
由于String是引用类型,自己本身不存储数据,在String类中实例变量如下:
String s1 = new String("hello");
String s2 = new String("world");
String s3 = s1;
如上这段代码是s1和s3是引用同一个对象的,画图解释:
注意:
在Java中用" "引起来的也是String类型!!
字符串的比较:
字符串的比较有四种情况:
1.比较String类型是否引用同一个对象:
也就是用"=="比较两个引用的地址是否相同:
public static void main(String[] args) {
//对于基本变量“==”是比较两个值是否相等
int a = 10;
int b = 20;
int c = 10;
System.out.println(a == b);//fasle
System.out.println(a == c);//true
//对于String引用类型,比较地址
String s1 = new String("abcd");
String s2 = new String("abcd");
String s3 = s1;
System.out.println(s1 == s2);//false
System.out.println(s1 == s3);//true
System.out.println(s2 == s3);//false
}
我们从结果也能看出!
但是!!!,这时候有一个问题:我用直接引用的方式,也就是不new直接引用一个字符串结果是否还是一样的呢?
public static void main(String[] args) { String s1 ="abcd"; String s2 = "abcd"; String s3 = s1; System.out.println(s1 == s2); System.out.println(s1 == s3); System.out.println(s2 == s3); }
结果是:
三个true,难道说此时没有在比较地址?还是说没有在堆区开辟新的空间?
要谈就这个问题和"常量池"有关,放在后边的讲解中!
2.equals方法按照字典序比较两个字符串
也就是比较两个字符串中的每一个字符是不是都是一样的,如果一样就返回true,如果不一样就返回false!
String类中的该方法时继承Object类中的equals方法,如果我们想要有自己的equals方法也可以重写。
public static void main(String[] args) {
String s1 = new String("abcde");
String s2 = new String("abcde");
String s3 = new String("abc");
System.out.println(s1.equals(s2));//true
System.out.println(s1.equals(s3));//false
}
此时可以看出结果,equals方法可以比较两个字符串里面的字符是不是一样的。
我们可以拿到equals的源码:
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
这个源码是Object类中的方法,被继承之后可以使用,这个源码的特点:
1、当两个引用类型引用同一个对性的时候,也就是地址相同时,直接返回true
2、检查两个引用的类型是否一样,如果不一样直接返回false。
3. this和 anObject 两个字符串的长度是否相同,是继续比较,否则返回 false4、将字符串放入字符数组中,逐一比较每个字符的Ascall值是否一样。
3.compareTo方法 按照字典序比较
这个方法比起equals方法更加精细化二了,equals方法只能告诉你两个字符串相不相等,
但是compareTo方法能够告诉你如果不相等那个字符串大。
public static void main(String[] args) {
String s1 = new String("abcdef");
String s2 = new String("abc");
String s3 = new String("efg");
String s4 = new String("abcdef");
System.out.println(s1.compareTo(s2));
System.out.println(s1.compareTo(s3));
System.out.println(s1.compareTo(s4));
}
注意:
1. 先按照字典次序大小比较,如果出现不等的字符,直接返回这两个字符的大小差值2. 如果前 k 个字符相等 (k 为两个字符长度最小值 ) ,返回值两个字符串长度差值
源码如下:
public int compareTo(String anotherString) {
int len1 = value.length;
int len2 = anotherString.value.length;
int lim = Math.min(len1, len2);
char v1[] = value;
char v2[] = anotherString.value;
int k = 0;
while (k < lim) {
char c1 = v1[k];
char c2 = v2[k];
if (c1 != c2) {
return c1 - c2;
}
k++;
}
return len1 - len2;
}
4、compareToIgnoreCase方法:
与compareTo方式相同,但是忽略大小写比较。
public static void main(String[] args) {
String s1 = new String("abcdef");
String s2 = new String("abc");
String s3 = new String("efg");
String s4 = new String("AbcdEf");
System.out.println(s1.compareToIgnoreCase(s2));
System.out.println(s1.compareToIgnoreCase(s3));
System.out.println(s1.compareToIgnoreCase(s4));
}
结果是:
发现s1和s4在大小写上有区别,但是该方法可以忽略大小写,直接比较!
字符串的查找:
返回index位置上字符:
也就是找到对应位置上的字符:
public static void main(String[] args) {
String s = "abcdefghhigkl";
System.out.println(s.charAt(1));
System.out.println(s.charAt(3));
System.out.println(s.charAt(20));
}
注意事项:
如果index为负数或者越界,抛出IndexOutOfBoundsException异常
返回字符第一次出现的位置:
public static void main(String[] args) {
String s = "abcdefghhigkl";
System.out.println(s.indexOf('e'));
System.out.println(s.indexOf('c'));
System.out.println(s.indexOf('z'));
}
注意事项:
1. 如果index在字符串中没有则返回-1。
2.参数index需要传字符,内部是用整形接收字符的ASCALL码值。
返回从指定位置开始第一次对应字符出现的位置:
public static void main(String[] args) {
String s = "abcdefghhigkl";
System.out.println(s.indexOf('a',0));
System.out.println(s.indexOf('a',2));
System.out.println(s.indexOf('l',99));
}
返回指定字符串的位置:
该方法可以返回指定字符串第一次出现的位置:
public static void main(String[] args) {
String s = "abcdefghhigkl";
System.out.println(s.indexOf("igk"));
System.out.println(s.indexOf("l"));
System.out.println(s.indexOf("abcd"));
}
如果没有就返回-1。
从后往前找对应字符串,返回对应位置:
public static void main(String[] args) {
String s = "abcdefghhigkl";
System.out.println(s.lastIndexOf('d'));
System.out.println(s.lastIndexOf('l'));
}
其效果和indexOf一样的。
当然它同样也有一些重载的方法,这里就不一一列举了!!
转化:
数值转字符串:
class Student{
int age;
String name;
public Student(int age,String name){
this.age = age;
this.name = name;
}
@Override
public String toString() {
return "Student{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
}
public class Test1 {
public static void main(String[] args) {
String s1 = String.valueOf(1234);
String s2 = String.valueOf(12.34);
String s3 = String.valueOf(true);
String s4 = String.valueOf(new Student(13,"xiaoming"));
System.out.println(s1);
System.out.println(s2);
System.out.println(s3);
System.out.println(s4);
}
字符串转数值:
public static void main(String[] args) {
String s1 = new String("12345");
String s2 = new String("123.45");
int a = Integer.parseInt(s1);
double b = Double.parseDouble(s2);
System.out.println(a);
System.out.println(b);
}
大小写转换:
public static void main(String[] args) {
String s1 = "abcde";
String s2 = "HAHAHA";
String s3 = "abcDEF";
System.out.println(s1.toUpperCase());//小写转大写
System.out.println(s2.toLowerCase());//大写转小写
System.out.println(s3.toUpperCase());//小写转大写
System.out.println(s3.toLowerCase());//大写转小写
}
字符串转数组:
public static void main(String[] args) {
String s = "hello";
// 字符串转数组
char[] ch = s.toCharArray();
for (int i = 0; i < ch.length; i++) {
System.out.print(ch[i]);
}
System.out.println();
// 数组转字符串
String s2 = new String(ch);
System.out.println(s2);
}
字符串的替换:
public static void main(String[] args) {
String s = "helloworld!";
System.out.println(s.replaceAll("l", "_"));
System.out.println(s.replaceFirst("l", "_"));
System.out.println(s.replaceAll("hel","_"));
}
注意:
如果字符串中没有对应要替换的对象就返回原来的字符串!
字符串拆分:
String[] split(String regex) 将字符串全部拆分
可以将一个完整的字符串按照指定的分隔符划分为若干个子字符串。
public static void main(String[] args) {
String s = "abc def ghi";
String[] s1 = s.split(" ");
for (String s2:s1) {
System.out.println(s2);
}
}
String[] split(String regex, int limit) 将字符串以指定的格式,拆分为limit 组
public static void main(String[] args) {
String s = "abc def ghi";
String[] s1 = s.split(" ",2);
for (String s2:s1) {
System.out.println(s2);
}
}
特殊:
拆分如下字符串:
public static void main(String[] args) {
String s = "192.182.1.13";
String[] s1 = s.split(".");
for (String x:s1) {
System.out.println(x);
}
}
打印结果却不对劲。
注意:
1. 字符"." , "|" , "*" , "+" 都得加上转义字符,前面加上 "\\" .2. 而如果是 "\" ,那么就得写成 "\\\\" .3. 如果一个字符串中有多个分隔符,可以用"|"作为连字符.
可以这样写:
public static void main(String[] args) {
String s = "192.182.1.13";
String[] s1 = s.split("//.");
for (String x:s1) {
System.out.println(x);
}
}
多次拆分:
String str = "name=zhangsan&age=18" ;
String[] result = str.split("&") ;
for (int i = 0; i < result.length; i++) {
String[] temp = result[i].split("=") ;
System.out.println(temp[0]+" = "+temp[1]);
}
字符串截取:
String substring(int beginIndex) 从指定索引截取到结尾String substring(int beginIndex, int endIndex) 截取部分内容
public static void main(String[] args) {
String s = "helloworld!!";
System.out.println(s.substring(3));
System.out.println(s.substring(3,8));
}