zoukankan      html  css  js  c++  java
  • JAVA核心技术I---JAVA基础知识(不可变对象和字符串)

    一:不可变对象

    不可变对象(Immutable Object)
    –一旦创建,这个对象(状态/值)不能被更改了–其内在的成员变量的值就不能修改了。
    –典型的不可变对象
    • 八个基本型别的包装类的对象String,BigInteger和BigDecimal等的对象
    可变对象(Mutable Object)
    –普通对象

    (一)普通对象:可修改值

            //普通对象
            genobj go = new genobj();
            genobj go2 = go;    //两个指针指向一个对象
            
            System.out.println(go.getnumber());
            System.out.println(go2.getnumber());
            go2.setnumber(16);
            
            System.out.println(go.getnumber());
            System.out.println(go2.getnumber());
            if(go==go2) {
                System.out.println("obj1==obj2");
            }
    12
    12
    16
    16
    obj1==obj2

    (二)不可变对象,不允许修改值

            //8个基本包装类
            Integer I1=12;
            Integer I2=I1;
            
            System.out.println(I1);
            System.out.println(I2);
            
            if(I1==I2) {
                System.out.println("I1==I2");
            }
            
            I2 = 13;    //修改值
            System.out.println(I1);
            System.out.println(I2);
            if(I1==I2) {
                System.out.println("I1==I2");
            }else {
                System.out.println("I1!=I2");
            }
            //发现原来的内存地址的值I1并没有修改,还是12,只是修改了对象指针I2的指向,指向13的内存
    12
    12
    I1==I2
    12
    13
    I1!=I2

    (三)在函数参数中体现不可变对象

            String a = new String("abc");
            String b = a;
            System.out.println(b);
            a = "def";
            System.out.println(b);
    abc
    abc
    View Code

    函数修改

        public static void main(String[] args) {
            String a = new String("abc");
            System.out.println(a);
            change(a);
            System.out.println(a);
        }
        
        public static void change(String b) {
            b = "def";
        }
    abc
    abc
    View Code

    不可变对象,也是传指针(引用)
    由于不可变,临时变量指向新内存,外部实参的指针不改动

    (四)如何创建一个不可变对象

    –immutable对象是不可改变,有改变,请clone/new一个对象进行修改
    –所有的属性都是final和private的
    –不提供setter方法
    –类是final的,或者所有的方法都是final
    –类中包含mutable对象,那么返回拷贝需要深度clone

    (五)不可变对象优缺点

    不可变对象(Immutable Object)
    优点
    –只读,线程安全
    –并发读,提高性能
    –可以重复使用
    缺点
    –制造垃圾,浪费

    二:字符串

    字符串是Java使用最多的类,是一种典型的不可变对象
    String定义有2种
    –String a = “abc”; //常量赋值,栈分配内存
    –String b = new String(“abc”); //new对象,堆分配内存
    字符串内容比较:equals方法
    是否指向同一个对象:指针比较==
    Java 常量池(Constant Pool)
    –保存在编译期间就已经确定的数据
    –是一块特殊的内存
    –相同的常量字符串只存储一份,节省内存,共享(栈中,不是堆中)

    (一)字符串加法

    String a=“abc”;
    a = a+“def”; //由于String不可修改,效率差。

    使用StringBuffer/StringBuilder类的append方法进行修改(原地修改,扩张StringBuffer/StringBuilder 的对象都是可变对象
    StringBuffer(同步,线程安全,修改快速),
    StringBuilder(不同步,线程不安全,修改更快)
            int n = 50000;
            Calendar t1 = Calendar.getInstance();
            String a = new String();
            for(int i=0;i<n;i++)
            {
                a = a + i + ",";
            }
            System.out.println(Calendar.getInstance().getTimeInMillis() - t1.getTimeInMillis());
            
            Calendar t2 = Calendar.getInstance();
            StringBuffer b = new StringBuffer("");
            for(int i=0;i<n;i++)
            {
                b.append(i);
                b.append(",");
            }
            System.out.println(Calendar.getInstance().getTimeInMillis() - t2.getTimeInMillis());
            
            Calendar t3 = Calendar.getInstance();
            StringBuilder c = new StringBuilder("");
            for(int i=0;i<n;i++)
            {
                c.append(i);
                c.append(",");
            }
            System.out.println(Calendar.getInstance().getTimeInMillis() - t3.getTimeInMillis());
    20017
    50
    35
    字符串append操作速度:StringBuilder>StringBuffer>String

    (二)字符串函数传递

        public static void changeValue(int a)
        {
            a = 10;
        }
        public static void changeValue(String s1)
        {
            s1 = "def";
        }
        public static void changeValue(StringBuffer s1)
        {
            s1.append("def");
        }
        public static void main(String[] args) {
            int a = 5;        //基本类型
            String b = "abc"; //不可变对象
            StringBuffer c = new StringBuffer("abc"); //可变对象
            changeValue(a);  //基本类型,传值
            changeValue(b);  //不可变对象,传引用,但是不允许修改
            changeValue(c);  //可变对象,传引用,可以修改值
            System.out.println(a);
            System.out.println(b);
            System.out.println(c);
        }

    三:StringBuffer和StringBuilder比较

    StringBuffer(字符串加减,同步,性能好)
    StringBuilder(字符串加减,不同步,性能更好)
    StringBuffer/StringBuilder: 方法一样,区别在同步
    –append/insert/delete/replace/substring –length 字符串实际大小,capacity字符串占用空间大小  空间大小为实际大小加一,再两倍
    –trimToSize(): 去除空隙,将字符串存储压缩到实际大小
    –如有大量append,事先预估大小,再调用相应构造函数
  • 相关阅读:
    golang 数据结构 优先队列(堆)
    leetcode刷题笔记5210题 球会落何处
    leetcode刷题笔记5638题 吃苹果的最大数目
    leetcode刷题笔记5637题 判断字符串的两半是否相似
    剑指 Offer 28. 对称的二叉树
    剑指 Offer 27. 二叉树的镜像
    剑指 Offer 26. 树的子结构
    剑指 Offer 25. 合并两个排序的链表
    剑指 Offer 24. 反转链表
    剑指 Offer 22. 链表中倒数第k个节点
  • 原文地址:https://www.cnblogs.com/ssyfj/p/10196488.html
Copyright © 2011-2022 走看看