JAVA编程基础:常用类与基础API

1. String类

  • String的声明:final修饰、实现了Comparable接口

  • String的不可变性

  • String的两种定义方式:① 字面量的定义方式 String s = "hello"                                                                                      ② new 的方式:String s = new String("hello");

    • String s = new String("hello");在内存中创建的对象的个数。

    • String的内存解析:字符串常量池、堆内存的使用

  • String的连接操作:+

    • 常量 + 常量 、变量 + 常量 、变量+变量、concat(String otherString)

    • String intern()

  • 熟悉String的构造器、与其他结构之间的转换、常用方法

    • 编码和解码

      • 编码:字符、字符串 --> 字节、字节数组。对应着编码集

      • 解码:字节、字节数组 --> 字符、字符串。对应着解码集

      • 规则:解码集必须使用当初编码时使用的编码集。只要不一致,就可能出现乱码!

  • String相关的算法问题。

  • 题目1:模拟一个trim方法,去除字符串两端的空格。

  • 题目2:将一个字符串进行反转。将字符串中指定部分进行反转。 比如"abcdefg"反转为"abfedcg"

  • 题目3:获取一个字符串在另一个字符串中出现的次数。 比如:获取"ab"在 "abkkcadkabkebfkabkskab" 中出现的次数

  • 题目4:获取两个字符串中最大相同子串。比如: str1 = "abcwerthelloyuiodef"; str2 = "cvhellobnm" 提示:将短的那个串进行长度依次递减的子串与较长的串比较。

  • 题目5:对字符串中字符进行自然顺序排序。

  • 提示: 1)字符串变成字符数组。 2)对数组排序,选择,冒泡,Arrays.sort(); 3)将排序后的数组变成字符串。

  • public class StringAnswers {
        //题目1:
        public String myTrim(String str) {
            if (str != null) {
                int start = 0;// 用于记录从前往后首次索引位置不是空格的位置的索引
                int end = str.length() - 1;// 用于记录从后往前首次索引位置不是空格的位置的索引
    
                while (start < end && str.charAt(start) == ' ') {
                    start++;
                }
                while (start < end && str.charAt(end) == ' ') {
                    end--;
                }
                if (str.charAt(start) == ' ') {
                    return "";
                }
                return str.substring(start, end + 1);
            }
            return null;
        }
        @Test
        public void testMyTrim() {
            String str = "   a   ";
            // str = " ";
            String newStr = myTrim(str);
            System.out.println("---" + newStr + "---");
        }
        //题目2:
        // 方式一:
        public String reverse1(String str, int start, int end) {// start:2,end:5
            if (str != null) {
                // 1.
                char[] charArray = str.toCharArray();
                // 2.
                for (int i = start, j = end; i < j; i++, j--) {
                    char temp = charArray[i];
                    charArray[i] = charArray[j];
                    charArray[j] = temp;
                }
                // 3.
                return new String(charArray);
            }
            return null;
        }
        // 方式二:
        public String reverse2(String str, int start, int end) {
            // 1.
            String newStr = str.substring(0, start);// ab
            // 2.
            for (int i = end; i >= start; i--) {
                newStr += str.charAt(i);
            } // abfedc
            // 3.
            newStr += str.substring(end + 1);
            return newStr;
        }
        // 方式三:推荐 (相较于方式二做的改进)
        public String reverse3(String str, int start, int end) {// ArrayList list = new ArrayList(80);
            // 1.
            StringBuilder s = new StringBuilder(str.length());
            // 2.
            s.append(str.substring(0, start));// ab
            // 3.
            for (int i = end; i >= start; i--) {
                s.append(str.charAt(i));
            }
    
            // 4.
            s.append(str.substring(end + 1));
            // 5.
            return s.toString();
        }
        @Test
        public void testReverse() {
            String str = "abcdefg";
            String str1 = reverse3(str, 2, 5);
            System.out.println(str1);// abfedcg
    
        }
        //题目3:
        // 判断str2在str1中出现的次数
        public int getCount(String mainStr, String subStr) {
            if (mainStr.length() >= subStr.length()) {
                int count = 0;
                int index = 0;
                // while((index = mainStr.indexOf(subStr)) != -1){
                //      count++;
                //      mainStr = mainStr.substring(index + subStr.length());
                // }
                // 改进:
                while ((index = mainStr.indexOf(subStr, index)) != -1) {
                    index += subStr.length();
                    count++;
                }
                return count;
            } else {
                return 0;
            }
        }
    
        @Test
        public void testGetCount() {
            String str1 = "cdabkkcadkabkebfkabkskab";
            String str2 = "ab";
            int count = getCount(str1, str2);
            System.out.println(count);
        }
    
        //题目4
        // 如果只存在一个最大长度的相同子串
        public String getMaxSameSubString(String str1, String str2) {
            if (str1 != null && str2 != null) {
                String maxStr = (str1.length() > str2.length()) ? str1 : str2;
                String minStr = (str1.length() > str2.length()) ? str2 : str1;
    
                int len = minStr.length();
    
                for (int i = 0; i < len; i++) {// 0 1 2 3 4 此层循环决定要去几个字符
    
                    for (int x = 0, y = len - i; y <= len; x++, y++) {
    
                        if (maxStr.contains(minStr.substring(x, y))) {
    
                            return minStr.substring(x, y);
                        }
    
                    }
    
                }
            }
            return null;
        }
    
        // 如果存在多个长度相同的最大相同子串
        // 此时先返回String[],后面可以用集合中的ArrayList替换,较方便
        public String[] getMaxSameSubString1(String str1, String str2) {
            if (str1 != null && str2 != null) {
                StringBuffer sBuffer = new StringBuffer();
                String maxString = (str1.length() > str2.length()) ? str1 : str2;
                String minString = (str1.length() > str2.length()) ? str2 : str1;
    
                int len = minString.length();
                for (int i = 0; i < len; i++) {
                    for (int x = 0, y = len - i; y <= len; x++, y++) {
                        String subString = minString.substring(x, y);
                        if (maxString.contains(subString)) {
                            sBuffer.append(subString + ",");
                        }
                    }
                    System.out.println(sBuffer);
                    if (sBuffer.length() != 0) {
                        break;
                    }
                }
                String[] split = sBuffer.toString().replaceAll(",$", "").split("\\,");
                return split;
            }
    
            return null;
        }
        @Test
        public void testGetMaxSameSubString() {
            String str1 = "abcwerthelloyuiodef";
            String str2 = "cvhellobnmiodef";
            String[] strs = getMaxSameSubString1(str1, str2);
            System.out.println(Arrays.toString(strs));
        }
    
        //题目5
        @Test
        public void testSort() {
            String str = "abcwerthelloyuiodef";
            char[] arr = str.toCharArray();
            Arrays.sort(arr);
    
            String newStr = new String(arr);
            System.out.println(newStr);
        }
    
    }
    StringTest {
        /*
        * 题目2:将一个字符串进行反转。将字符串中指定部分进行反转。
          比如"abcdefg"反转为"abfedcg"
        * */
        @Test
        public void test(){
            String s = "abcdefg";
            String s1 = reverse(s,2,5);
            String s2 = reverse1(s,2,5);
            System.out.println(s1);
            System.out.println(s2);
        }
        /*
        * 方式1:将String转为char[],针对char[]数组进行相应位置的反转,反转以后将char[]转为String
        * */
        public String reverse(String str,int fromIndex ,int toIndex){
            //
            char[] arr = str.toCharArray();
            //
            for(int i = fromIndex,j = toIndex;i < j;i++,j--){
                char temp = arr[i];
                arr[i] = arr[j];
                arr[j] = temp;
            }
            //
            return new String(arr);
        }
        /*
        * 第2种方式
        * */
        public String reverse1(String str,int fromIndex ,int toIndex){
            //获取str的第1部分
            String finalStr = str.substring(0,fromIndex); //ab
            //拼接上第2部分
            for(int i = toIndex;i >= fromIndex;i--){
                finalStr += str.charAt(i);
            }//abfedc
            //拼接上第3部分
            finalStr += str.substring(toIndex + 1);
            return finalStr;
        }
        /*
        * 题目3:获取一个字符串在另一个字符串中出现的次数。
          比如:获取"ab"在 "abkkcadkabkebfkabkskab" 中出现的次数
        * */
        /**
         * 判断subStr在str中出现的次数
         * @param str
         * @param subStr
         * @return 返回次数
         */
        public int getSubStringCount(String str,String subStr){
            int count = 0;//记录出现的次数
    
            if(str.length() >= subStr.length()){
                int index = str.indexOf(subStr);
                while(index >= 0){
                    count++;
                    index = str.indexOf(subStr,index + subStr.length());
                }
            }
            return count;
        }
        @Test
        public void test2(){
            String subStr = "ab";
            String str = "abkkcadkabkebfkabkskab";
    
            int count = getSubStringCount(str,subStr);
            System.out.println(count);
        }
    
    }
    

2. StringBuffer、StringBuilder类

[面试题]String、StringBuffer、StringBuilder的区别

知道什么场景下使用StringBuffer、StringBuilder

3. jdk8之前的日期、时间API

  • System的currentTimeMillis()

  • 两个Date的使用

  • |--java.util.Date
          > 两个构造器的使用
          > 两个方法的使用:①toString() ② long getTime()
              |----java.sql.Date: 对应着数据库中的date类型
  • SimpleDateFormat用于格式化、解析

  • Calendar日历类的使用

  • Calendar:日历类
         ① 实例化 由于Calendar是一个抽象类,所以我们需要创建其子类的实例。这里我们通过Calendar的静态方法
                  getInstance()即可获取
    
         ②常用方法:get(int field) / set(int field,xx) / add(int field,xx) / getTime() / setTime()

4. jdk8中新的日期、时间API

  • LocalDate、LocalTime、LocalDateTime -->类似于Calendar

  • Instant -->类似于Date

  • DateTimeFormatter --->类似于SimpleDateFormat

public class DateTimeTest {
    /*
    * - 可变性:像日期和时间这样的类应该是不可变的。
     - 偏移性:Date中的年份是从1900开始的,而月份都从0开始。
     - 格式化:格式化只对Date有用,Calendar则不行。
     - 此外,它们也不是线程安全的;不能处理闰秒等。
    *
    * */
    @Test
    public void test1(){
        String s1 = "hello";
        String s2 = s1.replace('l', 'w'); //String的不可变性
        System.out.println(s1);//hello
        //体会Calendar的可变性
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_MONTH,23);
        System.out.println(calendar.get(Calendar.DAY_OF_MONTH));
    }
    @Test
    public void test2(){
        //偏移性:Date中的年份是从1900开始的,而月份都从0开始。
        Date date = new Date(2022,11,14);
        System.out.println(date);
    }

    /*
    * JDK8的api:LocalDate \ LocalTime \ LocalDateTime
    * */
    @Test
    public void test3(){
        //now():获取当前日期和时间对应的实例
        LocalDate localDate = LocalDate.now();
        LocalTime localTime = LocalTime.now();
        LocalDateTime localDateTime = LocalDateTime.now();
        System.out.println(localDate);//2022-12-05
        System.out.println(localTime);//15:43:51.474
        System.out.println(localDateTime); //2022-12-05T15:43:51.475
        //of():获取指定的日期、时间对应的实例
        LocalDate localDate1 = LocalDate.of(2021, 5, 23);
        LocalDateTime localDateTime1 = LocalDateTime.of(2022, 12, 5, 11, 23, 45);
        System.out.println(localDate1);
        System.out.println(localDateTime1);
        //getXXX()
        LocalDateTime localDateTime2 = LocalDateTime.now();
        System.out.println(localDateTime2.getDayOfMonth());
        //体现不可变性
        //withXxx()
        LocalDateTime localDateTime3 = localDateTime2.withDayOfMonth(15);
        System.out.println(localDateTime2);//2022-12-05T15:48:48.399
        System.out.println(localDateTime3);//2022-12-15T15:48:48.399
        //plusXxx()
        LocalDateTime localDateTime4 = localDateTime2.plusDays(5);
        System.out.println(localDateTime2);//2022-12-05T15:50:21.864
        System.out.println(localDateTime4);//2022-12-10T15:50:21.864
    }

    /*
    * JDK8的api: Instant
    * */
    @Test
    public void test4(){
        //now():
        Instant instant = Instant.now();
        System.out.println(instant);//2022-12-05T07:56:27.327Z
        //了解:
        OffsetDateTime instant1 = instant.atOffset(ZoneOffset.ofHours(8));
        System.out.println(instant1);

        Instant instant2 = Instant.ofEpochMilli(24123123312L);
        System.out.println(instant2); //1970-10-07T04:52:03.312Z

        long milliTime = instant.toEpochMilli();
        System.out.println(milliTime);

        System.out.println(new Date().getTime());
    }

    /*
    * JDK8的api: DateTimeFormatter
    * */
    @Test
    public void test5(){
        //自定义的格式。如:ofPattern(“yyyy-MM-dd hh:mm:ss”)
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
        //格式化:日期、时间-->字符串
        LocalDateTime localDateTime = LocalDateTime.now();
        String strDateTime = dateTimeFormatter.format(localDateTime);
        System.out.println(strDateTime);//2022/12/05 16:04:44

        //解析:字符串 ---> 日期、时间
        TemporalAccessor temporalAccessor = dateTimeFormatter.parse("2022/12/05 15:04:44");
        LocalDateTime localDateTime1 = LocalDateTime.from(temporalAccessor);
        System.out.println(localDateTime1);//2022-12-05T15:04:44

    }
}

5. 比较器(重点)

  • 自然排序涉及到Comparable

    • compareTo(Object obj)

    • 实现步骤:
      ① 具体的类A实现Comparable接口
      ② 重写Comparable接口中的compareTo(Object obj)方法,在此方法中指明比较类A的对象的大小的标准
      ③ 创建类A的多个实例,进行大小的比较或排序。
public class ComparableTest {
    @Test
    public void test1(){
        String[] arr = new String[]{"Tom","Jerry","Tony","Rose","Jack","Lucy"};
        Arrays.sort(arr);
        //排序后,遍历
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }
    @Test
    public void test2(){
        Product[] arr = new Product[5];
        arr[0] = new Product("HuaweiMate50pro",6299);
        arr[1] = new Product("Xiaomi13pro",4999);
        arr[2] = new Product("VivoX90pro",5999);
        arr[3] = new Product("Iphone14ProMax",9999);
        arr[4] = new Product("HonorMagic4",6299);
        Arrays.sort(arr);
        //排序后,遍历
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }
    @Test
    public void test3(){
        Product p1 = new Product("HuaweiMate50pro",6299);
        Product p2 = new Product("VivoX90pro",5999);
        int comapre = p1.compareTo(p2);
        if(comapre > 0){
            System.out.println("p1大");
        }else if(comapre < 0){
            System.out.println("p2大");
        }else{
            System.out.println("p1和p2一样大");
        }
    }
}
  • 定制排序涉及到Comparator

    • compare(Object obj1,Object obj2)

    • 实现步骤:
      ① 创建一个实现了Comparator接口的实现类A
      ② 实现类A要求重写Comparator接口中的抽象方法compare(Object o1,Object o2),在此方法中指明要
         比较大小的对象的大小关系。(比如,String类、Product类)
      ③ 创建此实现类A的对象,并将此对象传入到相关方法的参数位置即可。(比如:Arrays.sort(..,类A的实例))
public class ComparatorTest {
    @Test
    public void test1(){
        Product[] arr = new Product[5];
        arr[0] = new Product("HuaweiMate50pro",6299);
        arr[1] = new Product("Xiaomi13pro",4999);
        arr[2] = new Product("VivoX90pro",5999);
        arr[3] = new Product("Iphone14ProMax",9999);
        arr[4] = new Product("HonorMagic4",6299);
        //创建一个实现了Comparator接口的实现类的对象
        Comparator comparator = new Comparator(){
            //如果判断两个对象o1,o2的大小,其标准就是此方法的方法体要编写的逻辑。
            //比如:按照价格从高到低排序
            @Override
            public int compare(Object o1, Object o2) {
                if(o1 instanceof Product && o2 instanceof Product){
                    Product p1 = (Product) o1;
                    Product p2 = (Product) o2;
                    return -Double.compare(p1.getPrice(),p2.getPrice());
                }
                throw new RuntimeException("类型不匹配");
            }
        };
        Comparator comparator1 = new Comparator(){
            //如果判断两个对象o1,o2的大小,其标准就是此方法的方法体要编写的逻辑。
            //比如:按照name从低到高排序
            @Override
            public int compare(Object o1, Object o2) {
                if(o1 instanceof Product && o2 instanceof Product){
                    Product p1 = (Product) o1;
                    Product p2 = (Product) o2;
                    return p1.getName().compareTo(p2.getName());
                }
                throw new RuntimeException("类型不匹配");
            }
        };
        Arrays.sort(arr,comparator1);
        //排序后,遍历
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }
    @Test
    public void test2(){
        String[] arr = new String[]{"Tom","Jerry","Tony","Rose","Jack","Lucy"};
        Arrays.sort(arr,new Comparator(){
            @Override
            public int compare(Object o1, Object o2) {
                if(o1 instanceof String && o2 instanceof String){
                    String s1 =(String) o1;
                    String s2 =(String) o2;
                    return -s1.compareTo(s2);
                }
                throw new RuntimeException("类型不匹配");
            }
        });
        //排序后,遍历
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值