String相关代码
public class TestDemo2 {
public static void main(String[] args) {
String str = "hellobit";//直接赋值,在常量池中,只放字符串.
//其他对象都在堆上。被static所修饰的放在方法区。
String str2 = new String("hellobit");
System.out.println(str==str2);
String str3="hellobit";
System.out.println(str==str3);//这里比较的是地址是否一样。
String str4="hello"+"bit";//常量在编译的时候已经拼接好了。
System.out.println(str==str4);
System.out.println(str3==str4);
String str5="hello";
String str6=str5+"bit";
System.out.println(str==str6);
//str5是一个变量。常量在编译时无法判断。
String str7="hello"+new String("bit");
System.out.println(str==str7);
//hello在常量池中,而new的常量bit在堆上。所以地址不同。
String str8=new String("hello")+new String("bit");
System.out.println(str==str8);
//hello和bit 都在堆上,但是开辟了不同空间,所以地址不同;
String str9= new String("hello").intern();//手动入池
String str10="hello";
System.out.println(str9==str10);//都放在常量池中,所以地址相同,返回true。
String str11=new String("hellobit").intern();//手动入池,会产生垃圾空间。
System.out.println(str==str11);
}
}
特殊
public class TestDemo2 {
public static void main(String[] args) {
String str=null;
String str2=new String("hellobit");
System.out.println(str.equals(str2));
}
}
这是会出现NullPointerException错误—空指针错误。
所以null不能和开辟了内存的对象比较。
字符串不可变更
字符串一旦定义不可改变
String的拼接每次都会产生新的对象
public class TestDemo2 {
private static Double lnteger;
public static void main(String[] args) {
String str="abc";
System.out.println(lnteger.toHexString(str.hashCode()));
str=str+"def";
System.out.println(lnteger.toHexString(str.hashCode()));
str=str+"ghi";
System.out.println(lnteger.toHexString(str.hashCode()));
System.out.println(str);
}
输出结果为:
字符串上没有变化,但是其哈希码不同,所以充分证明String的拼接每次都会产生新的对象。此方法忽产生很多的垃圾空间。
但是 StringBuffer StringBuilder就可以改变这种情况。
public class TestDemo2 {
private static Double lnteger;
public static void main(String[] args) {
String str="abc";
System.out.println(lnteger.toHexString(str.hashCode()));
str=str+"def";
System.out.println(lnteger.toHexString(str.hashCode()));
str=str+"ghi";
System.out.println(lnteger.toHexString(str.hashCode()));
System.out.println(str);
System.out.println("====================");
StringBuffer stringBuffer=new StringBuffer();
System.out.println(lnteger.toHexString(stringBuffer.hashCode()));
stringBuffer.append("ab");
System.out.println(lnteger.toHexString(stringBuffer.hashCode()));
stringBuffer.append("cd");
System.out.println(lnteger.toHexString(stringBuffer.hashCode()));
System.out.println("=====================");
StringBuilder stringBuilder=new StringBuilder();
System.out.println(lnteger.toHexString(stringBuilder.hashCode()));
stringBuilder.append("ab");
System.out.println(lnteger.toHexString(stringBuilder.hashCode()));
stringBuilder.append("cd");
System.out.println(lnteger.toHexString(stringBuilder.hashCode()));
}
}
输出结果为:
面试题
String StringBuffer StringBuilder的区别和联系
- StringBuffer 和 StringBuilder 也是操作字符串的两个类,三种类型都被final修饰。
1、StringBuffe 有 synchronized 但是StringBuilder没有
StringBuffer多线程情况下使用,synchronized线程安全的关键字
StringBuilder没有 String 没有 单线程情况下 线程不安全
2、拼接上:String每次都会产生新的空间
而StringBuffer StringBuilder ==》append() ==>不会产生新的空间
3、String的拼接底层被优化为StringBuilder
append进行拼接 结果将会调用StringBuilder的toString();
String str = "hello";
str = str+"bit";
System.out.println(str);
当String 拼接遇到循环时,优先考虑StringBuilder。并且放在循环的外面
class StringA {
public String fun(String[] strings) {
String str = null;
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < strings.length; i++) {
stringBuilder.append(strings[i]);
str = stringBuilder.toString();
}
return str;
}
}
String 和 StringBuffer的相互转换
//String转StringBuffer
public class TestDemo4 {
public static void main(String[] args) {
String str="change";
StringBuffer stringBuffer=new StringBuffer();
System.out.println(str);
StringBuffer stringBuffer1=new StringBuffer();
stringBuffer1.append(str);
System.out.println(stringBuffer1);
}
}
//StringBuffer转 String
public class TestDemo4 {
public static void main(String[] args) {
StringBuffer stringBuffer =new StringBuffer("change");
String str=new String(stringBuffer);
System.out.println(str);
String str2=stringBuffer.toString();//返回一个toString
System.out.println(str2);
}
}
字符与字符串
将字符数组中的所以内容变为字符串。
import java.util.Arrays;
public class TestDemo2 {
public static void main(String[] args) {
char[]value ={'a','b','c','d','e'};
//将字符数组中的所以内容变为字符串
String str=new String(value);
System.out.println(str);
//将部分字符数组中的内容变为字符串
String str2=new String(value,0,2);
System.out.println(str2);
//取得指定索引位置的字符,索引从零开始。
String str3="hyh";
//从0号位置开始找
char ch=str3.charAt(1);
System.out.println(ch);
//将字符串变为字符数组
char[]chars=str3.toCharArray();
System.out.println(Arrays.toString(chars));
}
}
判断字符串中数字的个数
public class TestDemo1 {
public static int isNumber(String str) {
int count=0;
for (int i = 0; i < str.length(); i++) {
/*if(str.charAt(i) < '0'|| str.charAt(i) > '9') {
count++;
}*/
//Character.isDigit(str.charAt(i) 判断一个字符是否为数字
if(Character.isDigit(str.charAt(i))) {
count++;
}
}
return count;
}
public static void main(String[] args) {
String str="abc21b416u";
System.out.println(isNumber(str));
}
字节与字符串
public class TestDemo1 {
public static void main(String[] args) throws UnsupportedEncodingException {
byte[] bytes = {97, 98, 99, 100};
String s = new String(bytes, 1, 2);//将部分数组中的内容变为字符串
System.out.println(s);
String str = "abcdef";
byte[] data = str.getBytes("UTF-8");
System.out.println(Arrays.toString(data));将字符串以字节数组的形式返回
}
}
字符串比较
public class TestDemo1 {
public static void main(String[] args) {
String str1="abcdefbc";
String str2="abc";
System.out.println(str1.equals(str2));//区分大小写的比较
System.out.println(str1.equalsIgnoreCase(str2));不区分大小写的比较
System.out.println(str1.compareTo(str2));比较两个字符串大小关系
}
}
字符串查找
public class TestDemo1 {
public static void main(String[] args) {
//判断一个字符串是否存在
System.out.println(str1.contains("ab"));//必须是连续的
//从头开始查找指定字符串的位置,查到了返回位置的开始索引,如果查不到返回-1
System.out.println(str1.indexOf("bc",5));
System.out.println(str1.indexOf("bc",15));//返回-1
//从指定位置由后向前查找
System.out.println(str1.lastIndexOf("bc", 4));
//从指定位置判断是否以指定字符串开头
System.out.println(str1.startsWith("ab",2));
//判断是否以指定字符串开头
System.out.println(str1.startsWith("a"));
//判断是否以指定字符串结尾
System.out.println(str1.endsWith("d"));
System.out.println(str1.endsWith("bc"));
}
}
字符串替换
public class TestDemo1 {
public static void main(String[] args) {
String str1="abcdefbc";
//把第一个参数替换成第二个参数
String str2=str1.replaceAll("ab","g");
System.out.println(str2);
//替换首个内容
String str3=str1.replaceFirst("ab","gg");
System.out.println(str3);
}
}
字符串拆分
public class TestDemo4{
public static void main(String[] args) {
String str="change the world";
String[] strings=str.split(" ",3);//将字符串部分拆分,该数组长度就是limit的最小值
for (String sr1:strings){
System.out.println(sr1);
}
System.out.println("================");
String[] strings2=str.split(" ",2);当limit小于最小值,只能拆分两次
for (String sr2:strings2){
System.out.println(sr2);
}
}
}
特殊情况的拆分
特殊符号: * ^ . : | \ 这些符号都需要 \ 的转义
public class TestDemo4 {
public static void main(String[] args) {
String str = "192.168.1.1";
String[] strings = str.split("\\.");
for (String str2 : strings) {
System.out.println(str2);
}
System.out.println("=============");
String str1 = "192^168^1^1";
String[] strings1 = str1.split("\\^");
for (String str2 : strings1) {
System.out.println(str2);
}
System.out.println("=============");
String str2 = "192\\168\\1\\1";
String[]strings2=str2.split("\\\\");//一个\跟一个\.
for (String str3:strings2){
System.out.println(str3);
}
}
}
字符串截取
public class TestDemo4 {
public static void main(String[] args) {
String str="change world";
String sub=str.substring(2,7);//左闭右开[2,7)
System.out.println(sub);
String str1=" hu yu hang ";
String str2=str1.trim();//去掉字符串左右空格,保留中间空格
System.out.println(str2);
String str3=str.toUpperCase();//字符串转大写
System.out.println(str3);
boolean str4=str.isEmpty();//判断是否为空字符串,但不是null,而是长度为0;
System.out.println(str4);
}
}
Object类
Object是java默认提供的一个类。java里面除了Object类,所有类都存在继承关系。默认继承Object父类。
class Preson implements Comparable<Preson>{
private String name;
private int age;
public Preson (String name,int age){
this.name=name;
this.age=age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public int compareTo(Preson o) {
int a=o.age;
int b=this.age;
return a-b;
}
}
public class TestDemo5 {
public static void main(String[] args) {
String str = "change";
String str1 = "world";
str.equals(str1);
System.out.println(str);
fun(new Preson("hyh",20));
fun(new Student());
}
}
对象比较
class Preson implements Comparable<Preson>{
private String name;
private int age;
public Preson (String name,int age){
this.name=name;
this.age=age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (this==obj){
return true;
}
if (!(obj instanceof Preson)){
return false;
}
Preson preson=(Preson)obj;
return this.name.equals(preson.name)&&
this.age==preson.age;
}
}
public class TestDemo5 {
public static void main(String[] args) {
Preson preson1=new Preson("hyn",10);
Preson preson2=new Preson("hyh",10);
Preson preson3=preson1;
System.out.println(preson1.equals(preson2));
}
}
使用Object来接受数组对象
public class TestDemo5 {
public static void main(String[] args) {
Object object = new int[]{1, 2, 3, 4};//Object接受数组,向上转型
int [] data=(int[]) object;//向下转型,需要强转
for (int i :data)
System.out.println(i);
Object object2 = new double[]{1.1, 2.0, 3.9, 4.1};
double [] data1=(double[]) object2;
for (double j :data1)
System.out.println(j);
}
}
包装类
包装类就是讲基本数据类型封装到类中
装箱与拆箱:
public class TestDemo5 {
public static void main(String[] args) {
//装箱(装包) 把简单类型包装为一个对象
Integer a=20;//自动装箱//Integer.valueOf
Integer a2=new Integer(40);//显示装箱
System.out.println(a);
System.out.println(a2);
//拆箱 :把包装类拆分为对应的简单类型
int i=a;//自动拆箱 Integer.intValue:()
System.out.println(i);
double d =a.doubleValue();
System.out.println(d);//显示拆箱
}
}
说明:对于 Integer var = ? 在-128 ⾄ 127 范围内的赋值,Integer 对象是在IntegerCache.cache 产生,会复⽤已有对象,这个区间内的 Integer 值可以直接使用==进行判断,但是这个区间之外的所有数据,都会在堆上产生,并不会复用已有对象,这是一个大坑,推荐使用 equals 方法进行判断。
public class TestDemo5 {
public static void main(String[] args) {
//缓存 -128 -- 127
Integer integer=100;
Integer integer1=100;
System.out.println(integer==integer1);
Integer integer2=200;
Integer integer3=200;
System.out.println(integer2==integer3);
}