JAVA常用类之Scanner、String

Scanner(用于接收键盘录入数据)

Scanner的概述和构造方法原理
  • 概念:JDK5以后用于获取用户的键盘输入
  • Scanner的构造方法原理:
    Scanner(InputStream source);构造一个新的Scanner,它生成的值是从指定输入流扫描的。
    
    System类下有一个静态的字段:
    public static final InputStream in;//标准的输入流,对应着键盘录入
    
Scanner类的hasNextXxx()和nextXxx()方法的讲解
  • 格式:
    a. 判断下一个是否是某种类型的元素,其中Xxx可以是Int,Double等。如果需要判断是否包含下一个字符串,则可以省略Xxx
    hasNextXxx()
    
    b.获取下一个输入项。Xxx的含义和上个方法中的Xxx相同
    nextXxx()
    
  • hasNextXXX()的用法示例:(这里主要是一些oj题目经常用到的!)
    例如:根据输入(无限行)打印杨辉三角形(对应的无限多个)
    public class Main11 {
        public static void main(String[] args) {
            Scanner scanner = new Scanner(System.in);
            while (scanner.hasNextInt()) {
                int x = scanner.nextInt();
                printYangHuiTriangles(x);
                System.out.println("");
            }
        }
    
        private static void printYangHuiTriangles(int x) {
            int[][] arr = new int[x][x];
            for(int i=0;i<x;i++){
                for(int j=0;j<=i;j++){
                    if(j==0||(i==j)){
                        arr[i][j] = 1;
                    }else{
                        arr[i][j] = arr[i-1][j] + arr[i-1][j-1];
                    }
                }
            }
    
            for(int i=0;i<x;i++){
                for(int j=0;j<=i;j++){
    
                    if(j==i){
                        System.out.print(arr[i][j]+" \n");
                    }else{
                        System.out.print(arr[i][j] + " ");
                    }
    
                }
            }
        }
    }
    ---------------------------
    输出:
    1
    1 
    
    2
    1 
    1 1 
    
    5
    1 
    1 1 
    1 2 1 
    1 3 3 1 
    1 4 6 4 1 
    
Scanner获取数据出现的小问题及解决方案
  • 两种常用的方法:
    a. 录入基本类型:
    scanner.nextXXX();
    
    b. 录入字符串:
    scanner.nextLine();
    
    读取一整行,包括中间的空格!
    scanner.next();
    
    读取一部分数据,以空格作为分隔符,空格后的数据读取不到!
  • 注意:使用nextLine()方法时,你先录入整数,再录入字符串,会导致字符串录入不进去,相当于nextLine()方法只录入了一个输入数字后的换行符!
  • 解决办法:
    a. 你可以在录入字符串之前,再重新创建一个scanner,然后再进行录入操作!(参考老师上课所演示的!)
    b. 可以直接利用scanner.next()方法(不需要重新创建对象),但是录入的字符串中间不能有空格,如果有空格,则空格后面的内容不录入!(相当于:把所有的数据都先按照字符串获取,然后要什么,你就对应的转换为什么。)
    示例:
    public class Demo {
        public static void main(String[] args) {
            System.out.println("请输入一个数字:");
    
            Scanner scanner = new Scanner(System.in);
            int x = scanner.nextInt();
            System.out.println(x);
            scanner = new Scanner(System.in);
            System.out.println("请输入一个字符串:");
            String xxx = scanner.nextLine();
            System.out.println(xxx);
        }
    }
    ------------------------------
    输出:
    请输入一个数字:
    1
    1
    请输入一个字符串:
    xxxxx
    xxxxx
    

String(字符串)

String类的概述
  • 字符串概念:
    a. 字符串是由多个字符组成的一串数据(字符序列)
    b. 字符串可以看成是字符数组(由JAVA的String源码可得出此结论!)
  • String概述:
    通过JDK提供的API,查看String类的说明可以看到这样的两句话:
    a:字符串字面值"abc"也可以看成是一个字符串对象。
    b:字符串是常量,一旦被创建,就不能被改变。
String类的构造方法
  • 常见的构造方法(构造方法重载)
    public String():空构造
    public String(String original):把字符串常量值转成字符串
    public String(byte[] bytes):把字节数组转成字符串	
    public String(byte[] bytes,int index,int length):把字节数组的一部分转成字符串(index:表示的是从第几个索引开始, length表示的是长度)
    public String(char[] value):把字符数组转成字符串
    public String(char[] value,int index,int count):把字符数组的一部分转成字符串
    
  • 注意:String 类重写了Object类中的toString()方法,所以调用println()方法时,会调用String.toString()的方法去打印字符串的内容!
  • 示例:(把字节数组转换为字符串)
    byte[] bytes={97,98,99,100,101};
    String s = new String(bytes);
    System.out.println(s);
    ----------------------------------
    输出:
    abcde
    
  • 示例2:(把字节数组的一部分转换成字符串!,注意索引越界问题)
    String s1 = new String(bytes,3,2)//从第三个元素起,取两个元素进行转换!
    System.out.println(s1)
    --------------------
    输出:
    de
    
  • 示例3:(把一个字符数组转换成字符串:)
    char[] chars = {'a','b','c','d','你','好'}
    String s = new String(chars)
    System.out.println(s)
    --------------------------------
    输出:
    abcd你好
    
    同样的,也可以只转换一部分!
  • 示例4:( 返回此字符串的长度。 )
    public class Demo {
        public static void main(String[] args) {
            char[] chars = {'a', 'b', 'c', 'd', '你', '好'};
            String s = new String(chars);
            System.out.println(s.length());
        }
    }
    ---------------------
    输出:
    6
    
String的特点:
  • String 类代表字符串。Java程序中的所有字符串字面值(如:“abc”)都作为此类的实例(也就是说"abc"也是一个String类的对象)实现!
    示例:(两者都能调用String类的.length()方法)

    String s1 = new String("abcdef")
    int length1 = s1.length();
    -------------------------------
    int lenght2 = "我爱你们".length();
    
  • 定义字符串的两种方式:
    示例:参考运行时常量池(JAVA内存详解的那篇文章)可知,其实这二者是不一样的

    String s1 = "我爱你们";
    Stinrg s2 = new String("我爱你们");
    

    常量池的一些现象:(具体原因也可以参考上面说的常量池的文章!)

    public class Demo {
        public static void main(String[] args) {
            String s1 = new String("我爱你们!");
            String s2 = "我爱你们!";
            String s3 = "我爱你们!";
            String s4 = s1.intern();
            System.out.println(s1);
            System.out.println(s2);
            System.out.println(s3);
            System.out.println(s4);
            System.out.println(s1 == s2);
            System.out.println(s2 == s3);
            System.out.println(s3 == s4);
            System.out.println(s1 == s4);
        }
    }
    ---------------------
    输出:
    我爱你们!
    我爱你们!
    我爱你们!
    我爱你们!
    false
    true
    true
    false
    
  • 字符串是常量:
    a. 一旦被创建就不能改变 因为字符串的值是在方法区的常量池中划分空间 分配地址值的
    b. 它们的值在创建后不能改变,能变的只是指向!(引用本身可以指向别的地方!)

    String s = "hello" ; 
    s =  "world" + "java"; 问s的结果是多少?
    

    参考图示:(s的指向发生了变化,但原来的字符串都没变!)
    在这里插入图片描述

  • 字符串:new 和 直接赋值有没有区别?

    • 注意:==号判断两个对象时(JAVA一切皆对象),判断的是地址值是否相同!
    • 参考老师上课画的内存图和上课的代码!(相当于解释了我上面记述的常量池的一些现象!)
    • 参考上课所讲述的JAVA字符串的一篇博客
    • 问题:在上课讲述的过程中,提到了编译期无法确定,进而无法优化的问题。为什么编译期无法优化的问题?在运行期间(执行代码时,应该已经确定了!)还是按照编译期编译的结果输出?这个感觉不合理!
String类的常见面试题
  • 示例1:

    String s = new String(“hello”)和String s = “hello”;的区别
    
  • 示例1解析图示:(两个实际指向的对象是同一个,但是无法通过简单的==来进行判断,里面存在一层对象引用转换的问题!)
    在这里插入图片描述* 示例2:

    ==equals()的区别?
    

    "=="判断的是两个对象的地址值是否相同
    "=="号对于基本类型来说,判断的是数值是否相同,而对于引用类型来说,判断的是引用的地址是否相同

  • 示例3:(判等)

    String s1 = new String("hello");
    String s2 = new String("hello");
    System.out.println(s1 == s2);
    System.out.println(s1.equals(s2));
    ---------------
    输出:
    false
    true
    
    String s3 = new String("hello");
    String s4 = "hello";
    System.out.println(s3 == s4);
    System.out.println(s3.equals(s4));
    --------------------
    输出:
    false
    true
    
    String s5 = "hello";
    String s6 = "hello";
    System.out.println(s5 == s6);
    System.out.println(s5.equals(s6));
    ------------------
    输出:
    true
    true
    
String类的判断功能
  • 比较字符串的内容是否相同,区分大小写:
    public boolean equals(Object obj)
    
  • 比较字符串的内容是否相同,忽略大小写:
    public boolean equalsIgnoreCase(String str)
    
  • 判断字符串中是否包含传递进来的字符串:
    public boolean contains(String str)
    
  • 判断字符串是否以传递进来的字符串开头:
    public boolean startsWith(String str)
    
  • 判断字符串是否以传递进来的字符串结尾:
    public boolean endsWith(String str)
    
  • 判断字符串的内容是否为空串"":
    public boolean isEmpty()
    
案例:(模拟用户登录取款)
  • 示例:
    public class Demo {
        public static void main(String[] args) {
            String name = "张三";
            String password = "123456";
            int n_chance = 3;
            int p_chance = 3;
            Scanner scanner = new Scanner(System.in);
            n1:while(n_chance > 0){
                System.out.println("请输入您的用户名:"+"剩余机会数为:"+n_chance--);
                if (name.equals(scanner.nextLine())){
                    n2:while (p_chance > 0){
                        System.out.println("请输入您的密码:"+"剩余机会次数为:"+p_chance--);
                        if(password.equals(scanner.nextLine())){
                            System.out.println("您输入的正确!");
                            return ;
                        }else{
                            System.out.println("您输入用户密码的不正确!");
                        }
                    }
                    System.out.println("您的密码输入机会已经用尽,卡号已经被冻结!");
                    return;
                }else{
                    System.out.println("您输入的用户名不正确,请重新输入!");
                }
            }
            System.out.println("您的用户输入有误,请稍后再试!");
        }
    }
    ------------------------------------
    输出:
    请输入您的用户名:剩余机会数为:3
    张三
    请输入您的密码:剩余机会次数为:3
    123
    您输入用户密码的不正确
    请输入您的密码:剩余机会次数为:2
    123456
    您输入的正确!
    
String类的获取功能
  • 获取字符串的长度:
    public int length():
    
  • 获取指定索引位置的字符:
    public char charAt(int index)
    
  • 返回指定字符在此字符串中第一次出现处的索引:
    public int indexOf(int ch)
    int index = "这是一个字符串是".indexOf('是');
    
  • 返回指定字符串在此字符串中第一次出现处的索引:(方法重载)
    public int indexOf(String str)
    int index = "这是一个字符串是".indexOf("字符串")(返回的是“字”(子串的首字符)的索引号)
    
  • 返回指定字符在此字符串中从指定位置后第一次出现处的索引:
    public int indexOf(int ch,int fromIndex)
    
  • 返回指定字符串在此字符串中从指定位置后第一次出现处的索引:(方法重载)
    public int indexOf(String str,int fromIndex)
    
  • 可以顺带提一下lastIndexOf系列(估计与上述内容差不多,只不过是从最后位置开始计算!)
  • 从指定位置开始截取字符串,默认到末尾:
    public String substring(int start)
    
  • 从指定位置开始到指定位置结束截取字符串(含头不含尾)
    public String substring(int start,int end)
    
  • 截取字符串示例:
    public class Demo {
    	public static void main(String[] args) {
            String str = "假如我年少有位不自卑,懂得什么是珍贵";
    		// 根据起始索引,截取到字符串末尾
            String s1 = str.substring(str.indexOf("懂"));
            System.out.println(s1);
    		// 根据首尾索引,截取一部分字符串(含头不含尾,所以要+1)---》 跟Python一样!
            String s2 = str.substring(3, str.indexOf('卑') + 1);
            System.out.println(s2);
        }
    }
    ----------
    输出:
    懂得什么是珍贵
    年少有位不自卑
    
案例: (遍历字符串)
  • 注:也可以直接用字符来进行比较,如:‘b’ > ‘a’:true!
  • 示例:统计一个字符串中大写字母字符,小写字母字符,数字字符出现的次数。
    public class Demo {
        public static void main(String[] args) {
            /*A:
            案例演示:
            需求:统计一个字符串中大写字母字符,小写字母字符,数字字符出现的次数。(不考虑其他字符)*/
            String str="asfdassdfASFSsf1222asdfas5555s4555AFFDDdddaAAA";
            int tag_start = (int)('a');
            int tag_end = (int)('z');
            int upper_start_tag = (int)('A');
            int upper_end_tag = (int)('Z');
            int num=0,_char=0,upper_char = 0;
            for (int i = 0; i < str.length(); i++) {
                int char_num = (int)str.charAt(i);
                if (char_num >= tag_start && char_num < tag_end){
                    _char++;
                }else if(char_num >= upper_start_tag && char_num<= upper_end_tag){
                    upper_char++;
                }else if(char_num >=48 && char_num <=57){
                    num++;
                }
            }
            System.out.println("大写字符有:"+upper_char+"个\n小写字符有:"+_char+"个\n数字字符有:"+num+"个");
        }
    }
    ------------------
    输出:
    大写字符有:12个
    小写字符有:22个
    数字字符有:12
String类的转换功能
  • 把字符串转换为字节数组:
    public byte[] getBytes()
    "asdfas".getBytes()
    
  • 把字符串转换为字符数组:
    public char[] toCharArray()
    String s4 = "我在人民广场吃着炸鸡";
    char[] chars = s4.toCharArray();
    
  • 注意:String类的valueOf方法可以把任意类型的数据转成字符串。
    • 把字符数组转成字符串:
    public static String valueOf(char[] chs)
    new String(chars)//还是调用重载的构造函数!
    String s = new String("asdfas".getBytes());//这种方法也行!
    String s1 = String.valueOf("asdfas".getBytes());
    
    • 把int类型的数据转成字符串:
    public static String valueOf(int i)
    
  • 把字符串转成小写:
    public String toLowerCase()
    "abcd".toLowerCase();//转换为小写的abcd
    
  • 把字符串转成大写:
    public String toUpperCase()
    "abcd".toUpperCase();//转换为大写的ABCD
    
  • 把字符串拼接:(看一下字符串的"xxxx".concat()的源码是如何拼串的?)
    public String concat(String str)
    
案例演示:(按要求转换字符)
  • 示例:把一个字符串的首字母转成大写,其余为小写。(只考虑英文大小写字母字符)
    public class Demo {
        public static void main(String[] args) {
            /*   A:
            案例演示:
            需求:把一个字符串的首字母转成大写,其余为小写。(只考虑英文大小写字母字符)*/
            String s = "acBBDfdaffdfeadfeafdFAAFF";
    
            String first_chars = s.substring(0,1).toUpperCase();
            String other_chars = s.substring(1,s.length()).toLowerCase();
            System.out.println(first_chars.concat(other_chars));
        }
    }
    ----------------------------------------
    输出:
    Acbbdfdaffdfeadfeafdfaaff
    
String类的其他功能:
  • 指定字符进行互换:
    public String replace(char old,char new)
    str.replace('奥','*'); //一次替换一个字符
    
    
  • 将指定字符串进行互换:
    public String replace(String old,String new)
    str.replace("奥巴马","****"); //一次替换一个子字符串
    
  • 去除两端空格:
    public String trim()
    String username = "                  zhangsan               "
    String u3 = username.trim();//====> "zhangsan"
    
  • 相比函数:(好像用的比较少)
    public int compareTo(String str)
    String s = new String("asdfas".getBytes());
    int x = s.compareTo("asdf");
    System.out.println(x);//2
    String s = new String("asdfaa".getBytes());
    int x = s.compareTo("asdfab");
    System.out.println(x);//-1
    -------------------------------
    public int compareToIgnoreCase(String str) 跟上面一样 只是忽略大小写的比较 
    
    小结:(只返回第一个数值不一样的位置的字符值的差值!)
    1. 会对照ASCII 码表 从第一个字母进行减法运算 返回的就是这个减法的结果
    2. 如果前面几个字母一样会根据两个字符串的长度进行减法运算返回的就是这个减法的结果
    3. 如果连个字符串一摸一样 返回的就是0
案例:(去除两端空格)
  • 示例:
    public class Demo {
        public static void main(String[] args) {
            //课堂作业:
            //去除左端空格
            String s4 = "     z   h   a   n   g  s  an     ";
            int index1=0;
            for (int i = 0; i < s4.length(); i++) {
                if(s4.charAt(i)!=' '){
                    index1=i;
                    break;
                }
            }
            String s4_result = s4.substring(index1);
            System.out.println(s4_result);
    
            //去除右端空格
            String s5 = "     z   h   a   n   g  s  an     ";
            int index2 = 0;
            for (int i = s5.length()-1; i>=0; i--) {
                if(s5.charAt(i)!=' '){
                    index2 = i;
                    break;
                }
            }
            String s5_result = s5.substring(0,index2+1);
            System.out.println(s5_result);
    
            //只去除中间空格
            String s6 = "     z   h   a   n   g  s  an     ";
    //        String s6_temp = s6.substring(index1,index2+1);
            String s6_temp = s6.trim();
    
    
            String s6_result="";
            for (int i = 0; i < s6_temp.length(); i++) {
                s6_result = s6_result.concat(s6_temp.substring(i,i+1).trim());
    
            }
            System.out.println(s6.substring(0,index1).concat(s6_result).concat(s6.substring(index2+1)));
    
        }
    }
    -----------------------
    输出:
    z   h   a   n   g  s  an     
         z   h   a   n   g  s  an
         zhangsan     
    
案例:(把数组转成字符串)
  • 示例:把数组中的数据按照指定个格式拼接成一个字符串
    public class Demo {
        public static void main(String[] args) {
           int[] arr = {1,2,3};
           String result="";
            for (int i = 0; i < arr.length; i++) {
                if (i==0){
                    result = result.concat("["+arr[i]+",");
    
                }else if(i==arr.length-1){
                    result = result.concat(arr[i]+"]");
                }else{
                    result = result.concat(""+arr[i]+",");
                }
            }
            System.out.println(result);
        }
    }
    ---------------------------
    输出:
    [1,2,3]
    
案例:(统计大串中小串出现的次数)
  • 示例:

    public class Demo {
        public static void main(String[] args) {
            /* A:
            画图演示
            需求:统计大串中小串出现的次数
            举例:
            "woaijavawozhenaijavawozhendeaijavawozhendehenaijavaxinbuxinwoaijavagun”中java出现了5次*/
            String maxStr="woaijavawozhenaijavawozhendeaijavawozhendehenaijavaxinbuxinwoaijavagun";
            String minStr="java";
            //统计上面这段字符串中java出现了几次
            /*
             * 思路:indexOf("java")
             *
             *
             * */
            int index=0;
            int count =0;
            while(index!=-1){
                index = maxStr.indexOf(minStr);
                if (index!=-1){
                    maxStr = maxStr.substring(index+4);
                    count++;
                }
            }
            System.out.println(count);
        }
    }
    ------------------------
    输出:
    5
    

    这里还有其他思路:(优化方向!)

    1. 比如把"java"字串替换成其他特殊字符,这样统计特殊字符的个数即可。(但是要考虑字串中是否有特殊字符)
    
    2. 把"java"替换成""空字符串,然后统计新得到的字符串长度,然后(原始长度-新的替换后的长度)/4,即可得到"java"字串的个数!
    
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值