java SE_2

1.单例模式

  • 单例模式: 保证类的实例只有一个。
    • 构造函数私有化,提供一个可以获取到对象的静态公开方法。
  • 方式1
// 单例模式
public class Singleton {
   // 自己创建一个对象
   private static Singleton s = new Singleton();

   // 提供一个私有构造函数
   private Singleton() {
   }

   // Instance : 实例化
   // synchronized: 同步 (保证这个方法被线程使用完之后, 其他线程才可以使用到。)
   public static synchronized Singleton getInstance() {
      return s;
   }
}

class Test1 {
   public static void main(String[] args) {
      Singleton s1 = Singleton.getInstance();
      Singleton s2 = Singleton.getInstance();
// 判断是否为同一个对象
      System.out.println(s1 == s2);
   }
}
  • 方式2
//单例模式
public class SingletonA {
   // 定义一个静态变量
   private static SingletonA sa;

   // 私有化构造函数
   private SingletonA() {
   } 
   
   //提供一个静态函数
   public static synchronized SingletonA getInstance() {
      if (sa == null) {
         sa = new SingletonA();
      }
      return sa;
   }
}
  • 单例:

image-20230804083423932

  • 非单例:一个类型可以创造出多个对象

image-20230804083545110

  • 用单例模式写一个冒泡排序算法(面试题)
    • 知识点1:单例模式
public class Singleton {
   //提供一个是私有构造函数
   private Singleton(){}

   //自己创建一个对象
   private static Singleton s = new Singleton();

   //Instance : 实例化
   public static synchronized Singleton getSingleton(){
      return s;
   }
   public int[] sort(int[] arr){
      for(int i = 0; i < arr.length -1 ; i++){
         for (int j = 0; j < arr.length-1-i; j++){
            if (arr[j] > arr[j+1]){
               int temp = arr[j];
               arr[j] = arr[j+1];
               arr[j+1] = temp;
            }
         }
      }
      return arr;
   }
}

class Test1{
   public static void main(String[] args) {
      Singleton s1 = Singleton.getSingleton();
      Singleton s2 = Singleton.getSingleton();
      System.out.println(s1 == s2);
      Singleton s = Singleton.getSingleton();
      int[] arr = {5,4,3,2,1};
      System.out.println("排序后的数组"+ Arrays.toString(s.sort(arr)));
   }
}
  • 知识点2: 冒泡排序
public class SingletonA {
   //定义一个静态变量
   private static SingletonA sa;

   //私有化构造函数
   private SingletonA() {
   }

   //提供一个静态函数
   public static synchronized SingletonA getSingleton() {
      if (sa == null) {
         sa = new SingletonA(); // 保证只执行一次。
      }
      return sa;
   }

   public int[] sort(int[] arr) {
      for (int i = 0; i < arr.length - 1; i++) {
         for (int j = 0; j < arr.length - 1 - i; j++) {
            if (arr[j] > arr[j + 1]) {
               int temp = arr[j];
               arr[j] = arr[j + 1];
               arr[j + 1] = temp;
            }
         }
      }
      return arr;
   }
}

class Test2 {
   public static void main(String[] args) {
      SingletonA s = SingletonA.getSingleton();
      int[] arr = {5, 4, 3, 2, 1};
      System.out.println("排序后的数组" + Arrays.toString(s.sort(arr)));
   }
}

2.String类中的方法使用

  • 查找指定字符串在某字符串中的索引位置
//字符串的方法
//--- 跟索引有关
public class StringDemo1 {
   public static void main(String[] args) {
      String str = "abtomcdtomeftomastomdftom";  // "tom"是一个子字符串
      //1.找到字符串tom
      //字符串.indexOf(字串) -- 找到某个字符串在原字符串的位置
      //                   *** 找到就返回这个字符串的首字符位置,找不到就返回-1
      /*int i = str.indexOf("tom1");
      System.out.println(i);
      if (i == -1){
         System.out.println("找不到");
      }*/
      // 2. 从指定位置开始找
      //int i1 = str.indexOf("tom", 3);
      //System.out.println(i1);
      //3.统计“tom”的个数
      int count = 0;
      int index = str.indexOf("tom"); //先找到第一个tom
      if (index != -1) {
         count++;
         index = index + 3; //找到第一个后,往后找
      }
      while (index != -1) {
         index = str.indexOf("tom", index); //继续往后找tom
         if (index != -1) {
            count++;
            index = index + 3; //下一次寻找的起点
         }
      }
      System.out.println("tom有" + count + "个");

      //3.lastIndecOf(字符串) -- 从后往前找,找到最后一个出现的字符串的索引位置
      System.out.println(str.lastIndexOf("tom"));  //
      //3.lastIndecOf(字符串, index)
      System.out.println(str.lastIndexOf("tom", 6));
      System.out.println(str.lastIndexOf("tom1")); // -1

      //计算出"aaaa33aaa22233" -- a的个数
      char c = str.charAt(0);
      if (c == 'a') {
         System.out.println("个数加1");
      }
   }
}
  • 截取子字符串
//-- 子字符串
public class StringDemo2 {
   public static void main(String[] args) {
      String s = "tomjackalicerose";  // 每个字符有一个对应的索引位置
      // 1.获取字字符串
      //找到tom
      //substring(begin) --- 指定开始位置,到字符串结尾的子字符串
      //substring(begin, end) -- 从指定位置开始,到end-1位置结束的字符串。 [begin,end) -- 包含前面,不包含后面
      //Math.random()  [0,1) -- 包含0,不包含1
      String sub1 = s.substring(0, 3);
      System.out.println(sub1);
      s.substring(s.indexOf("rose"));
      System.out.println(sub1);
      //2.练习:字符串 。。。,找到邮箱名字
      String email = "rose@qq.com";
      sub1 = email.substring(0,email.indexOf("@")); //
      System.out.println("邮箱名字为:"+sub1);
      System.out.println(email.substring(0, email.lastIndexOf("@")));
      System.out.println(email.substring(email.indexOf("@") + 1));

      //3。练习:把字符串str 按三个一组,截取为子字符串,然后保存遭字符数组中
      String str = "abcdefghijklmn";
      String[] ss = new String[0];
   }
}

字节数组 & 字符编码

public class StringDemo3 {
   public static void main(String[] args) throws UnsupportedEncodingException {
      String str = "中国你好";
      byte[] bytes = str.getBytes(); // 没有指定编码,就看当前软甲使用的编码方式
      System.out.println(Arrays.toString(bytes) +"-------"+bytes.length);
      byte[] bytes1 = str.getBytes("utf-8"); //一个中文字符三个字节
      byte[] gbks = str.getBytes("gbk"); //一个中文两个字符
      System.out.println(Arrays.toString(bytes1) +"-------"+bytes1.length);
      System.out.println(Arrays.toString(gbks) +"-------"+gbks.length);
      byte[] bytes2 = str.getBytes(StandardCharsets.UTF_8); // StandardCharsets.UTF_8 -- 常量
      //字符串的构造函数
      String str1 = new String("hello");
      String str2 = new String(gbks); // gbks中存的gbk编码获取的字节数组,类使用的utf-8编码。
      str2 = new String(gbks, "gbk");
      System.out.println(str2); // 乱码?
      char[] c = {'a', 'b', 'c'};
      String str3 = new String((c));
      System.out.println(str3); 
   }
}

3.正则表达式

3.1 正则表达式的介绍

  • 正则表达式是一个特殊的字符串,是由一些特定的字符串组成的“规则字符串”。

  • 正则表达式,主要用于对字符串进行匹配,查找,替换等操作。

    比如: 如果检查一个字符串是否符合邮箱的规则。

    名字 @ qq . com

    ​ /1+@[a-zA-Z0-9]+(.[a-zA-Z0-9]+)+$/

    ​ (.[a-zA-Z0-9]+)称为一个组

  • 正则表达式的规则**:**

    • 可以出现的字符

    image-20230804150259928

    • 可以出现的字符简写

    image-20230804160407805

    • 字符串出现的次数限定

    image-20230804160516600

    • 其他规定

    image-20230804160523419

3.2 String中正则表达式的使用

  • split方法把字符串按照指定的分隔符,分割为字符串数组。

image-20230804160644864

  • String提供了用于字符串替换的方法

image-20230804160706024

  • 代码:

    • split: 字符串切割位数组

    • replaceAll:把正则匹配的内容,替换为指定的字符串

//split方法的使用
//regex : 正则, ① 能出现的哪些字符,②出现的次数,③特殊规定:限定开始,限定结尾,全局查找,忽略大小写。
public class StringDemo4 {
   public static void main(String[] args) {
      //1.根据数字,把字符串切割为字符串数组
      String str = "aa12321bb3434cc1dd343ee33"; // {"aa","bb","cc","dd","ee"}
      String regex = "[0-9]{1,}";
      //split --- 分割, split(regex) --- 根据正则表达式的匹配规则,把字符串,分割为字符串数组
      String[] split = str.split(regex);
      System.out.println(Arrays.toString(split));
      //按字母来切割,得到字符串数组
      regex = "[a-z]{1,}";
      split = str.split(regex);
      System.out.println(Arrays.toString(split));
      //2.练习 2023.8.3 转为2023-8-3
      String year = "2023.8.3";
      regex = "\\.";  // 正则中的"."表示任意字符,使用"\."表示点本身
      String[] ys = year.split(regex);
      System.out.println(ys[0] + "-" + ys[1] + "-" + ys[2]);
      //3.练习:0123456789 ,变成0-1-2-3-4-5-6-7-8-9
      String old = "0123456789";
      regex = "";
      String[] ds = old.split(regex);
      String dStr = "";
      for(int i = 0; i < ds.length; i++){
         dStr += ds[i] + "-";
      }
      System.out.println(dStr);// 0-1-2-3-4-5-6-7-8-9-
      String subStr = dStr.substring(0,dStr.length()-1);
      System.out.println(subStr);// 0-1-2-3-4-5-6-7-8-9
      //4. 思考: “abtomcdtomefto1tom2tom” 把tom 替换为TOM
      regex = "tom";
      old = "abtomcdtomefto1tom2tom";
      ds = old.split(regex);
      System.out.println("ds:" + Arrays.toString(ds));

      //5.使用replaceAll(正则,字符串) --- 把正则匹配的内容,替换为指定的字符串
      String s = old.replaceAll("tom", "TOM");
      System.out.println(s);
      System.out.println(year.replaceAll("\\.", "/"));

      //6.练习"中国你好";---把你好,替换为"是我最喜欢的国家"。
      old = "中国你好";
      String newStr = old.replace("你好", "是我最喜欢的国家");
      System.out.println(newStr);

      //7.练习: “你妈最近身体好吗,你妹妹最近考上那个大学.我最喜欢的明星范冰冰,我妈妈也喜欢,因为演技很好。”,把妈显示为**

      old = "你妈最近身体好吗,你妹妹最近考上那个大学.我最喜欢的明星范冰冰,我妈妈也喜欢,因为演技很好。";
      newStr = old.replaceAll("妈{1,}|妹{1,}|[冰]+","******");
      System.out.println(newStr);
   }
}

4.StringBuffer & StringBuilder

4.1 StringBuffer

  • StringBuffer封装可变的字符串, StringBuffer对象创建后,可以通过调用方法,修改字符串的内容。

  • StringBuffer构造器函数

    • public StringBuffer();

    • public StringBuffer(String str);

  • StringBuffer提供的操作字符串的方法: append , insert , delete , replace,reverse等。

  • StringBuffer提供的很多方法,返回值是StringBuffer(return this ) , 所以支持链式操作:

    ​ StringBuffersb = new StringBuffer(“a”);

    ​ sb.append(“b”).append(“b”)…

image-20230804170238290

4.2 StringBuilder

  • StringBuilder封装可变的字符串, StringBuilder对象创建后,可以通过调用方法,修改字符串的

    内容。

  • StringBuilder构造器函数

    ​ public StringBuilder();

    ​ public StringBuilder(String str);

  • StringBuilder提供的操作字符串的方法: append , insert , delete , replace,reverse等。

  • StringBuilder提供的很多方法,返回值是StringBuilder (return this ) , 所以支持链式操作:

​ StringBuilder sb = new StringBuilder(“a”);

​ sb.append(“b”).append(“b”)…

image-20230804170819739

4.3 参考代码

  • 把类型修改为StringBuffer ,以下方法均可正常使用。
//StringBuilder 中提供的方法
public class StringBuilderDemo1 {
   public static void main(String[] args) {
      StringBuilder sb = new StringBuilder();
      //追加 -- append
      sb.append("今天天气很好。");
      System.out.println(sb);
      //插入 -- insert
      sb.insert(2,"是星期四"); // 指定位置之前插入
      System.out.println(sb.toString()); //输出对象本身就是在调用toString方法。
      //替换 -- replace
      int begin = sb.indexOf("星期四");
      int end = begin + "星期四".length();
      sb.replace(begin, end, "XQS");
      System.out.println(sb);
      //删除 -- delete
      begin = sb.indexOf("是XQS");
      end = begin + "是XQS".length();
      sb.delete(begin, end);
      System.out.println(sb);

      //反转 -- reverse
      sb.reverse();
      System.out.println(sb);
      //练习:  判断"上海自来水来自海上"是不是回文。
      String str = "上海自来水来自海上";
      StringBuilder sb1 = new StringBuilder(str);
      sb1.reverse();
      if (str.equals(sb1.toString())) {
         System.out.println("是回文");
      }else{
         System.out.println("不是回文");
      }
   }
}

4.4 如果频繁修改字符串,使用StringBuilder/StringBuffer

image-20230804171010618

4.5 String , StringBuffer ,StringBuilder的区别

  • String vs StringBuffer vs StringBuilder

    • StringBuffer和StringBuilder类提供了操作字符串的方法。

    • String是不可变的,StringBuffer和StringBuilder是可变的。

  • String类的特点:

    • String类是不可变的,一旦创建就不能被修改。
    • 在多线程环境下是安全的,因为它是不可变的。
    • 在字符串池中使用相同的字符串来节省内存。
  • StringBuffer的特点:

    • 在Java1.4之前,StringBuffer是唯一的字符串操作类。
    • 所有的public方法都是同步的,适合在多线程环境下使用。
    • 提供线程安全,但性能相对较低。
  • StringBuilder的特点:

    • 自Java1.5开始引入,用于取代StringBuffer,性能更好。
    • 所有的public都不是同步的,适合单线程环境下使用。
    • 没有StringBuffer的一些额外方法,因为这些方法在String中已经存在。
  • StringBuffer和StringBuilder的相似之处:

    • StringBuffer和StringBuilder都是可变的,适用字符串拼接和修改。
    • 他们提供了append()、insert()、delete()、substring()等方法来来操作字符串。

5. 字符串操作练习:

import java.util.Scanner;
public class Home {
   public static String fetch(String str) {
      //封装一个方法, 把字符串的从右边开始的第4到第七位取出来
      StringBuilder sb = new StringBuilder(str);
      sb.reverse();  // 反转
      return sb.substring(3, 7); //返回子字符串
   }

   public static void main(String[] args) {
      String str1 = "12345678";
      System.out.println(fetch(str1));

      //输入一行字符,分别统计出其中英文字母、空格、数字、和其他字符的个数。
      //程序分析:利用while语句,条件为输入的字符不为'\n'.
      Scanner sc = new Scanner(System.in);
      System.out.println("输入一行字符:要空格");
      String str = sc.nextLine(); // 接收一行字符串
      int[] arr = f(str);
      System.out.println("字母数:" + arr[0] + "\n空格数:" + arr[1] + "\n数字数:" + arr[2] + "\n其他字符:" + arr[3]);
   }
   public static int[] f(String str){
      if (str == null) {
         return null;
      }
      char[] cs = str.toCharArray();
      int[] arr = new int[4];  //字母数 空格数 数字数 其他字符
      for (int i = 0; i < cs.length; i++){
         if ((cs[i] >= 'a' && cs[i] <= 'z') || (cs[i] >= 'A' && cs[i] <= 'Z')){
            arr[0]++;
         }else if (cs[i] == ' '){
            arr[1]++;
         }else if (cs[i] >= '0' && cs[i] <= '9'){
            arr[2]++;
         }else {
            arr[3]++;
         }
      }
      return arr;
   }
}

png


  1. a-zA-Z0-9_- ↩︎

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

A码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值