zoukankan      html  css  js  c++  java
  • java 字符串

    String、StringBuffer和StringBuilder的区别

    参考链接:https://www.cnblogs.com/weibanggang/p/9455926.html

    https://www.cnblogs.com/onetheway2018/p/11553168.html

    运行速度

    StringBuilder > StringBuffer > String

    String 真正不可变有下面几点原因:

    1. 保存字符串的数组(字符数组)被 final 修饰且为私有的,并且String 类没有提供/暴露修改这个字符串的方法。
    2. String 类被 final 修饰导致其不能被继承,进而避免了子类破坏 String 不可变。

    String最慢的原因:String为字符串常量,而StringBuilder和StringBuffer均为字符串变量,即String对象一旦创建之后该对象是不可更改的,但后两者的对象是变量,是可以更改的

        public static void main(String[] args) {
            long a = new Date().getTime();
            String cc = "";
            int n = 10000;
            for (int i = 0; i < n; i++) {
                cc += "." + i;
            }
            System.out.println("String使用的时间" + (System.currentTimeMillis() - a) / 1000.0 + "s");
            long s1 = System.currentTimeMillis();
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < n; i++) {
                sb.append("." + i);
            }
            System.out.println("StringBuilder使用的时间" + (System.currentTimeMillis() - s1) / 1000.0 + "s");
            long s2 = System.currentTimeMillis();
            StringBuffer sbf = new StringBuffer();
            for (int i = 0; i < n; i++) {
                sbf.append("." + i);
            }
            System.out.println("StringBuffer使用的时间" + (System.currentTimeMillis() - s2) / 1000.0 + "s");
        }
        // String使用的时间0.161s
        // StringBuilder使用的时间0.003s
        // StringBuffer使用的时间0.004s

    线程安全

    在线程安全上,StringBuilder是线程不安全的,而String和StringBuffer是线程安全的

      如果一个StringBuffer对象在字符串缓冲区被多个线程使用时,StringBuffer中很多方法可以带有synchronized关键字,所以可以保证线程是安全的,但StringBuilder的方法则没有该关键字,所以不能保证线程安全,有可能会出现一些错误的操作。所以如果要进行的操作是多线程的,那么就要使用StringBuffer,但是在单线程的情况下,还是建议使用速度比较快的StringBuilder。

    (一个线程访问一个对象中的synchronized(this)同步代码块时,其他试图访问该对象的线程将被阻塞)

    性能

    每次对 String 类型进行改变的时候,都会生成一个新的 String 对象,然后将指针指向新的 String 对象。StringBuffer 每次都会对 StringBuffer 对象本身进行操作,而不是生成新的对象并改变对象引用。

    相同情况下使用 StringBuilder 相比使用 StringBuffer 仅能获得 10%~15% 左右的性能提升,但却要冒多线程不安全的风险

    总结

     String:适用于少量的字符串操作的情况

     StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况

     StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况

    为什么要把String设计为不变量?

    1. 节省空间:字符串常量存储在JVM的字符串池中可以被用户共享。
    2. 提高效率:String会被不同线程共享,是线程安全的。在涉及多线程操作中不需要同步操作。
    3. 安全:String常被用于用户名、密码、文件名等使用,由于其不可变,可避免黑客行为对其恶意修改。

    StringBuilder用法

    public static void main(String[] args) {
            StringBuilder string = new StringBuilder();
            string.append("abcd");
            System.out.println(string.toString());// 转换为String对象
            string.insert(3, "123");
            System.out.println(string.toString());
            string.delete(3, 5);// [3,5)//deleteCharAt(index)
            System.out.println(string.toString());
            System.out.println(string.length());
            string.replace(1, 3, "o");
            System.out.println(string.toString());// [1,3)
            string.replace(3, 4, "m");
            System.out.println(string.toString());
            // abcd
            // abc123d
            // abc3d
            // 5
            // ao3d
            // ao3m
        }

    StringBuilder类型字符串中的字符换位置

     StringBuilder sb = new StringBuilder(s);
          char x = sb.charAt(0);
      char y = sb.charAt(3);
      sb.setCharAt(0, y);
      sb.setCharAt(3, x);

         //做到了把位置在0和3的字符互换了位置。

    一些处理字符串的方法

    trim()的作用是去掉字符串两端的多余的空格,注意,是两端的空格,且无论两端的空格有多少个都会去掉,当然

    中间的那些空格不会被去掉

      String s = " dsf fg ";
            s = s.trim();
            System.out.println(s);
    
    
    dsf fg

     .split()  

      String s = "2019-06-30";
            String[] a = s.split("-");//双引号,String 类型
            for (String x : a) {
                System.out.println(x);
            }

    2019
    06
    30

     String和字符数组转换

        public String sortt(String s) {
            char[] ar = s.toCharArray();
            Arrays.sort(ar);
    
            return new String(ar);
        }

    实现两个字符串获取两个指定字符串中的最大相同子串

    import java.util.*;
    
    public class Main {
        public String same(String s1, String s2) {
    
            String min, max;
            if (s1.length() > s2.length()) {
                min = s2;
                max = s1;
            } else {
                min = s1;
                max = s2;
            }
            //一次外循环 表示一种长度的子串:min.length()-i为子串长度
            for (int i = 0; i < min.length(); i++) {
                for (int j = 0, k = min.length() - i; k < min.length() + 1; j++, k++) {
                    String tmp = min.substring(j, k);
                    if (max.contains(tmp)) {
                        return tmp;
    
                    }
                }
            }
            return null;
        }
    
        public static void main(String agrs[]) {
            Scanner input = new Scanner(System.in);
            String s1 = input.next();
            String s2 = input.next();
            Main ma = new Main();
            System.out.println(ma.same(s1, s2));
    
        }
    }

    给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 "" 。

    注意:

    • 对于 t 中重复字符,我们寻找的子字符串中该字符数量必须不少于 t 中该字符数量。
    • 如果 s 中存在这样的子串,我们保证它是唯一的答案。
    class Solution {
        int mapt[]  =new int[123];
        int maps[]  =new int[123]; //'z':ASCII 122
        public String minWindow(String s, String t) {
        String smin  ="";
              for(int i=0;i<t.length();i++){
                  mapt[t.charAt(i)]++;
              }
              int sta=0,end=0,minl  =Integer.MAX_VALUE,cnt=0;//Integer.MAX_VALUE 2*10^(9)左右
              while(end<s.length()){
                  if(mapt[s.charAt(end)]!=0){
                       if(  mapt[s.charAt(end)] >maps[s.charAt(end)]   ) cnt++;//表示得到t中一个字符
                       maps[s.charAt(end)]++;
                  }
                  if(cnt==t.length()){
                      while(mapt[s.charAt(sta)]==0||maps[s.charAt(sta)]>mapt[s.charAt(sta)]){//s[sta]可以不用:该字符不在t中或者此时的s子串已经有足够的该字符
                                 if(maps[s.charAt(sta)]>mapt[s.charAt(sta)]){
                                    maps[s.charAt(sta)]--;//多了就减1,表示从子串中去掉该字符
                                 }
                                 sta++;//收缩sta
                      }
                      if(minl>end-sta+1){
                          smin = s.substring(sta,end+1);
                          minl  = end-sta+1;
                      }
                  }
                  end++; //后移end
              }
              return smin;
        }
    }

     字符和数字转换

      char x = 'b';
            int y = x - 'a';
            System.out.println(y);//1
            int x1 = 3;
            // x += 96;
            char y1 = (char) (x1 + 96);
            System.out.println(y1);//c

    String字符串转化为数字

      private static String getType(Object a) {
            return a.getClass().toString();
        }
     // String--->数字
            String s = "056";
            int num1 = Integer.parseInt(s);
            int num2 = Integer.valueOf(s);
            System.out.println(num1 + " " + num2);// 56 56
            String sf = "12.036";
            float num3 = Float.parseFloat(sf);
            double num4 = Double.parseDouble(sf);
            System.out.println(getType(num3) + ": " + num3 + getType(num4) + ": " + num4);// 12.036 12.036
            // class java.lang.Float: 12.036class java.lang.Double: 12.036
            // 数字-->String
            double num = 5036.036;
            String ss = String.valueOf(num);
            System.out.println(ss);// 5036.036

    字符串拼接用“+” 还是 StringBuilder?

    对象引用和“+”的字符串拼接方式,实际上是通过 StringBuilder 调用 append() 方法实现的,拼接完成之后调用 toString() 得到一个 String 对象

     意味着每循环一次就会创建一个 StringBuilder 对象。

    如果直接使用 StringBuilder 对象进行字符串拼接的话,就不会存在这个问题了。

     

    字符串常量池

    JDK1.7 之前运行时常量池逻辑包含字符串常量池存放在方法区。JDK1.7 的时候,字符串常量池被从方法区拿到了堆中。

     

  • 相关阅读:
    spring
    Hibernate中一级缓存和二级缓存使用详解
    myeclipse 配置weblogic
    小程序animation动画效果综合应用案例(交流QQ群:604788754)
    PHP:第二章——PHP中的equire与incude语句
    PHP:第二章——PHP中的break一continue一return语句
    PHP:第二章——PHP中的for语句
    PHP:第二章——PHP中的while语句
    PHP:第二章——PHP中的流程控制语句
    小程序animation动画效果(小程序组件案例)
  • 原文地址:https://www.cnblogs.com/tingtin/p/15693192.html
Copyright © 2011-2022 走看看