java中常用类String见解

字符串操作是计算机程序设计中最常见的行为,所以掌握好String类的使用很重要。
String是一个final修饰的类,所以它是不可以被继承的,String对象是不可以变的,也就是说创建了一个对象以后,那么这个对象的长度是不可以修改的,而我们平时进行的字符串拼接、修改等操作都只是拷贝了它的引用,并不会改变原字符串的大小。
下面通过一段代码来了解一个String的创建对象;

       //创建String对象
        String str="yxc";
        String str2="yxc";
        String str1=new String("yxc");
        String str3=new String("yxc");
        System.out.println(str1==str3);
        System.out.println(str==str2);
        System.out.println(str==str1);

返回结果:
false
true
false
可能初学者有点困惑,那么下面通过图解来分析(还在寻找合适的画图软件,暂时手动画:)

在这里插入图片描述 首先对于str和str2来说,在常量池创建一个“yxc”常量,然后将它的地址给str,str2.
而str1和str3来说,首先使用new关键字在堆内存在创建一个对象,然后把堆内存的引用传给str1和str3 而后面传进来的参数是常量池中的引用。
再看下面的一段代码:

       String str1="hello world";
       String str2=str1.substring(2);
       System.out.println(str2);
       System.out.println(str1);

运行结果:
llo world
hello world
对于substring函数是截取字符串,后面的参数表示索引,从哪开始截取,这个我们后续再说,这里想要说的是,我们修改了通过str.substring(),但是原来的字符串str1其实根本没有改变,这就是字符串的不可变成,其实这种设计正是我们需要的,很多时候我们不希望修改原来的值。对于字符串中的函数通常都是如果操作成功返回一个新的对象,如果没有就返回原来的对象,这样节约了很多空间,怎么说的,看下面代码:

       tring str1="hello world";
       String str2=str1.substring(0);
       String str3=str1.substring(1);
       System.out.println(str1==str3);
       System.out.println(str1==str2);

结果返回:
false
true
对吧,这就说明了返回原对象和返回一个新的对象。字符窜中很多方法都是这样设计的,下面我们学习一下String中常用的方法。通过一段代码加上详细的注释直接搞定:

package com.yxc.string;
//测试String中常见的方法
public class StringProject {
    public static void main(String[] args) {
        System.out.println("其它数据类型转为String类型测试");
       //将其它数据类型转为字符串
        double d=123456.7;
        String str1 = String.valueOf(d);
        System.out.println(str1);   //123456.7
        //其它的数据类型都是一样的,只是换一下数据类型就可以
        //这里还有一种稍微特殊一点的
        char[] c=new char[]{'a','y','z','w'};
        //从下标为1开始截取,截取两个,然后将这两个转换为字符串
        String str2 = String.valueOf(c, 1, 2);
        System.out.println(str2);    //yz


        System.out.println("字符串转为其它数据类型");
        String str3="3121";
        int j = Integer.parseInt(str3);
        System.out.println(j);   //3121
        //其它的数据类型类似

        System.out.println("计算字符串长度");
        System.out.println(str3.length());//注意length是方法,不是数据中的属性

        System.out.println("字符串开头和结尾 返回boolean类型");
        String str4="jamesy";
        System.out.println(str4.startsWith("j"));//true
        System.out.println(str4.endsWith("k"));   //false

        System.out.println("索引");
        /**
         * 索引元素,如果存在返回字符串所在的下标,下标从零开始 如果不存在返回-1
         * 如果是从后面索引,如果找到也是返回下标吗,而是是从前往后的下标(注意)
         * 如果有相同的就返回第一个查找的的
         */
        String str5="I will give you some color to see see";
        System.out.println(str5.indexOf("give"));
        System.out.println(str5.lastIndexOf("give")); //返回结果也是7
        System.out.println(str5.indexOf("see"));           //30
        System.out.println(str5.lastIndexOf("see"));  //34
        //所以索引see的时候肯定是不一样的,从前往后索引和从后索引第一个出现的see的位置不一样

        System.out.println("忽略大小写比较");
        System.out.println("hello".equalsIgnoreCase("HeLLo"));//true

        System.out.println("根据位置索引值");
        System.out.println("asdfg".charAt(3)); //f

        System.out.println("将字符串转为字符数组");
        String str6="just do it";
        char[] chars = str6.toCharArray();
        for(int i=0;i<chars.length;i++){
            System.out.print(chars[i]);
        }

        System.out.println("截取字符串");
        String str7="justsoso";
        String substring = str7.substring(2, 5);  //sts 2截取到5
        System.out.println(substring);

        System.out.println("连接字符串");
        System.out.println("yxc".concat("xin"));

        System.out.println("将字符串转为字节数组");
        String str8="yuio";
        byte[] bytes = str8.getBytes();
        for(int i=0;i<bytes.length;i++){
            System.out.print(bytes[i]+" ");  //121 117 105 111
        }

        System.out.println("是否包含某一个对象");
        String str9="yangxinchun";
        String str10="xin";
        System.out.println(str9.contains(str10));  //true

    }
}

String类确实经常使用,但是有些情况使用它的效率会很低,看下面一段代码:

        long startTime = System.currentTimeMillis();
        String str="yxc";
        for(int i=1;i<100000;i++){
            str=str+i;
        }
        long endTime=System.currentTimeMillis();
        System.out.println(endTime-startTime);

在我机器上硬是跑了40977ms,(我测试了下10000000,几分钟没跑出来我就关闭了)这才十万级别,而且更可怕的是上面的操作会产生十万多个对象。这样的效率太低而且消耗资源,因为对象的创建是很耗资源的,只是为了拼接一个字符上去就要产生一个新的对象,这样的设计显然不和实际,所以java中有加强String类中字符串拼接的类,StringBuffer和StringBuilder,同样我们测试一下时间:

        long startTime = System.currentTimeMillis();
        String str="yxc";
        StringBuilder str1=new StringBuilder(str);
        for(int i=1;i<100000;i++){
            str1.append(i);
        }
        long endTime=System.currentTimeMillis();
        System.out.println(endTime-startTime);

耗时27ms

        long startTime = System.currentTimeMillis();
        String str="yxc";
        StringBuffer str1=new StringBuffer(str);
        for(int i=1;i<100000;i++){
            str1.append(i);
        }
        long endTime=System.currentTimeMillis();
        System.out.println(endTime-startTime);

耗时33ms,所以可以看出来,在字符串拼接上面,后两者的效率提高的不只是几个档次了,而对于后面两者StringBuilder的效率还会高一点,但是它是线程不安全的,而Stringbuffer是线程安全的。

 StringBuffer str=new StringBuffer("abcdefg");
        //stringbuffer中常见的方法

        System.out.println("插入一个元素在字符串中");
        StringBuffer str1 = str.insert(2, "poi");
        System.out.println(str1);   //abpoicdefg
        //和String不一样,str的值发生了改变
        System.out.println(str);  //abpoicdefg
        //也就是说两者的对象时一样的
        System.out.println(str==str1);  //true

        System.out.println("字符串的反转");
        System.out.println(str.reverse());   //gfedciopba

        System.out.println("字符串的删除");
        StringBuffer str3 = str.delete(3, 6);
        System.out.println(str3);  //gfeopba

StringBuilder和StringBuffer是一样的,而且String有的方法这两个类基本也有,可以看成是对于String的扩展类,但是不是继承,因为String是final修饰的类,不能被继承。注意上面的代码操作的都是一个对象,修改以后,StringBuffer的对象一直在改变。

发布了33 篇原创文章 · 获赞 37 · 访问量 4397

猜你喜欢

转载自blog.csdn.net/weixin_42142899/article/details/101899630
今日推荐