zoukankan      html  css  js  c++  java
  • Java基础之:String类

    Java基础之:String类

    String对象用于保存字符串,也就是一组字符序列

    常量对象:字符串常量对象是用双引号括起来的字符序列,例如:"小范",”12.34“,”xiaofan“等

    字符串的字符使用Unicode字符编码,一个字符(不区分字母还是汉字)占两个字节。

     

    String对象的两种创建方式

    第一种:String s1 = "xiaofan";

    第二种:String s2 = new String("xiaofan");

    说明:

    方法一是直接赋值,而方法二是调用构造器。方法一会直接将引用指向常量池中的”xiaofan“,而方法二会先在堆中创建一个空间,在此空间中放入指向常量池"xiaofan"的地址,再让栈空间的对象名指向堆地址。

     

    由于这两种创建方式的不同指向,会出现很多字符串比较是否相等上的问题。

    简单案例

    package class_string;
    ​
    public class ClassTest {
    ​
        public static void main(String[] args) {
    ​
            String s = "hello"; //常量池中创建hello,指向它
            String ss = new String ("hello");   //堆中创建对象,指向常量池中的hello
            System.out.println(s.equals(ss));   //比较内容,T
            System.out.println(s == ss);    //比较地址,F
            
            String a = "abc";
            String b = "abc"; // 因为上面a已经在常量池中创建了abc,所以b直接指向b就可以了
            System.out.println(a.equals(b));    //比较内容,T
            System.out.println(a == b); //比较地址,T
            
            String x = new String("XYZ");   
            String y = new String("XYZ"); //x、y都在堆中创建了对象,但它们的对象都指向常量池中的XYZ
            System.out.println(x.equals(y));    //比较内容,T
            System.out.println(x == y); //比较地址,F
            
            System.out.println("============");
            
            String a1 = "abc"; // a1指向 常量池
            String b1 =new String("abc");//b1 指向堆
            System.out.println(a1.equals(b1)); //T , 比较内容
            System.out.println(a1==b1); // F,比较地址
            System.out.println(a1==b1.intern()); //T , b1.intern() 指向常量池的”abc”
            System.out.println(b1==b1.intern());//F  , 对象b1的堆地址和常量池中"abc"的地址比较
            
            /*  b1.intern() 方法最终返回的是常量池的地址(对象)
             *  当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串
             * (用 equals(Object) 方法确定),则返回池中的字符串。
             *  否则,将此 String 对象添加到池中,并返回此 String 对象的引用
             */
            
            System.out.println("============");
            
            class Person{
                private String name;
            }
            
            Person p1 = new Person();
            p1.name = "chuannong"; 
            Person p2 = new Person();
            p2.name = new String("chuannong");
    ​
            System.out.println(p1.name.equals(p2.name));  //T
            System.out.println(p1.name == p2.name);     //F,p1.name 指向常量池,p2.name 指向堆空间 
            System.out.println(p1.name == "chuannong");   //T
            System.out.println(p1.name.intern());   //返回"chuannong"
        }
    }
    

      

    字符串的特性

    可以从最开始介绍String类的时候看到,它的对象底层是保存在一个final数组中的。

    所以对于String对象保存的字符串来所,一个字符串对象一旦分配,其内容就是不可变的。

    package class_string;
    /**
     *  String is final
     */
    public class ClassTest02 {
        public static void main(String[] args) {
            //在常量池中创建了两个对象,"abc"、"hello"
            String a = "abc";
            a = "hello";
            
            //在常量池中创建了一个对象,"abchello",可以理解为,abc与hello并没有被指向引用,所以不需要创建
            String b = "abc" + "hello"; //编译器会自动的处理"+",将abc 和 hello 拼接起来
            
            //在常量池中创建了三个对象,"xiao"、"fan"、"xiaofan"
            String c = "xiao";  //有c指向"xiao",所以创建
            String d = "fan";   //同理
            String e = c + d ;
            
            /*
             * 因为String对象 底层是放在  private final char value[]; 这里面的
             * 所以String是final的,若想要进行拼接或更改字符串,只能是重新在常量池中创建对象
             */
        }
    }

     

    String类使用

    了解了String对象两种声明方式不同,以及字符串特性之后。就又会出现一些对于字符串声明上的问题。

    简单案例

    package class_string;
    ​
    public class ClassTest03 {
        
        String str = new String("good");
        final char[] ch = { 't', 'e', 's', 't' };
    ​
        public static void main(String[] args) {
            ClassTest03 ex = new ClassTest03();
            ex.change(ex.str, ex.ch);
            System.out.print(ex.str + " and ");
            System.out.println(ex.ch);
        }
    ​
        public void change(String str, char ch[]) {
            str = "test";
            ch[0] = 'g';
        }
    }

    程序输出:good and gest

    案例理解:

    1. 程序加载时,首先在栈空间创建main方法空间,创建ex对象

    2. 在ex对象的堆空间中,创建一个String引用str指向另外一个堆空间,此堆空间中放"good"在常量池中的地址

    3. 在ex对象的堆空间中,创建一个char[]引用ch 指向另外一个堆空间,此堆空间存放 { 't', 'e', 's', 't' }

    4. 在栈空间中创建change方法空间,传入对象ex的str与ch引用地址

    5. str = "test" ,在常量池中创建"test",返回给str,即将change方法中的str的引用改变,不再指向堆空间的地址,而变为指向常量池中的"test"

    6. ch[0] = 'g' ,将change方法中的ch[0]该为g,即直接改变堆空间中的ch数组

    7. change方法结束,change方法空间销毁,此时 main方法空间中的str并没有改变,ch数组的第一个改变为g,常量池中多了一个"test"。

     

    String类的常用方法

    第一部分:

    package class_string;
    public class StringMethods {
        public static void main(String[] args) {
            String username = "JOHN";
            // 2.equalsIgnoreCase 忽略大小写的判断内容是否相等
            if ("john".equalsIgnoreCase(username)) {
                System.out.println("Success!");
            } else {
                System.out.println("Failure!");
            }
            // 3.length 获取字符的个数,字符串的长度
            System.out.println("小范".length());  //输出:2
            // 4.indexOf 获取字符在字符串对象中第一次出现的索引,索引从0开始,如果找不到,返回-1
            String s1 = "wer@terwe@g";
            int index = s1.indexOf('@');
            System.out.println(index);//输出:3
            // 5.lastIndexOf 获取字符子啊字符串中最后一次出现的索引,索引从0开始,如果找不到,返回-1
            String s2 = "wer@terwe@g@";
            int index2 = s1.lastIndexOf('@');
            System.out.println(index);//输出:3
            // 6.substring 截取指定范围的子串
            String name = "hello,小范";
            System.out.println(name.substring(6));// 截取后面的字符,输出:小范
            System.out.println(name.substring(0, 5));//输出:hello
        }
    }
    

      

    第二部分:

    package class_string;
    ​
    public class StringMethods02 {
    ​
        public static void main(String[] args) {
            // 1.toUpperCase转换成大写
            String s = "heLLo";
            System.out.println(s.toUpperCase());
            // 2.toLowerCase
            System.out.println(s.toLowerCase());
            // 3.concat拼接字符串
            String s1 = "小范";
            s1 = s1.concat("小黄").concat("小雨").concat("together");
            System.out.println(s1);
            // 4.replace 替换字符串中的字符
            String s2 = "小范 and 小黄 小黄 小黄 小黄";
            s2 = s2.replace("小黄", "小雨");
            System.out.println(s2);
            // 5.split 分割字符串, 对于某些分割字符,我们需要 转义比如 | \等
            System.out.println("======================");
            String poem = "鹅鹅鹅,曲项向天歌,白毛浮绿水,红掌拨清波";
            String[] split = poem.split(",");
            for (int i = 0; i < split.length; i++) {
                System.out.println(split[i]);
            }
            System.out.println("======================");
            String poem2 = "E:\附加项目\附加-project";
            String[] split3 = poem2.split("\\");
            for (int i = 0; i < split3.length; i++) {
                System.out.println(split3[i]);
            }
            // 6.toCharArray 转换成字符数组
            System.out.println("======================");
            String s4 = "happy";
            char[] chs = s4.toCharArray();
            for (int i = 0; i < chs.length; i++) {
                System.out.println(chs[i]);
            }
            // 7.compareTo 比较两个字符串的大小,如果前者大,则返回正数,后者大,则返回负数,如果相等,返回0
            System.out.println("======================");
            String a = "jchn";
            String b = "jack";
            System.out.println(a.compareTo(b)); // 返回值是 'c' - 'a' = 2的值
            System.out.println("a".compareTo("d")); // 返回值是 'a' - 'd' = -3的值
            System.out.println("a".compareTo("a")); // 返回值是 'a' - 'a' = 0的值
    ​
            // 8.format 格式字符串
            /*
             * 占位符有: %s 字符串 %c 字符 %d 整型 %.2f 浮点型
             * 
             */
            System.out.println("======================");
            String name = "john";
            int age = 10;
            double score = 98.3 / 3;
            char gender = '男';
            // String info =
            // "我的姓名是"+name+"年龄是"+age+",成绩是"+score+"性别是"+gender+"。希望大家喜欢我!";
            String info = String.format("我的姓名是%s年龄是%d,成绩是%.2f性别是%c.希望大家喜欢我!", name, age, score, gender);
            System.out.println(info);
        }
    }

    程序输出:

    HELLO

    hello

    小范小黄小雨together

    小范 and 小雨 小雨 小雨 小雨

    ========================

    鹅鹅鹅

    曲项向天歌

    白毛浮绿水

    红掌拨清波

    ========================

    E:

    附加项目

    附加-project

    ========================

    h a p p y

    ========================

    2 -3 0

    ========================

    我的姓名是john年龄是10,成绩是32.77性别是男.希望大家喜欢我!

     

    简单应用案例

    package class_string;
    ​
    import java.util.Scanner;
    ​
    /**
     *   判断邮箱是否合法,要求里面必须包含@和.    而且 @ 必须在. 的前面
        案例:不使用系统提供的trim 方法,自己写一个myTrim方法,去除字符串两端的空格,
        比如 "     hello world   "  => 返回 “hello world”
     */
    public class ClassWork01 {
    ​
        public static void main(String[] args) {
            Scanner scanner = new Scanner(System.in);
            System.out.println("请输入邮箱:");
            String email =  scanner.next();
            if(legalEmail(myTrim(email))) {
                System.out.println("输入正确,你的Email地址为:" + email);
            }else {
                System.out.println("输入错误!");
            }
        }
        
        public static String myTrim(String email) {
            String temp = "";
            for(int i = 0;i<email.length();i++) {   //去除前面的空格
                if(email.charAt(i) != ' ') {
                    temp = email.substring(i);
                    break;
                }
            }
            
            for(int i = temp.length() - 1;i >= 0;i--) { //去除后面的空格
                if(temp.charAt(i) != ' ') {
                    email = temp.substring(0,i);
                    break;
                }
            }
            return email;
        }
        
        public static boolean legalEmail(String email) {
            
            if(email.indexOf("@") < 0 && email.indexOf(".") < 0) {  //没有@和.
                return false;
            }else {
                if(email.indexOf("@") != email.lastIndexOf("@")) {  //不止一个@
                    return false;
                }else {
                    if(email.indexOf("@") > email.indexOf(".")) {   //"."不在@之后
                        return false;
                    }
                }
            }
            return true;
        }
    }
    

      

     

  • 相关阅读:
    铁轨
    POJ 2385 -- Apple Catching
    POJ 3258 -- River Hopscotch
    POJ 1469 -- COURSES (二分匹配)
    POJ 2349 -- Arctic Network
    最小生成树
    NOIP200703守望者的逃离
    NOIP200706字符串的展开
    POJ 1036 -- Gangsters
    POJ 1952 -- BUY LOW, BUY LOWER
  • 原文地址:https://www.cnblogs.com/SongHai/p/14159286.html
Copyright © 2011-2022 走看看