zoukankan      html  css  js  c++  java
  • 【Java】String类、Object类、包装类总结

    String类

        "=="本身是进行数值比较的,如果现在用于对象比较,那么所比较的就应该是两个对象所保存的内存地址数值比较,而并没有比较对象的内容。

        String str1 = "hello";

        String str2 = new String("hello");

        System.out.println(str1==str2);    //输出结果是false


        第一行代码,首先创建一个内容为“hello”的字符串实例对象,

        第二行代码,新new出来一个字符串对象,在堆内存中新开辟一个空间,在栈内存中str2指向这个新的地址,所以str1与str2是指向不同地址的两个引用;

        String str1 = “hello”;

        String str2 =  “hello”;

        String str3 =  “hello”;

        System.out.println(str1==str2);  //true

        System.out.println(str1==str3);  //true

        System.out.println(str2==str3);  //true

        这是因为,通过String str1 = “hello”;直接赋值创建的对象,JVM会将该对象保存在对象池中,下次再直接赋值创建对象,如果对象池中有相同的内容,则不再堆内存重新生成对象,直接让它们指向对象池中的同一个对象。

        

        String str1 = new String("hello") ;
        String str2 = "hello" ;
        System.out.println(str1 == str2); // false

        第一行代码字符串的创建并没有使“hello”入池,在String中提供了intern( )方法来让我们手动入池

        String str1 = new String("hello") .intern();//让"hello"入池并返回String;
        String str2 = "hello" ;
        System.out.println(str1 == str2); // true

        在Java中,String类提供了equals(String str)方法来进行字符串的比较,它比较的是两字符串的内容,那么显然

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

        System.out.println(str1.equals(str2)); // true 

        System.out.println("hello".equals(str2)); // true 字符串常量是String的匿名对象

        
        String的两种创建方式
        通过构造方法创建和直接赋值创建;
        构造方法:会开辟两块堆内存空间,其中一块成为垃圾空间,不会自动保存在对象池中,可以使用
    intern()方法手工入池。
        直接赋值:只会开辟一块堆内存空间,并且该字符串对象可以自动保存在对象池中以供下次使用。    

        因此建议使用直接赋值。

        

        字符串常量不可改变:

        我们在编程中会遇到这种情况:

        String str = "hello";

        str = str+" world";

        System.out.println(str);

        结果输出:hello world

        不是说字符串常量不可改变吗?为什么还会打印出helloworld? 看一下String的内存图

        

        一开始呢,str的确是“hello”,不过在执行 str+" world"; 的时候,在堆内存中又生成了两块空间,一个是“ world”,还有一个两字符串链接后的空间“hello world”,最后str的指向发生了变化,也就是说str一开始所指向的堆内存“hello”并没有改变,而是它所指向的地址发生了变化。

        

        String类中常用的方法:

        public char charAt(int index) 获取索引位置的字符

        public char[] toCharArray()    将字符串变为字符数组返回

        public byte[] getBytes()     将字符串以字节数组返回

        public int compareTo(String anotherString)    比较两字符串的大小,返回差值

        1. 相等:返回0.
        2. 小于:返回内容小于0.

        3. 大于:返回内容大于0。

        public boolean contains(CharSequence) ;    //判断一个字符串是否在该字符串内

        public int indexOf(Stirng str) ;    //从头查找str是否在,存在返回第一个找到的下标,找不到返回-1

        public int indexOf(Stirng str ,int fromIndex);     //从指定位置开始查找

        public int lastIndexOf(Stirng str);     //从后向前查找

        public int lastIndexOf(Stirng str ,int fromIndex);     //从指定位置从后向前查找

        public String replaceAll(String regex, String replacement);    //替换所有指定内容

        String str = "helloworld" ;
        System.out.println(str.replaceAll("l", "_"));    //将所有"l"替换为"_"

        public String[ ] split(String regex);    //将字符串按照给定字符串regex分割为字符串数组返回

        public String[ ] split(String regex, int limit);    //数组的长度的极限是limit

        public String subString(int index);    //从指定位置开始截取到尾部

        public String subString(int begin, int end);    //截取其中一段  

       

        在数组中获取长度是 .length  length是数组的属性

        在String中获取长度是 .length()  是Sting类的方法


    StringBuffer类

        任何的字符串常量都是String对象,而且String的常量一旦声明不可改变,如果改变对象内容,改变的是其引用的指向而已。

        通常来讲String的操作比较简单,但是由于String的不可更改特性,为了方便字符串的修改,提供StringBuffer类。在String中使用"+"来进行字符串连接,但是这个操作在StringBuffer类中需要更改为append()方法;

        StringBuffer sb = new StringBuffer();
        sb.append("Hello").append("World");

        String和StringBuffer最大的区别在于:String的内容无法修改,而StringBuffer的内容可以修改。频繁修改字符串的情况考虑使用StingBuffer。

        StringBuffer类的常见方法

        public synchronized StringBuffer reverse();    //字符串反转

        public synchronized StringBuffer delete(int start, int end);    //删除指定范围的数据

        public synchronized StringBuffer insert(int offset, 各种数据类型 b);    //插入数据

    面试题:请解释String、StringBuffer、StringBuilder的区别:
    1. String的内容不可修改,StringBuffer与StringBuilder的内容可以修改.

    2. StringBuffer采用同步处理,属于线程安全操作;而StringBuilder采用异步处理,属于线程不安全操作。


    Object类

        Object是Java默认提供的一个类。Java里面除了Object类,所有的类都是存在继承关系的。默认会继承Object父类。

    即,所有类的对象都可以使用Object进行接收。

        在输出对象时,默认输出的是一个地址编码默认Object类提供的toString()方法只能够得到一个对象的地址(而这是所有对象都共同具备

    的特征)。如若觉得默认给出的toString()方法功能不足,就在需要的子类上覆写toString()方法。

    class Person{
    private String name ;
    private int age ;
    public Person(String name, int age) {
    this.age = age ;
    this.name = name ;
    }
    @Override
    public String toString() {
    return "姓名:"+this.name+",年龄:"+this.age ;
    }
    }
    public class Test {
    public static void main(String[] args) {
    fun(new Person("yuisama",25) );
    fun("Hello");
    }
    public static void fun(Object obj) {
    System.out.println(obj.toString()); // 默认输出对象调用的就是toString()方法
    }
    }


    对象比较

        String类对象的比较使用的是equals()方法,实际上String类的equals()方法就是覆写的Object类中的equals()方法。

        而我们自己定义的Person类如果没有覆写equals(Object obj),那么它只是判断传入的对象是否是该对象本身,若我们想通过该类的一些属性来比较判断它们是否相同,那我们就得自己覆写该方法;

    接收引用数据类型
        在之前已经分析了Object可以接收任意的对象,因为Object是所有类的父类,但是Obejct并不局限于此,它可以
    接收所有数据类型,包括:类、数组、接口。


    包装类

        Object类可以接收所有引用数据类型。然而在Java中,数据类型分为基本数据类型和引用数据类型,那么基本数据类型如何处理呢?


    包装类基本原理

        包装类就是将基本数据类型封装到类中。

        Java为了方便开发,专门提供了包装类的使用,而对于包装类的使用,提供了两种类型。
            对象型(Object的直接子类):Boolean、Character(char);

            数值型(Number的直接子类):Byte、Double、Short、Long、Integer(int)、Float;

    装箱与拆箱
        在包装类与基本数据类型处理之中存在有两个概念:
        装箱:将基本数据类型变为包装类对象,利用每一个包装类提供的构造方法实现装箱处理。

        拆箱:将包装类中包装的基本数据类型取出。利用Number类中提供的六种方法。

        Integer num = new Integer(55) ; // 装箱
        int data = num.intValue() ; // 拆箱
        System.out.println(data);

        在JDK1.5之后,提供了自动拆装箱的机制,最为重要的是,由于此类机制的
        存在,可以直接利用包装类的对象进行各种数学计算。
        范例:自动装箱与拆箱处理

        // 自动装箱
        Integer x = 55 ;
        // 可以直接利用包装类对象操作
        System.out.println(++x * 5 );

    说明:对于 Integer var = ? 在-128 至 127 范围内的赋值,Integer 对象是在IntegerCache.cache 产生,会复用
    已有对象,这个区间内的 Integer 值可以直接使用==进行判断,但是这个区间之外的所有数据,都会在堆上产

    生,并不会复用已有对象,这是一个大坑,推荐使用 equals 方法进行判断。

    Integer num1 = 10;
    Integer num2 = 10;

    System.out.println(num1==num2);    //true

    Integer num1 = 128;
    Integer num2 = 128;
    System.out.println(num1==num2);    //false

            数值在-128~127之间的数,对象会在IntegerCache.cache 产生,会复用已有对象,所以第一个代码返回结果为true

        而数值不在这个范围内,就会在堆上产生新的对象,所以结果返回false

    阿里编码规范:使用int还是Integer?

    关于基本数据类型与包装数据类型的使用标准如下:

        1) 【强制】所有的 POJO 类属性必须使用包装数据类型。

        2) 【强制】RPC 方法的返回值和参数必须使用包装数据类型。 

        3) 【推荐】所有的局部变量使用基本数据类型。


    字符串与基本数据类型转换

    1. String变为int 类型(Integer类):public static int parseInt(String s) throws NumberFormatException
    2. String变为double类型(Double类):public static double parseDouble(String s) throws NumberFormatException
    3. String变为Boolean类型(Boolean类):public static boolean parseBoolean(String s)

    那么如果现在要将基本数据类型变为字符串
    1. 任何数据类型使用了"+"连接空白字符串就变为了字符串类型。
    2. 使用String类中提供的valueOf()方法,此方法不产生垃圾。

    String str = String.valueOf(100) ;



  • 相关阅读:
    简单马周游问题1152siicly
    Sicily 1155. Can I Post the lette
    POJ 1007
    给定2个大小分别为n, m的整数集合,分别存放在两个数组中 int A[n],B[m],输出两个集合的交集。
    算法1--
    GAN
    为什么ConcurrentHashMap是弱一致的
    手写HASHMAP
    千万级规模高性能、高并发的网络架构经验分享
    Web 通信 之 长连接、长轮询(转)
  • 原文地址:https://www.cnblogs.com/yongtaochang/p/13615353.html
Copyright © 2011-2022 走看看