JavaSE常用类String02 2021.06.18-19

努力努力再努力

常见算法题目

  1. 模拟一个trim方法,去除字符串两段的空格:
public class Test01 {
    public static void main(String[] args) {
        String s1="  hell o wo rl d ";

        Test01 t1 = new Test01();
        String s = t1.myTrim(s1);
        System.out.println("---"+s+"---");
    }

    public  String myTrim(String str){
        int start =0;
        int end=str.length()-1;
        while(start<=end && str.charAt(start)==' '){//从左边开始寻找第一个不是空格的字符位置
            start++;
        }
        while(start<=end && str.charAt(end)==' ' ){//从右边开始寻找第一个不是空格的字符位置
            end--;
        }
        String s1=str.substring(start,end+1);//提取相应位置的子字符串
        return s1;
    }
}
  1. 将字符串中指定部分进行反转:
public class Test02 {
    public static void main(String[] args) {
        Test02 test02 = new Test02();
        String reverse = test02.reverse("123456789", 2, 6);
        String reverse1 = test02.reverse1("123456789", 2, 6);
        String reverse2 = test02.reverse2("123456789", 3, 5);
        System.out.println(reverse);//127654389
        System.out.println(reverse1);//127654389
        System.out.println(reverse2);//123654789
    }

    //方式一:转换为char[]
    public String reverse(String str, int startIndex, int endIndex) {
        if (str!=null) {
            char[] chars = str.toCharArray();
            for (int x = startIndex, y = endIndex; x < y; x++, y--) {
                char temp = chars[x];
                chars[x] = chars[y];
                chars[y] = temp;
            }
            String s2 = new String(chars);
            return s2;
        }
        return null;
    }
/* 优化的部分
 for (int i = startIndex; i < endIndex; i++) {
     for (int j = endIndex; j > i ; j--) {
         char temp=chars[j];
         chars[j]=chars[j-1];
         chars[j-1]=temp;
     }
 }
 */

    //方式二:使用String的拼接
    public String reverse1(String str, int startIndex, int endIndex) {
        if (str!=null) {
            //第一部分
            String reverseStr = str.substring(0, startIndex);
            //第二部分
            for (int i = endIndex; i >= startIndex; i--) {
                reverseStr += str.charAt(i);
            }
            //第三部分
            reverseStr += str.substring(endIndex + 1);
            return reverseStr;
        }
        return null;
    }
    //方式三:使用StringBuffer/StringBuilder 替换String
    public String reverse2(String str, int startIndex, int endIndex) {
        if (str!=null){
            StringBuilder builder = new StringBuilder(str.length());
            //第一部分
            builder.append(str.substring(0,startIndex));
            //第二部分
            for (int i = endIndex; i >=startIndex ; i--) {
                builder.append(str.charAt(i));
            }
            //第三部分
            builder.append(str.substring(endIndex + 1));

            return builder.toString();
        }
        return  null;
    }
}
  1. 获取一个字符串在另一个字符串中出现的次数
public class Test03 {
    public static void main(String[] args) {
        Test03 test03 = new Test03();
        int i = test03.occurTimes("abafsbaaklnvabdjabfabvabvavbavbaab", "ab");
        System.out.println(i);

    }

    public int occurTimes(String str,String targetStr){
        int times=0;
        int index=0;
        if (str.contains(targetStr)) {
/* 方式一
            while(str.substring(index).contains(targetStr)){
                times++;
                index= index+str.substring(index).indexOf(targetStr)+targetStr.length();
            }
            return times;
 */
 //方式二
            while ((index=str.indexOf(targetStr,index))!=-1){
                times++;
                index+=targetStr.length();
            }
            return times;
        }
        return 0;
    }
}
  1. 获取两个字符串中最大相同的子串。
    (提示:将短的那个串进行长度依次递减的子串与较长的串比较)
public class Test04 {
    public static void main(String[] args) {
        Test04 test04 = new Test04();
        String s = test04.sameString("fqbeqqhelhloaqqf", "aqqeaehelhelheqlloqqfsfvs");
        System.out.println(s);
    }

    public String sameString(String str1,String str2){
        String longStr = str1.length()>=str2.length() ? str1 : str2;
        String shortStr = str1.length()<str2.length() ? str1 : str2;
        /*
        if (str1.length()>=str2.length()){
            longStr=str1;
            shortStr=str2;
        }else {
            longStr=str2;
            shortStr=str1;
        }
         */

        boolean flag=false;
        if(!longStr.contains(shortStr) ){
            for (int i = shortStr.length()-1; i >0 ; i--) {//子字符串长度递减

                for (int j = 0; j <= shortStr.length()-i; j++) {//每一个子字符串与长字符串比较

                    String substr=shortStr.substring(j,j+i);
                    if (longStr.contains(substr)){
                        System.out.println(substr);//改进:用StringBuffer,添加相同的字符串
                        flag=true;
                    }
                }
                if (flag){//有相同字符串时,不再寻找下轮子字符串,
                    return "";//改进:返回 StringBuffer对象添加后的值
                }
            }
            return null;
        }
        return  shortStr;
    }
}
  1. 对字符串中字符进行自然顺序排序。
//方式一:Arrays.sort()
public class Test05 {
    public static void main(String[] args) {
        Test05 test05 = new Test05();
        String str = test05.mySort("ajbvabvaknv");
        System.out.println(str);
    }
    public String mySort(String str){
        char[] chars = str.toCharArray();
        Arrays.sort(chars);
        String s = new String(chars);
        return s;
    }
}

//方式二:选择,冒泡。。

字符串相关的类:StringBuffer、StringBuilder

String、StringBuffer、StringBuilder三者的异同

  • String:不可变的字符序列;底层使用char[]存储
  • StringBuffer:可变的字符序列;线程安全的,效率低;底层使用char[]存储
  • StringBuilder:可变的字符序列;jdk5.0新增;线程不安全,效率高;底层使用char[]存储

源码分析

/*
源码分析
String str = new String();//char[] value = new char[0];
String str1 = new String("abc");//char[] value = new char[]{'a','b','c'};

StringBuffer sb1 = new StringBuffer();//char[] value = new char[16];底层创建了一个长度为16的数组;
sb1.append('a');//value[0] = 'a';
sb1.append('b');//value[1] = 'b';

StringBuffer sb2 = new StringBuffer("abc");//char[] value = new char["abc".length() + 16];

问题1:System.out.println(sb2.length());// 3
问题2:扩容问题:如果要添加的数据底层数组盛不下了,那就需要扩容底层的数组。
       默认情况下,扩容为原来的两倍+2,同时将原有数组中的元素复制到新的数组中。

       指导意义:开发中建议使用:StringBuffer(int capacity) 或 StringBuilder(int capacity) 来指定容量避免扩容。
 */

public class StringBufferBuilder01 {
    public static void main(String[] args) {
        StringBuffer sb1 = new StringBuffer("abc");
        System.out.println(sb1);//abc

        sb1.append('d');
        System.out.println(sb1);//abcd

        sb1.setCharAt(0,'o');
        System.out.println(sb1);//obcd

        System.out.println(sb1.length());//4
    }
}

StringBuffer的常用方法(StringBuilder的方法也一样)

  1. StringBuffer append(xxx);提供了很多的append()方法,用于进行字符串拼接
  2. StringBuffer delete(int start,int end);删除指定位置[start,end)的内容
  3. StringBuffer replace(int start,int end,String str);把[start,end)位置替换成str
  4. StringBuffer insert(int offset,xxx);在指定位置插入xxx
  5. StringBuffer reverse();把当前字符序列逆转
  6. int indexOf(String str);str在StringBuffer首次出现的位置
  7. String subString(int start,int end);返回一个[start,end)的子字符串
  8. int length(); 源码返回值:return count,不是容量,count记录有效字符的个数。
  9. char charAt(int index);返回某索引处的字符
  10. void setCharAt(int index,char ch);将指定位置的字符改为新的字符
        StringBuffer s1 = new StringBuffer("abcdf");
        s1.append("1");// 1. StringBuffer append(xxx);提供了很多的append()方法,用于进行字符串拼接
        s1.append(2);
        System.out.println(s1);//abcdf12

        s1.delete(2,4);// 2. StringBuffer delete(int start,int end);删除指定位置[start,end)的内容
        System.out.println(s1);//abf12 ,左闭右开

        s1.replace(2,4,"hello");// 3. StringBuffer replace(int start,int end,String str);把[start,end)位置替换成str
        System.out.println(s1);//abhello2

        s1.insert(3,true);// 4. StringBuffer insert(int offset,xxx);在指定位置插入xxx
        System.out.println(s1);//abhtrueello2

        s1.reverse();// 5. StringBuffer reverse();把当前字符序列逆转
        System.out.println(s1);//2olleeurthba

        //不获取返回值也可以输出,因为StringBuffer是可变序列

        System.out.println(s1.indexOf("eu"));//5
        // 6. int indexOf(String str);str在StringBuffer首次出现的位置

        System.out.println(s1.substring(3, 7));//leeu,要返回值String,没有改变当前StringBuffer
        // 7. String subString(int start,int end);返回一个[start,end)的子字符串

        System.out.println(s1.length());//12
        // 8. int length(); 源码返回值:return count,不是容量,count记录有效字符的个数。

        System.out.println(s1.charAt(6));//u
        // 9. char charAt(int index);返回某索引处的字符

        s1.setCharAt(1,'d');// 10. void setCharAt(int index,char ch);将指定位置的字符改为新的字符
        System.out.println(s1);//2dlleeurthba

        /*总结:
        增:append(xxx); 方法链:s1.append().append().append()...,原理:返回值是自身
        删:delete(int start,int end)
        改:setCharAt(int index,char ch) / replace(int start,int end,String str)
        查:charAt(int index)
        插:insert(int offset,xxx)
        长度:length();
        *遍历:for + charAt() / toString()
         */

三者效率对比

效率从高到低:StringBuilder > StringBuffer > String

public class Efficiency {
    public static void main(String[] args) {
        //初始设置
        long startTime=0L;
        long endTime=0L;
        String text="";
        StringBuffer buffer = new StringBuffer("");
        StringBuilder builder = new StringBuilder("");

        //开始比较
        startTime = System.currentTimeMillis();
        for (int i = 0; i <20000 ; i++) {
            buffer.append(String.valueOf(i));
        }
        endTime =System.currentTimeMillis();
        System.out.println("StringBuffer的执行时间:"+(endTime-startTime));

        startTime = System.currentTimeMillis();
        for (int i = 0; i <20000 ; i++) {
            builder.append(String.valueOf(i));
        }
        endTime =System.currentTimeMillis();
        System.out.println("StringBuilder的执行时间:"+(endTime-startTime));

        startTime = System.currentTimeMillis();
        for (int i = 0; i <20000 ; i++) {
            text = text + i;
        }
        endTime =System.currentTimeMillis();
        System.out.println("String的执行时间:"+(endTime-startTime));
    }
}

String与StringBuffer、StringBuilder之间的转换

  • String - - > StringBuffer、StringBuilder :调用StringBuffer、StringBuilder构造器
  • StringBuffer、StringBuilder - - > String :①调用String构造器、 ② StringBuffer、StringBuilder 的toString()方法

JVM中字符串常量池存放位置

  • jdk 1.6(jdk 6.0 ,java 6.0):字符串常量池存储在方法区(永久区)
  • jdk 1.7:字符串常量池存储在堆空间
  • jdk 1.8:字符串常量池存储在方法区(元空间)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值