Java基础day18——String 及其API

1.对象数组的排序和查找

java中核心类库中排序一般用两种Comparable和Compare to

package com.atguigu.java;

import java.util.Arrays;

public class SortTest {
    public static void main(String[] args) {

        Person[] ps = new Person[4];
        ps[0] = new Person(1,"a",20);
        ps[1] = new Person(3,"c",18);
        ps[2] = new Person(2,"b",21);
        ps[3] = new Person(4,"d",22);


        Arrays.sort(ps);//通过调用对象的compareTo方法进行的排序

        for (int i = 0; i < ps.length; i++) {
            System.out.println(ps[i]);//调用的是对象的toString方法
        }

        //注意:不是通过对象的地址值  通过属性的内容。
        int i = Arrays.binarySearch(ps, new Person(2,"b",21));

        System.out.println(i);

    }
}

class Person implements Comparable{
    public int id;
    public String name;
    public int age;

    public Person(int id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return id + " " + name + " " + age;
    }

    @Override
    public int compareTo(Object o) {
        //校验:
        Person p = (Person) o;

        return this.age - p.age;
    }
}

2.String的概述

1.为了节省内存 String 底层的Char类型数组中文2Btye 字母1Btye 而在混合时均为2Btye

2.String在内存区域内存在一个字符串常量池 其内常量不可改变

import org.junit.Test;

/*
    String :

    说明:
        1.String被final所修饰那么String这个类不能被其它类继承
        2.String实现了Comparable接口 那么可以比较字符串内容。
        3.String的底层是一个char类型的数组(JDK9开始变成了byte[]--原因是为了节省内存)
                JDK9之前                      JDK9开始
                char[] 编译UTF-16             byte[](编译 latin1 - UTF-16)
                a -> char                    a - 1个byte
                中 -> char                   中 - 2个byte
               a中 -> 2个char                a中 - 4个byte
       4.String是一个不可变的字符序列
            ①String不能被子类继承--那么就没有了子类可以对父类的操作
            ②char[]是被final修饰 - char[]的对象(字符串)不能被修改 -- 只看到这还无法保证数组的内容被修改
            ③char[]是被private修饰 - 类的名部不能操作该数组同时类的内部不提供对数组内容本身修改的方法

       5.为什么String要设置成不可变呢? 因为不可变才能被共享,因为共享才能节省内存。
            因为字符串在内存存储的区域是一个比较特殊的区域 - 字符串常量池(相同的对象只能有一份)
 */
public class StringTest {
    /*
        创建字符串对象
     */
    @Test
    public void test(){
        //方式一
        String s = new String("abc");

        //方式二
        String s2 = "abc";
    }

    /*
        创建String对象两种方式的区别
     */
    @Test
    public void test2(){

        String s3 = "abc";
        String s4 = "abc";

        String s = new String("abc");
        String s2 = new String("abc");



        System.out.println(s == s2);//false
        System.out.println(s3 == s4);//true
    }


    /*
        案例二
     */
    @Test
    public void test3(){
        String s = "a";
        String s2 = s;
        s = "b"; //把一个新的对象赋值给了s

        System.out.println(s == s2);//false
    }

    /*
        案例三
     */
    @Test
    public void test4(){
        String s = "abcd";
        //将字符串中的字符a被A替换 - 字符串是一个不可变的字符序列 原来的字符串并没有修改而是创建了一个新的
        String s2 = s.replace('a', 'A');

        System.out.println("s:" + s);//abcd
        System.out.println("s2:" + s2);//Abcd
        System.out.println(s2 == s); //false
    }

    /*
        案例四
     */
    @Test
    public void test5(){
        String str = new String("world");
        char[] ch = new char[]{'h','e','l','l','o'};
        change(str,ch);
        System.out.println(str);//world
        System.out.println(String.valueOf(ch));//abcde
    }

    public void change(String str, char[] arr){
        str = "change";
        arr[0] = 'a';
        arr[1] = 'b';
        arr[2] = 'c';
        arr[3] = 'd';
        arr[4] = 'e';
    }

}

import org.junit.Test;

public class StringTest2 {

    @Test
    public void test(){

        char[] c = {'a','b','c'};
        String s = new String(c); // 字符串常量池中有没有abc? 没有

        System.out.println(s);
    }
}
ackage com.atguigu.java;

public class StringTest3 {

    /*
        [面试题] String s = "a" + "b" + "c" 创建了几个对象 ? 1个-字符串常量池

        [面试题] String s = new String("abc") 创建了几个对象 ?
                如果字符串常量池中没有abc 那么会创建2个对象 1个在字符串常量池 1个在堆中
                如果字符串常量池中已经存在abc 那么会创建1个对象在堆中
     */
    public static void main(String[] args) {

        String s = "hello";
        String s2 = "hel" + "lo"; //编译的时候就是 "hello"
        String s3 = "hel";
        String s4 = "lo";

        /*
            总结:只要有变量参与字符串拼接就会用StringBuilder中的toString方法在该方法中new String 并返回
         */
        String s5 = "hel" + s4;//有变量参与字符串拼接 -- 底层调用StringBuilder中的toString方法在该方法中new String 并返回
        String s6 = s3 + "lo";//有变量参与字符串拼接 -- 底层调用StringBuilder中的toString方法在该方法中new String 并返回
        String s7 = s3 +  s4;//有变量参与字符串拼接-- 底层调用StringBuilder中的toString方法在该方法中new String 并返回

        /*
            intern() : 调用该方法时会直接去字符串常量池中寻找有没有该内容。如果有直接返回。
                如果没有往字符串常量池中放一份并返回。

            注意:返回值是从字符串常量池中寻找后返回的结果。
         */
        String s8 = (s3 + s4).intern(); //优化 - 节省了内存(从字符串常量池中获取的)

        System.out.println(s == s2); //true
        System.out.println(s == s5); //false
        System.out.println(s2 == s6); //false
        System.out.println(s == s7); //false
        System.out.println(s5 == s6);//false
        System.out.println(s2 == s7);//false


        System.out.println(s == s8);//true

    }
}

String新建对象时字符串常量池中没有就新建

有则使用常量池中对象

3.Sting的构造器

import org.junit.Test;

import java.io.UnsupportedEncodingException;
import java.util.Arrays;

public class StringAPI01 {
    /*
        构造器

* `public String() ` :初始化新创建的 String对象,以使其表示空字符序列。
* ` String(String original)`: 初始化一个新创建的 `String` 对象,使其表示一个与参数相同的字符序列;
            换句话说,新创建的字符串是该参数字符串的副本。
* `public String(char[] value)  :通过当前参数中的字符数组来构造新的String。
* `public String(char[] value,int offset, int count) :通过字符数组的一部分来构造新的String。
* `public String(byte[] bytes)  :通过使用平台的默认字符集解码当前参数中的字节数组来构造新的String。
* `public String(byte[] bytes,String charsetName)  :通过使用指定的字符集解码当前参数中的字节数组来构造新的String。
     */
    @Test
    public void test() throws UnsupportedEncodingException {
        String s = new String(); //相当于 ""
        System.out.println("a" + s + "b");

        String s2 = new String("longge");

        System.out.println("======================================");
        char[] c = {'a','b','c','d','e'};
        String s3 = new String(c);
        System.out.println(s3);

        //public String(char[] value,int offset, int count) :通过字符数组的一部分来构造新的String。
        String s4 = new String(c, 2, 2);// 第一个2是索引位置  第二个2是长度
        System.out.println(s4);

        System.out.println("======================================");

        /*
        public String(byte[] bytes)  :通过使用平台的默认字符集解码当前参数中的字节数组来构造新的String。

         */
        byte[] b = {97,98,99}; //整数
        String s5 = new String(b);
        System.out.println(s5);

        System.out.println("======================================");
        /*
         public String(byte[] bytes,String charsetName)  :通过使用指定的字符集解码当前参数中的字节数组来构造新的String。
         */
        byte[] b2 = {97,98,99}; //整数
        String s6 = new String(b,"utf-8");
        System.out.println(s6);

        //将字符串转成byte[]
        byte[] bytes = "小鬼子".getBytes("gbk"); //[-48, -95, -71, -19, -41, -45]
        System.out.println(Arrays.toString(bytes));
        bytes = "小鬼子".getBytes("utf-8");
        System.out.println(Arrays.toString(bytes)); //[-27, -80, -113, -23, -84, -68, -27, -83, -112]

        String ss2 = new String(bytes, "gbk");//因为bytes中放的是UTF-8的编码集的内容  然后非得转成gbk编码 肯定乱码
        System.out.println(ss2);
    }


}

4.字符串拼接

在常量池中的字符串:

1.双引号中

2.intern方法:需要返回值接收 否则就是常量池中寻找并且(没有就添加)返回

import org.junit.Test;
public class StringTest4 {

    /*
        什么样的字符串在常量池中?
            1.双引号中
            2.调用了intern方法
     */
    @Test
    public void test(){
        String s1 = "hel";
        String s2 = "lo";
        String s3 = s1 + s2;

         /*
            intern() : 调用该方法时会直接去字符串常量池中寻找有没有该内容。如果有直接返回。
                如果没有往字符串常量池中放一份并返回。

            注意:返回值是从字符串常量池中寻找后返回的结果。
         */
        s3.intern();

        String s4 = "hello";

        System.out.println(s3 == s4);//true
        //System.out.println(result == s4);

    }

    @Test
    public void test2(){
        String s1 = "hel";
        String s2 = "lo";
        String s3 = s1 + s2;
        String s4 = "hello";
         /*
            intern() : 调用该方法时会直接去字符串常量池中寻找有没有该内容。如果有直接返回。
                如果没有往字符串常量池中放一份并返回。

            注意:返回值是从字符串常量池中寻找后返回的结果。
         */
        s3.intern(); //因为常量池中已经有hello了所以s3是不会再放到常量池中的
        System.out.println(s3 == s4);//false

    }
}

5.String的API

拼接 +

比较 equals 从第一个字母开始比较  同则后推

忽视大小写 equalsIgnoreCase

比较内容 CompareTo

同样也可忽视大小写CompareToIgnoreCase

Loca。China 转中文拼音

import org.junit.Test;

import java.text.Collator;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Locale;

public class StringAPITest {
    /*
     * static String copyValueOf(char[] data): 返回指定数组中表示该字符序列的 String
     * static String copyValueOf(char[] data, int offset, int count):返回指定数组中表示该字符序列的 String
     * static String valueOf(char[] data)  : 返回指定数组中表示该字符序列的 String
     * static String valueOf(char[] data, int offset, int count) : 返回指定数组中表示该字符序列的 String
     * static String valueOf(xx  value):xx支持各种数据类型,返回各种数据类型的value参数的字符串表示形式。
     */
    @Test
    public void test(){
        char[] cs = {'a','b','c','d','e','f'};
        String s = String.copyValueOf(cs);
        System.out.println(s);

        String s2 = String.copyValueOf(cs, 1, 2);
        System.out.println(s2);

        //基本数据类型 -> 字符串
        String s3 = String.valueOf(11);
    }

    /*
        字符串拼接
     */
    @Test
    public void test2(){
        String s = "a".concat("b");//底层new String
        String s2 = "a" + "b";

        //字符串比较
        boolean bo = "abc".equals("abd");//比较字符串的内容(比较每一个字符)
    }
    @Test
    public void test3(){
        System.out.println("abc".equals("AbC"));//false
        //比较内容 -忽略大小写
        System.out.println("abc".equalsIgnoreCase("ABC"));//true

        System.out.println("abc".compareTo("bde"));//比较内容 - 可以用来排序

        System.out.println("===================================================");

        System.out.println("a".compareTo("A"));
        System.out.println("a".compareToIgnoreCase("A"));//比较内容时忽略大小写
    }


    @Test
    public void test4(){

        String[] names = {"aa","cc","bb","dd"};

        Arrays.sort(names);

        System.out.println(Arrays.toString(names));

        System.out.println("======================================");

        String[] names2 = {"宝宝","弟弟","姐姐","哥哥"};

        Arrays.sort(names2, new Comparator<String>() {//我们传一个Comparator接口的实现类的对象目的是自己定义排序规则
            @Override
            public int compare(String o1, String o2) {
                Collator collator = Collator.getInstance(Locale.CHINA);
                return collator.compare(o1,o2);//该方法中做了两件事①将文字转换成拼音 ②对拼音进行比较
            }
        });

        System.out.println(Arrays.toString(names2));
    }
}

空串与null

import org.junit.Test;

public class StringAPITest2 {

    /*
        空字符串
     */
    @Test
    public void test(){
        String s = "";
        String s2 = null;
        String s3 = new String();//空串 - “”

        //isEmpty() : 字符串的内容是否为空
        System.out.println(s.isEmpty());
        System.out.println(s3.isEmpty());
        //System.out.println(s2.isEmpty());//NullPointerException

    }
    @Test
    public void test2(){

        char[] cs = {}; //char[] cs = new char[0];
        //空串
        String s = new String(cs);

        stringCheck(null);
    }
    public void stringCheck(String str){
        //如果是空串或null就不处理了

        if (str == null || str.isEmpty()){
            System.out.println("不需要处理");
        }



        /*
        下面的写法不对 如果传的是一个null 就会发生空指针异常
        if (str.isEmpty() || str == null ){
            System.out.println("不需要处理");
        }

         */
    }

    /*
        一个变量和一个双引号引起来的字符串进行内容比较
        最好是双引号引起来字符串在前面 调用equals方法 为了避免空指针异常
     */
    @Test
    public void test3(){
        String s = null;
        //System.out.println(s.equals("aaa")); // 如果s为null直接就空指针异常了
        System.out.println("aaa".equals(s));//这个好 s为null也不会发生空指针异常
    }

    @Test
    public void test4(){
        String s = "a";
        String s2 = "b";
        String s3 = s + s2;
    }
}

长度 int length

String toLowerCase 转字符串中字母为小写

String toUpperCase转字符串中字母为大写

boolean startsWith(xx) 是否以xx开头

boolean endsWith(xx) 是否以xx结尾

String trim() 去掉字符串前后空白行

boolean contains(xx)是否包含xx

int indexOf(xx)从前往后在字符串中找xx 返回第一次下标没有返回-1

int lastIndexOf(xx)从后往前在字符串中找xx返回最后一次下标没有返回-1

String substring(int beginIndex)返回新字符串

String substring(int beginIndex, int endIndex) :返回一个新字符串,
它是此字符串从beginIndex开始截取到endIndex(不包含)的一个子字符串。
    
char charAt(index):返回[index]位置的字符

char[] toCharArray(): 将此字符串转换为一个新的字符数组返回
将字符数组转为String对象,可以使用之前介绍过的构造器和静态方法valueOf或copyValueOf等

import org.junit.Test;

import java.util.Arrays;

public class StringAPITest3 {

    /*
        int length():返回字符串的长度
        String toLowerCase():将字符串中大写字母转为小写
        String toUpperCase():将字符串中小写字母转为大写
     */
    @Test
    public void test(){
        System.out.println("abc".length());
        System.out.println("abCDEf".toLowerCase());
        System.out.println("abCDEf".toUpperCase());
    }
    /*
    (4)boolean startsWith(xx):是否以xx开头
    (5)boolean endsWith(xx):是否以xx结尾
    (6)String trim():去掉字符串前后空白符
    (7)boolean contains(xx):是否包含xx
    (8)int indexOf(xx):从前往后找当前字符串中xx,即如果有返回第一次出现的下标,要是没有返回-1
    (9)int lastIndexOf(xx):从后往前找当前字符串中xx,即如果有返回最后一次出现的下标,要是没有返回-1
     */
    @Test
    public void test2(){
        System.out.println("abcdef".startsWith("acbc"));
        System.out.println("如何让龙哥挣1个亿.txt".endsWith(".txt"));
        System.out.println("   a    b     ".trim());
        System.out.println("abclonggeaaaheihei".contains("longge"));

        System.out.println("=====================");

        System.out.println("ffabcddabceeabc".indexOf("abc"));
        System.out.println("ffabcddabceeabc".lastIndexOf("abc"));
    }

    /*
    (10)String substring(int beginIndex) :返回一个新的字符串,
        它是此字符串的从beginIndex开始截取到最后的一个子字符串。

    (11)String substring(int beginIndex, int endIndex) :返回一个新字符串,
    它是此字符串从beginIndex开始截取到endIndex(不包含)的一个子字符串。
    
    (12)char charAt(index):返回[index]位置的字符

    (13)char[] toCharArray(): 将此字符串转换为一个新的字符数组返回
    将字符数组转为String对象,可以使用之前介绍过的构造器和静态方法valueOf或copyValueOf等
     */
    @Test
    public void test3(){
        System.out.println("abclongge".substring(3));
        System.out.println("abclongge".substring(3,8));

        String s = "abcde";
        for (int i = 0; i < s.length(); i++) {
            System.out.println(s.charAt(i));
        }

        System.out.println("===================================");
        char[] charArray = s.toCharArray();
        System.out.println(Arrays.toString(charArray));
    }
}

6.String的内存图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值