JavaSE之三个特殊的类

1.java.lang.String类

String类是一个引用数据类型,是被final修饰的类,不能被继承
String也有构造方法。
1.String类的两种赋值方式
1.1直接赋值:
直接赋值的数据在堆上开辟空间
java为String类提供了缓冲池机制的功能,当直接给字符串赋值时,JVM会先到缓冲池寻找是否存在内容相同的字符串,若有就直接使用,不另辟空间,若没有,就在缓冲池内创建一个新的空间保存字符串供下次使用。

String str="hello";

1.2通过构造方法实例化对象(直接方法)
用构造方法为实例化对象赋值时,jvm会开辟开辟两片内存空间,因为一个字符串就是一个匿名对象,会在堆内存开辟一片空间,当用了new以后,会再开辟一个堆空间,供栈内存引用,因此第一次开辟的堆内存空间就成了来及空间,会被GC回收,增大了开销。

String str1=new String("hello");

手工入池操作:public native String intern();
是一个本地方法,函数体在系统底层开发语言C语言中,是一个成员方法,需要对象调用。intern()方法的返回值是一个字符串。

String str2=new String("hello").intern();//new开辟的堆内存空间入池

入池操作可减少开销,提高性能,入池后用“==”比较两个相同的字符串,返回结果为true,因为是同一片内存地址,没有新开辟空间。

String str1="nihao";//直接赋值,自动入池,一片堆空间
String str2="nihao";//池中存在,不开辟堆空间
String str3="nihao";//池中存在,不开辟堆空间
String str4=new String("nihao");//构造方法赋值,开辟两块堆空间

以上代码段一共在堆内存上开辟了3片堆内存空间

2.字符串相等比较
“==”比较运算符只能比较数值是否相等,对于字符串不能用“==”比较,因为String是引用数据类型,若用“==”比较,比较的是字符串的地址,因此要比较字符串的内容只能用方法equals()public boolean equals(String anotherString)比较,equals方法只是一个成员方法,因此要用对象调用。

str.equals(anotherString)

使用equals 方法时,若要判定用户输入的字符串是否与特定字符串相等,那么尽量将特定字符串写在前面,避免了用户输入为空时会造成空指针异常。

3.字符串常量(“”括起来的内容)是String的匿名对象
验证方法:"hello".equals(str1);返回结果为true.
4.字符串常量不可变更
字符串常量一旦定义后不可修改,若进行了修改,会另外开辟新的堆空间(字符串对象)。

String str="hello";//产生符串对象"hello"
str=str+"world";//产生字符串对象 "world","hello world"
str+="!!!";//产生字符串对象 "!!!","hello world !!!"
System.out.println(str);//此段代码共产生了5个字符串对象。

5.字符与字符串的相互转换
a.将字符数组转为字符串

public String(char[] value);//构造方法,使用构造方法赋值时使用

public String(char[] value,int offset,int count)//构造方法,使用构造方法赋值时使用

b.将字符串转为单个字符

public char charAt(int index);//返回值为字符,参数为字符串索引

c.将字符串变为字符数组

public char[] toCharArray();
	char[] data=new char[]{'h','e','l','l','o'};//定义字符数组
	String str=new String(data);//通过字符串的构造方法将字符数组转为字符串
	System.out.println(str);
	
	char c="hello".charAt(1);//将字符串转为字符,取索引为1的字符
	System.out.println(c);
	
	char[] chars="hello".toCharArray();//将字符串串转为字符数组
	System.out.println(chars);
	
	System.out.println(chars.length);//数组有length属性
	
	System.out.println("nihao".length());//字符串有length方法

字节与字符串
1.将字符串转为字符数组

public String(byte[] value)
public String(byte[] value,int offset,int length)
public void code4(){
		byte[] by=new byte[]{1,2,3};
		String str=new String(by);
		System.out.println(str);
	}

2.将字符串转为字节数组
字节不适合处理中文,字节只适合处理二进制字节
public byte[] getBytes();

public void code5(){
	String str="hello";
	byte[] by=str.getBytes();
	for(int i=0;i<by.length;i++){
	System.out.println(by[i]);
	}

3.将字符串按照指定编码转为字节数组

   public byte[] getBytes(String charsetName);

字符串比较
1.不区分大小写相等比较

public boolean equalsIgnoreCase(String str)
public void code6(){
		String str1="hello";
		String str2="Hello";
		System.out.println(str1.equalsIgnoreCase(str2));
	}

2.比较两个字符串的大小

  public int CompareTo(String str)//返回值0:表示等于比较对象
  //返回值大于0:表示大于比较对象
  //返回值小于0:表示小于比较对象

字符串查找
1.判断本字符串是否存在

public boolean contains(String s)
String str1="hello";
	String str2="Hello";
	System.out.println(str1.contains(str2));//false

2.判断是否以指定字符串开始

String str1="hello";
	String str2="Hello";
	System.out.println(str1.startsWith(str2));	

3.是否以指定字符串结尾

System.out.println("skfdk".endsWith("k"));	
	

4.使用indexof()进行位置查找
一旦查找到立即返回索引,未查找到返回-1

String str="helloworld";
	System.out.println(str.indexOf("ll"));//2
	System.out.println(str.indexOf("nihao"));//-1
	System.out.println(str.indexOf("o"));//4

5.从指定位置开始查找
包含指定位置开始

public in indexOf(String str,int fromIndex)

6.从指定位置开始判断是否以指定字符开头

	System.out.println("nihao".startsWith("h",2));	//true
       //从“nihao”的第二个位置开始,判断是否以“h”开头

字符串替换
1.替换所有指定内容

public String replaceAll(String reg,String replace)

2.替换首个指定内容

public String replaceFirst(String reg,String replace)
System.out.println("java is best".replaceAll(" ","-"));	
System.out.println("java is best".replaceFirst(" ","-"));	

字符串拆分
1.将字符串按照指定格式全部拆分为字符串数组split(String reg)
2.将字符串部分拆分为字符串数组 ,数组长度为limit split(String reg,int limit)

String str="hello java language";
	String[] result=str.split(" ");
	for(int i=0;i<result.length;i++){
		System.out.println(result[i]);
	}
//hello
//java
//language
	
	String[] result1=str.split(" ",2);
	for(int i=0;i<result1.length;i++){
		System.out.println(result1[i]);
	}
//hello
//java language
String str="张三:23|李四:23|王五:78";
		String[] res=str.split("\\|");//“|”是转义字符,需用\\转义
		for(int i=0;i<res.length;i++){
			String[] temp=res[i].split(":");
			for(int j=0;j<temp.length;j++){
			System.out.println(temp[j]);}
		}

字符串截取
1.从指定位置截取到结尾

public String substring(int begin);

2.从指定位置开始截取到指定位置结束

public String substring(int start,int ends);//包含start 不包含ends
String str="helloworld";
	System.out.println(str.substring(5));//world
	System.out.println(str.substring(5,9));//worl

字符串的其他方法
1.去掉字符串的左右空格,保留中间空格

public String trim()

2.字符串转大写
只能转化字母

public String toUpperCase

3.字符串转小写
只能转化字母

public String toLowerCase()
String str=" hello bite !";
	System.out.println(str.trim());
	str=str+"你好3487&&*&MD";
	System.out.println(str.toUpperCase());
	System.out.println(str.toLowerCase());

在这里插入图片描述
4.取得字符串长度

public int length()

5.判断是否为长度为0的字符串(长度为0 不是null)

public boolean isEmpty()
System.out.println("sssd".isEmpty());//false
	System.out.println("".isEmpty());//true
	System.out.println(new String().isEmpty());//true

应用:字符串首字母大写

public static String firstUpperCase(String str){
	if(str==null||"".equals(str)){
		
		return str;
	}else{
		if(str.length()==1){
			return str.toUpperCase();
		}
		str=(str.substring(0,1)).toUpperCase()+str.substring(1);
		return str;
	}
}

2.StringBuffer类

由于String有不可更改的特性,因此提供StringBuffer类,方便字符串的修改,在String中使用"+"来进行字符串连接,但是这个操作在StringBuffer类中需要更改为append()方法:
String与StringBuffer无法相互转换,若想转换:
1.String -->StringBuffer:利用StringBuffer的构造方法或append方法
2.StringBuffer–>String :调用toString()方法

StringBuffer bs=new StringBuffer("java");	
	bs.append(" is").append(" best");//append方法的链式调用
	System.out.println(bs);//java is best
	String str=bs.toString()+"!!!";
	System.out.println(str);//java is best!!!

String与StringBuffer的相同点:都是字符集(见CharSequence)的接口子类
StringBuffer类特有的方法:
1.字符反转 reverse()

	System.out.println(bs.reverse());

2.删除指定范围的数据 delete(int start, int end)
包含start,不包含end
3.插入数据

public synchronized StringBuffer insert(int offset, 各种数据类型 b)
 
	StringBuffer bs=new StringBuffer("java");	
	System.out.println(bs.insert(0,new StringBuffer( "hi ")));//hi java
	System.out.println(bs.insert(0,"hello "));//hello hi java

面试题:请解释String、StringBuffer、StringBuilder的区别:
String是被final修饰的类,不能修改,不能被其他类继承,而StringBuffer、StringBuilder不是,可以修改
StringBuffer采用同步处理,属于线程安全操作(用于多线程项目),而StringBuilder是采用异步处理,属于线程不安全操作(常用于但线程项目)

2.Object类

Object类是所有类的父类,所有类都继承与Object,因此Object可以接收所有对象(基本数据类型、引用数据类型、接口、数组),一些基本方法也是由Object类定义的,因此在其子类中可以覆写

class Student{

    private String   name;
    private  int age;
public Student(int age,String name){
    this.age=age;
    this.name=name;
}
    @Override
    //覆写Object类中的toString方法
    public  String toString(){
        return "姓名" + this.name + "年龄" + age;
    }
}
class Person{}


public class ObjectTest{
public static void  main(String[] args){

//Person类没有覆写的toString方法,因此输出是默认的Object中的方法:对象名+地址
ObjectTest.fun(new Person());

//调用覆写过的toString方法
ObjectTest.fun(new Student(18,“name”));
}

//Object类接收对象(引用数据类型)
    public static void fun(Object object){
    System.out.println(object.toString());
    }
}
public static void main(String[] args) {
//        Object向上转型,接收int[]数组
        Object array1=new int[]{1,2,3,4};
//      需使用数组时需向下转型
        int[] array=(int[])array1;
        for (int temp:array){
            System.out.println(temp);
        }
    }

equals方法覆写
重写equals方法应遵循的规则:
1.自反性。对于任何非null的引用值x,x.equals(x)应返回true
2.对称性。对于任何非null的引用值x,y,当且仅当:y.equals(x)返回true时,x.equals(y)才应返回true
3.传递性。对于非null的引用值x,y,z,如果x.equals(y)返回true,且y.equals(z)返回true,那么x.equals(z)也应返回true.
4.一致性。对于任何非空引用值x,y假设对象上equals比较信息没有被修改,则多次调用x.equals(y)返回值需一致
5.对于任何非空引用值x.equals(null)应返回false

class Person {
    private String name;
    private int age;


    @Override
    public boolean equals(Object obj) {
      //若对象没有实例化
        if(obj==null){
            return false;
        }
        //若当前对象与传入对象的地址相等
        if(this==obj){
            return true;
        }
        //若传入对象的类与当前的Person类不属于同一个类
        if(!(obj instanceof Person)){
            return  false;
        }
//排除以上情况,判断传入对象的内容是否相等,相等则返回true
        Person person=(Person) obj;
        return this.name.equals(person.name) && this.age==person.age;
    }
}

Object接收接口

public static void main(String[] args) {
        IMesage im=new Mesage();//实现类向接口转型
        Object obj=im;//接口向Object转型
       im.getMesage();

       //Object接收接口的实现类,依然要强制类型转换
       Object object=new Mesage();
        ((Mesage) object).getMesage();
      
        //Object强制类型转化,向下转型
        IMesage temp=(IMesage)object;
        temp.getMesage();
    }

在Java中,利用Object接受一个基本数据类型是可编译可执行的,这是因为基本数据类型会被包装为一个包装类,JVM提供自动装箱机制,将基本数据类型包装,而包装类是Object的子类,因此编译执行提供。

**八种基本数据类型的包装类:**整体被分为对象型和数值型,数值型中,包含六种数值包装类
在这里插入图片描述
装箱:将基本数据类型变为包装类对象,可以用包装类的构造方法 或是JVM提供的直接装箱机制。
拆箱:将包装类中的基本数据类型取出,可以用包装类中提供的八种方法或是JVM提供的直接拆箱机制。

public static void main(String[] args) {
   //利用构造方法装箱
    Integer num=new Integer(12);
   //直接装箱
    Integer num2=12;
    //利用方法拆箱
    int num3=num.intValue();
        System.out.println(num);//12
        System.out.println(num2);//12
        System.out.println(num3);//12
       //直接拆箱
        System.out.println(++num);//13
    }

注:在Integer类中采用直接赋值法,[-128,127]区间内的数值创建的相应的对象是在IntegerCache.cache中产生的,若要创建相同的数值,不会另外创建对象,会复用存在这块区域中的已有的对象,若超出这个范围以外的对象,则会重新在堆内存空间上创建对象(无论是否有相同的数值).

 public static void main(String[] args) {
        Integer num1=12;
        Integer num2=12;
        Integer num3=153;
        Integer num4=153;
        Integer num5=new Integer(100);
        Integer num6=new Integer(100);
    
      //用==比较的是地址,用equals比较内容(数值)
        System.out.println(num1==(num2));//true
        System.out.println(num4==(num3));//false
     
        //若采用构造方法赋值装箱的方法,则是会在内存上开辟空间,用==比较的是地址,因此返回false
        System.out.println(num5==(num6));//false
    }

若将上述"=="判断改为equals则全为true
阿里编码规范:所有相同类型的包装类之间的值比较全部用equals方法进行比较
字符串与基本数据类型的转换:
1.String–>Integer包装类 Integer.parseInt(字符对象)
2.String–>Double包装类 Double.parseDouble(字符对象)
3.String–>Boolean包装类 Boolean.parseBoolean(字符对象)
将字符串转为数字时,若字符串中包含非数字字符,则转换会出错(NumberFormatException);而将字符串转为Boolean不会报此类错误

 public static void main(String[] args) {
        String string="123.123";
        String string1="123";
        String string2="true";
        String string3="false";
        System.out.println(Integer.parseInt(string1));
        System.out.println(Double.parseDouble(string));
        System.out.println(Boolean.parseBoolean(string2));//true
        System.out.println(Boolean.parseBoolean("trues"));//false

    }

4.基本数据类型–>字符串
①利用 数值+""加空白字符串的方式(会产生垃圾空间)
②利用String.valueOf(基本数据类型值);(不会产生垃圾空间)

	System.out.println(12+"");
	System.out.println(String.valueOf(12));

JDK新特性:
在JDK7以后的版本中,对于高位数字,中间可用_分割利于区分数位

        System.out.println(1000_000_00);//100000000

若想给int型变量直接赋以二进制表示的值时,在二进制数前加上0b即可

         int a=0b10010;
        System.out.println(a);//18

String类中+连接字符串的原理
使用+进行字符串连接时,会创建一个临时的StringBuilder对象,该对象调用append方法负责字符串的连接操作,然后再调用StringBuilder类的toString()方法装换成String对象。
若反复执行+操作,内存的开销是非常大的,因此在循环中需要反复连接字符串时,建议采用StringBuilder类的append()方法代替+。
String字符最大长度
在String类中,是使用一个字符数组维护字符序列的,因此String的最大长度取决于数组长度,因为在指定数组长度时可以使用byte、short、char、int而不能使用long,因此数组的最大长度是int类型的最大长度即0x7fffffff,这也是String能容纳的最大字符数量,在获得String对象长度时,返回值类型为int也是这个原因。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值