JDK常用接口和String类

JDK常用接口和String类,第1张

Java中的万物之母Object类:

全名称:java.lang.Object

Object类是所有类的默认父类,无法使用extends继承

Class声明的类都有一个父类Object类

1.因为Object类是所有类的父类,使用Object引用来接收所有的类型,参数最高统一化!!!

     void fun(Object obj){                    

     } 

   Object obj1 = new Person();

   Object obj2 = new String();

   Object obj3 = new Dog();

   

    Java中所有的类型都可以发生向上转型为Object类型!

 2.Object类中的所有方法子类全都继承了下来

    之所以System.out.println(任意的引用类型) => 默认都调用了toString()方法

  @Override
  public String toString() {
     return "Dog类的toString方法";
  }

  Dog dog = new Dog();
  System.out.println(dog);

//结果
 Dog类的toString方法
 equlas: 

3.Java中的引用数据类型比较要使用equlas方法 ,"==" 比较的是地址值!!! 

   "=="比较的是数值,而对于引用类型来将保存的是地址值

//Object类中的equals方法
public boolean equals(Object obj) {
        return (this == obj);
    }

此时我们想判断两个引用类型是否相等就需要覆写equals方法!!! 

public class Student {
     String name ;
     int age;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
                   //向上转型 O = student2,Object里面没有stu2独有的name和age
                     所以要向下转型!!!才能比较!!!
    public boolean equals(Object o) { 
        if(this == o){
            return true;
        }
            //防止发生类型转换异常 
        if(o instanceof Student){
            Student s1 = (Student) o;     //String类型可以直接调用父类的equals方法比较
            return this.age == s1.age && this.name.equals(s1.name);
        }
          // 比较的都不是一个东西
             学生和狗不能比较!
        return false;
    }

}
public class Test {
       static String s1 = "wu";
       static String s2 = "wu";

    public static void main(String[] args) {
        Student student1 = new Student("张三",18);
        Student student2 = new Student("张三",18);
        System.out.println(student1.equals(student2));

        System.out.println(s1.equals(s2));
    }

}

//结果
  true
  true

 3.JDK对Object类做了扩展

    Object类可以接收所以引用数据类型的对象(接口,数组,类)

   // 接口引用

  ITest i1 = new TestImpl();

  //整形数组引用

  int[] data = new int[10];

 //只有是引用类型,都可以使用Object来接收

 Object obj1 = i1;

 Object obj2 = data;

因此在Java中,若一个方法参数或者返回值类型是Object类型,说明该参数或返回值可以是任意引用数据类型(数组,类,接口)

除了8大基本类型没法用Object类来接收,所以类型都可以用Object来接收.

包装类应运而生  


Comparable: 

java.lang.Comparable:当一个类实现了Comparale接口,表示该类具备了可比较的能力!!!

 由于Person这个类型是自定义类型,对于编译器来说,不像int类型大小一目了然

 到底哪个Person对象大,哪个Person对象小,编译器无从得知.

 要让Person具备比较能力,就需要让Person类实现Compareale接口,覆写抽象方法compareTo

                  //当一个类实现了Comparable接口,即这个类拥有了比较能力
public class Person implements Comparable{

    String name;
    int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    public int compareTo(Object o) {

        if(this == o){
            return 0;
        }

        if(o instanceof Person){
            Person person = (Person) o;
                  //按升序排序 >0
                  //按降序排序<0,person.age - this.age即可
            return this.age - person.age;
        }
        throw new IllegalArgumentException("不是Person类型,无法比较!");
    }
}
public class ComparableTest {
    public static void sort(Comparable[] arr) {
        for (int i = 0; i < arr.length - 1; i++) {
            for (int j = 0; j < arr.length - i - 1; j++) {
//                if (arr[j] > arr[j + 1]) // swap
                if (arr[j].compareTo(arr[j + 1]) > 0) {
                    // 前一个大于后一个,交换j和j + 1
                    Comparable temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }
    }

    public static void main(String[] args) {
        //people是一个Person类型的数组,创建了三个Person类型的变量
        Person person = new Person("z",100);
        Person person1 = new Person("f",18);
        Person[] people = new Person[]{
                //arr[0]
                new Person("张三",17),
                //arr[1]
                new Person("李四",18)
        };
        Arrays.sort(people);
        System.out.println(Arrays.toString(people));
    }

}

Cloneable:

  java.lang.Cloneable  克隆接口

  

  什么是克隆接口?

    原对象和新产生的对象是两个独立的对象,新产生的对象是通过原对象"拷贝"而来,属性值和原对象完全一致.

  要让一个类具备可复制能力,实现Cloneable接口,覆写clone方法

当我让Animal这个类实现Cloneable这个接口时并没有强制要求覆写方法,这是为什莫哪?

  答:类似Cloneable接口,把这种接口称之为"标记"接口,这个接口本身没有任何抽象方法,只有打上这个标记的子类才具备克隆的能力!

      JVM在运行时会检查所有实现了Cloneable接口的子类,赋予其克隆的能力.

      clone方法是Object提供的方法.

public class Animal implements Cloneable{

    String name;

    public Animal(String name) {
        this.name = name;
    }
}
public class Animal implements Cloneable{

    String name;

    public Animal(String name) {
        this.name = name;
    }

    public Animal clone(){
        Animal newAnimal = null;
        try {
            newAnimal = (Animal) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return newAnimal;
    }
}

 animal和clone之间没有任何关系,只是属性值相等

clone的产生是依赖于animal

public class CloneTest {
    
    public static void main(String[] args) {
        Animal animal = new Animal("zs");
        Animal clone = animal.clone();
        System.out.println(clone.name);
    }
}

深浅拷贝: 

  只需要了解概念即可

   浅拷贝:就是克隆的对象和原对象肚子里包含的其他对象是一个东西

   深拷贝:就是克隆对象和原对象肚子里包含的其他对象也是克隆出来的 


 在Java中产生一个新对象有两种方式:

  1.最常见的是通过构造方法产生对象

 new 类(); 当有new关键字,就会在堆上开辟相应属性的空间,并给属性赋默认值

  2.通过clone();产生对象,调用clone时,JVM会开辟与原对象内存大小完全相同的新空间,并将原对象的属性值复制一份.(不推荐)


String: 
public final class String
    implements java.io.Serializable, Comparable, CharSequence {

 为什莫String类被find修饰?

答:被find修饰的类无法继承,String类不存在子类,这样就可以保证大家用到的String类仅此一个,大家都相同.

假设String允许继承,每个人都可以继承String类,修改它的方法等实现,继承和覆写带来灵活性的同时,也会带来子类行为不一致的问题(每个人的String功能不一致).

1.创建字符串的四种方式(最常用1and2):

  (1).直接赋值

  String str1 = "hello word"; //字符串字面量,也是字符串对象

  (2).通过构造方法产生对象

  String str2 = new String("hello word");

  (3).通过字符数组产生对象

  char[] data = new char[] {"a","b","c"}

  String str = new String(data);

  (4).通过String的静态方法valueOf(任意数据类型) ->转为字符串

  String str = String.valueOf(10); 

String str1 = "hello";

String str2 = str1;

在栈中:str1,str2 同时指向了堆中的"hello"

public class StringTest {
    
  //"Hello"也是字符串的字面量,是一个新的字符串对象,str2实际上指向了新的字符串对象"Hello"
  // str1仍旧指向"hello word"
    public static void main(String[] args) {
        String str1 = "hello word";
        String str2 = str1;
        str2 = "Hello";
        System.out.println(str1);
    }
}

 

2.字符串比较是否相等 

//结果:true 说明了指向了同一块地址
public static void main(String[] args) {
        String str1 = "hello word";
        String str2 = "hello word";
        System.out.println(str1 == str2);
    }
//结果:false  equals是区分大小写的比较
public static void main(String[] args) {
        String str1 = "hello word";
        String str2 = "Hello word";
        System.out.println(str1.equals(str2));
    }

//结果:true  equalsIgnoreCase是不区分大小写的比较
public static void main(String[] args) {
        String str1 = "hello word";
        String str2 = "Hello word";
        System.out.println(str1.equalsIgnoreCase(str2));
    }
//这个变量由用户从浏览器输入
 String useName = null;
//有可能引发空指针异常,牵扯到用户输入就要做判空处理
 System.out.println(useName.equals("zs"));
//这样就可以避免useName为Null的问题
 System.out.println("zs".equals(useName));

3.字符串常量池  

 使用直接赋值法产生字符串对象时,JVM会维护一个常量池,若该对象在常量池中不存在,则产生一个新的字符串对象加入字符串常量池中.

当继续使用直接赋值法产生字符串对象时,JVM发现该引用指向的内容在常量池中已经存在了,就不再创建新对象,而是引用已有对象.

        String str1 = "hello"; //字符串常量第一次出现,JVM发现常量池中不存在,就把该对象加入到常量池
        String str2 = "hello";
        String str3 = "hello";
        System.out.println(str1 == str2);//true
        System.out.println(str2 == str3);//true

有new就有新空间,这三行代码产生四个字符串对象,其中一个在常量池,其余三个在堆

        //三个引用指向了三个不同的对象
     String str1 = new String("hello");//代码从右向左执行碰到"hello"就把它加入到常量池中
     String str2 = new String("hello");
     String str3 = new String("hello");

     System.out.println(str1 == str2);//false
     System.out.println(str2 == str3);//false

常量池这样设计的原因是什么?

答:所谓的"池"都是类似的思想

    共享设计模式-节省空间(内存是一个非常紧张的资源),字符串产生之后大部分都用来输出处理,打印内容,"hello"为啥不整一个就好

数据库的连接池 线程池都是类似的思想!!!


 String的intern方法

public native String intern();//这个方法有一个返回值

调用intern方法会将当前字符串引用指向的对象保存到字符串常量池中.

a.若常量池已经存在了该对象,就不会产生新对象,返回常量池中的String对象.

b.若当前常量池不存在该对象,就将该对象入池,返回入池后的地址, 

  String str1 = new String("hello");
 //常量池中已经有了"hello",不在产生新的对象返回常量池中的对象(但是没有接收)
  str1.intern(); 
  String str2 = "hello";
  System.out.println(str1 == str2);//false
String str1 = new String("hello");
str1 = str1.intern(); //接收了常量池中的字符串对象地址
String str2 = "hello";
System.out.println(str1 == str2); //true

     char[] data = new char[]{'a','b','c'};
     String str1 = new String(data);//这是字符数组,不会入常量池,将字符数组转化为String
     str1.intern();   //并没有赋值,intern将"abc"放入到了常量池
     String str2 = "abc";
     System.out.println(str1 == str2); //true

 4.String的不可变性

 字符串的不可变指的是字符串对象的内容不可变,而不是字符串引用不能变!

 这里的不可变指的是"hello" "word" "helloword" "!!!"

 "helloword!!!" 这些字符串对象一旦声明后就无法修改内容 

        String str = "hello";
        str = str + "word";
        str += "!!!";
        System.out.println(str);

 

为什么字符串的对象无法修改内容,而其它对象可以修改内容?

 答:字符串底层是被find修饰的char类型的数组

 

 5.如何修改字符串的内容

    a.在运行时通过反射破话value数组的封装(不推荐)

    b.更换使用StringBuilder或StringBuffer类(已经不是一个类型了)

StringBuilder:只会创建一个对象,若要频繁进行字符串的拼接使用StringBuilder的append方法 

        StringBuilder sb = new StringBuilder();
        sb.append("hello");
        sb.append("word");
        sb.append("!!!");
        System.out.println(sb);

 StringBuilder类的具体使用:

   a.StringBuilder类和String类是两个独立的类,StringBuilder类是为了解决字符串的拼接产生的.

   b.因为String的对象内容无法修改,为了方便字符串的拼接 *** 作,产生了StringBuilder类,String Builder类的对象是可以修改的

 String和StringBuilder之间的互相转换!!!

//String转换为StringBuilder

//1.使用StringBuilder的构造方法   
StringBuilder sb = new StringBuilder("123");
//2.使用append方法
        sb.append("hello");
        sb.append("word");
        sb.append("!!!");

//StringBuilder转换为String
   String str = sb.toString

1.字符串反转 *** 作revers(); 

 StringBuilder sb = new StringBuilder();
        sb.append("hello");
        sb.append("word");
        System.out.println(sb.reverse());//drowolleh

 2.删除指定范围数据 delete(int start,int end):[start,end)

 StringBuilder sb = new StringBuilder();
        sb.append("hello");
        sb.append("word");
        System.out.println(sb.delete(5,9));//hello

 3.插入 *** 作 insert(int start,各种数据类型):插入后新数值的索引为start

  StringBuilder sb = new StringBuilder();
        sb.append("hello");
        sb.append("word");
        System.out.println(sb.insert(5,10));//hello10word

4.将字符数组的部分内容转换为字符串 

        char[] ch = new char[]{'a','b','c'};
                      //字符数组引用,起始位置,转换个数
        String s = new String(ch,1,2);
        System.out.println(s);//"bc"

5.取出字符串中指定索引字符 

        String str = "hello";
        System.out.println(str.charAt(1));//e

6.将字符串中的内容转为字符数组String -> char[] 

        //String对象不可变!!!内容改不了!!!
        String str = "hello";
       //此时产生了一个新的字符数组,将字符串的内容复制过去
        char[] data = str.toCharArray();
        data[0] = 'H';
        System.out.println(str); //hello

 判断一个字符串是否由纯数字组成!!!

"123" = true

"123a" = false

        String str1 = "123";
        String str2 = "123a";
        System.out.println(isNum(str1));
        System.out.println(isNum(str2)); 
    
    public static boolean isNum(String str){
        char[] chars = str.toCharArray();
        for(char s : chars){
            if(s < '0' || s > '9'){
                return false;
            }
        }
        return true;
    }

7.字符串和字节的相互转换 (将字符串保存到文件中或是通过网络传输都要用到字节数组)

String->byte[] 

        String str1 = "中国你好";
        //将字符串以默认字节数组形式返回
        byte[] data = str1.getBytes();
        //按照指定的编码格式转为字节数组
        byte[] gbks = str1.getBytes("gbk");
        System.out.println(Arrays.toString(data));
        System.out.println(Arrays.toString(gbks));

在UTF-8编码下一个汉字占3个字节
在gbk编码下,一个汉字占2个字节
[-28, -72, -83, -27, -101, -67, -28, -67, -96, -27, -91, -67]
[-42, -48, -71, -6, -60, -29, -70, -61]

byte[]->String 

       byte[] b = new byte[]{97,98,99};
        String s = new String(b);
        System.out.println(s); //abc

8.字符串的查找 

        String str1 = "helloword";
        System.out.println(str1.contains("wo"));//true
        String str1 = "helloword";
       //查看字符串是否以指定的字符开头
        System.out.println(str1.startsWith("hello"));
        String str1 = "helloword";
     //查看字符串是否以指定的字符串结尾
        System.out.println(str1.endsWith("word"));

9.字符串的替换 *** 作 

String类所有针对字符串的 *** 作都不会改变原字符串!!!字符串的不可变性!!!

        String str1 = "helloworld";
    //将字符串中所有l替换为_
        System.out.println(str1.replaceAll("l","_"));//he__owor_d
   //将字符串中第一个l替换为_
        System.out.println(str1.replaceFirst("l","_"));//he_loworld
        System.out.println(str1);//helloworld

10.字符串的拆分 *** 作 

        String str1 = "hello word hello rocker";
        String[] s = str1.split(" ");
        String[] s1 = str1.split(" ", 2);
        System.out.println(Arrays.toString(s));//[hello, word, hello, rocker]
        System.out.println(Arrays.toString(s1));//[hello, word hello rocker]

若字符串中没有指定的子串就返回原数组

a.你的拆分格式不存在

b.你的这个格式是个特殊字符,需要转义处理"\\."

        String str = "192.168.1.1";
        String[] data = str.split("\.");
        System.out.println(Arrays.toString(data));//[192, 168, 1, 1]

11.字符串的截取 

  String str = "helloword";
//产生一个新的字符串,原字符串不变
  System.out.println(str.substring(0,5));

 public String trim():去掉字符串中的左右空格,保留中间空格

 public String toUpperCase():字符串转大写

 public String toLowerCase():字符串转小写

 public int length():取得字符串长度

 public boolean isEmpty():判断是否为空字符串,但不是null,而是长度为0

        String str = " hello word ";
        System.out.println(str.trim());//hello word
        System.out.println(str.toUpperCase());// HELLO WORD 
        System.out.println("HELLO".toLowerCase());//hello
        System.out.println("HELLO".length());//5

 isEmpty():成员方法,只能判断字符串的长度是否为0,不能判断null

写一个方法将字符串的首字母大写处理 !!!

        String str = "hello";
        System.out.println(firstUpper(str));

 public static String firstUpper(String str){
        //1.判空处理
        if(str == null || str.isEmpty()){
            return null;
        }
        //边界条件
        if(str.length() == 1){
            return str.toUpperCase();
        }
        //此时str长度大于1
        //截取+大写 *** 作
        return str.substring(0,1).toUpperCase() + str.substring(1);
    }

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/883717.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-14
下一篇 2022-05-14

发表评论

登录后才能评论

评论列表(0条)

保存