Scanner的概述和构造方法原理
概述:JDK5以后用于获取用户的键盘输入
Scanner的构造方法原理:
Scanner(InputStream source)
System类下有一个静态字段:
public static final InputStream in ;标准的输入流,对应着键盘录入。
Scanner类的hasNextXxx()和nextXxx()方法
基本格式:
hasNextXxx()判断下一个是否是某种类型的元素,其中Xxx可以是int、double等。如果需要判断是否包含下一个字符串,可以省略Xxx。
nextXxx()获取下一个输入项。Xxx的含义和上个方法中的Xxx相同。
案例演示
我们分别就nextXxx方法和hasNextXxx方法进行演示
import java.util.Scanner;
public class Demo1{
public static void main (String [] args){
//Scanner(InputStream source)构造一个新的Scanner,它生成的值是从指定的输入流扫描的
Scanner scanner = new Scanner(System.in);
scanner.close();//释放资源
//这里的System.in对应的就是InputStream source,我们分开来写
InputStream myIn = System.in;
//System.in是直接通过类名System来调用in方法的,说明in方法是静态的
//public static final InputStream in “标准”输入流。此流已打开并准备提供输入数据。通常用于键盘输入。
Scanner scanner1 = new Scanner(myIn);
//Scanner 类中常用的方法有两个:nextXxx和hasNextXxx
/*hasNextXxx() 判断下一个是否是某种类型的元素,其中Xxx可以是Int,Double等。
如果需要判断是否包含下一个字符串,则可以省略Xxx
nextXxx() 获取下一个输入项。Xxx的含义和上个方法中的Xxx相同*/
//先来看第一个方法nextXxx,比如现在我想要一个Int类型的变量
System.out.println("请输入一个整数");
int i = scanner1.nextInt();
System.out.println(i);
scanner1.close();
}
}
这样就完成了从键盘输入到控制台输出。
这样做有一些小的问题,比如说我从键盘输入时不小心输入了别的类型,那么程序就会崩溃掉
我们可以在输入前先用hasNextXxx来判断一下输入的是不是我想要的类型再选择是否输出它
请看下一个案例:
import java.util.Scanner;
public class Demo2{
public static void main(String[] args){
System.out.println("请输入一个整数");
Scanner scanner2 = new Scanner(System.in);
//用hasNextXxx来判断一下输入的是不是我想要的类型再选择是否输出它
boolean hasNextInt = scanner2.hasNextInt();
if (hasNextInt) {
int i1 = scanner2.nextInt();
System.out.println(i1);
} else {
System.out.println("你输入的不是整数类型");
}
}
}
public class Demo2-2 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (true) {
System.out.println("请输入一个整数");
if (sc.hasNextInt()) {
int num = sc.nextInt();
break;
} else {
sc = new Scanner(System.in);
System.out.println("输入的类型不正确,请重新输入一个整数");
}
}
}
}
hasNext()方法
hasNextXxx()方法我们已经了解了,那么hasNext()方法又是怎么一回事呢?
hsaNextXxx()如果需要判断是否包含下一个字符串,则可以省略Xxx
hasNext()这个方法是如果此扫描器的输入中有另一个标记,则返回 true。
在等待要扫描的输入时,此方法可能阻塞。扫描器将不执行任何输入。所以循环会一直下去。
你可以设置一个终止符,调用hasNext()的重载方法hasNext(String patten):
如果下一个标记与从指定字符串构造的模式匹配,则返回 true。扫描器不执行任何输入。
例:以输入"0",结束输出
import java.util.Scanner;
public class Demo3{
public static void main(String[] args){
System.out.println("请输入,以0结束:");
Scanner sc = new Scanner(System.in);
while (!sc.hasNext("0")) {
System.out.println(sc.next());
}
sc.close();
}
}
//这个案例大家最好自己去试试效果比较好,我在这里文字演示一下:
请输入,以0结束:
输入:sadjfalskgjlksg
输出:sadjfalskgjlksg
输入:vnuieargqorewqlwglajsdflknav
输出:vnuieargqorewqlwglajsdflknav
输入:1234567
输出:1234567
输入:0
结束
常用的nextXxx()方法
1、nextLine():录入字符串。next()也可以录入字符串。
它们有什么区别呢?
nextLine()方法会把回车换行空格都录入进去
next()碰到回车换行空格就停止录入了
import java.util.Scanner;
public class Demo4 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入字符创1:");
String nextLine = scanner.nextLine();
System.out.println(nextLine);
System.out.println("请输入字符创2:");
String next = scanner.next();
System.out.println(next);
scanner.close();
}
}
请输入字符创1:
我真的 是个 好人
我真的 是个 好人
请输入字符创2:
我 真的 是个 好 人
我
import java.util.Scanner;
public class Demo5 {
public static void main(String[] args) {
int number = ScannerUtils.getNumber();
System.out.println(number);
}
}
//键盘输入工具类:获取一个int类型的数据,类型错误会再次获取直到正确为止
class ScannerUtils {
private ScannerUtils() {
}
public static int getNumber() {
Scanner sc = new Scanner(System.in);
int num;
while (true) {
System.out.println("请输入一个整数:");
if (sc.hasNextInt()) {
num = sc.nextInt();
break;
} else {
//第一次获取数据类型失败后,要重写创建一个人键盘录入对象获取数据
sc = new Scanner(System.in);
System.out.println("输入的类型不正确,请重新输入一个整数");
}
}
return num;
}
}
String类概述
字符串是由多个字符组成的一串数据(字符序列),字符串可以看成是字符数组。
我们查看JDK+API来看String类的说明:
String类代表字符串。 Java程序中的所有字符串文字(例如"abc" )都被实现为此类的实例。
字符串不变; 它们的值在创建后不能被更改。 字符串缓冲区支持可变字符串。 因为String对象是不可变的,它们可以被共享。 例如:
String str = "abc";
相当于:
char data[] = {'a', 'b', 'c'};
String str = new String(data);
所以说String类是java中唯一一个不用new就可以创建对象的类。
String类常见的构造方法
public String():空构造
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):把字符数组的一部分转成字符串
public String(String original):把字符串常量值转成字符串
public class StringDemo1 {
public static void main(String[] args) {
//1、public String():空构造——初始化一个新建的String对象,使其表示一个空字符序列
String s1 = new String();
System.out.println(s1); // ""
//2、public String(byte[] bytes):把字节数组转成字符串
byte[] bytes = {97, 98, 99, 100, 101, 102, 103};
String s2 = new String(bytes);
System.out.println(s2); //abcdefg
//3、public String(byte[] bytes,int index,int length):把字节数组的一部分转成字符串
// (index:表示的是从第几个索引开始, length表示的是长度)
String s3 = new String(bytes, 0, 3);//从字节数组第1个元素开始的3个元素转换为字符串
System.out.println(s3); //abc
//4、public String( char[] value):把字符数组转化为字符串
char[] chars = {'a', 'A', '你', '好'};
String s4 = new String(chars);
System.out.println(s4); //aA你好
//5、public String(char[] value,int index,int count):把字符数组的一部分转成字符串
String s5 = new String(chars, 2, 2);
System.out.println(s5); //你好
//6、public String(String original):把字符串常量值转成字符串
//初始化新创建的String对象,使其表示与参数相同的字符序列;
//换句话说,新创建的字符串是参数字符串的副本。
String s6 = new String("123ABC");
String s7 = "123ABC"; //简写
System.out.println(s6 + "-----" + s7); //123ABC-----123ABC
//两者没有任何区别,但是创建方法完全不同,下面有讲解
}
}
如何获取字符串的长度?
public int length():返回此字符串的长度。
public class StringDmeo2 {
public static void main(String[] args) {
String s = "abcde";
int length = s.length();
System.out.println(length); //5
}
}
String类的特点——常量
String类的特点:一旦被创建就不能被改变,因为字符串的值是在方法区的常量池中划分空间,分配地址值的;
来看一个小案例:
public class StringDemo3{
public static void main(String[] args){
String s = "hello";
s += "world";
System.out.println(s); //helloworld
}
}
我们已经讲到了String类实例一旦被创建就不能改变,那么为什么输出的仍然是helloworld呢?
原因在于:内容不能变,引用可以变
我们画内存图就可以解释:
Q1——String s = new String(“hello”);和String s = “hello”;的区别?
String s = new String(“hello”);会创建2(1)个对象,而String s = “hello”;会创建1(0)个对象。
public class Question1 {
public static void main(String[] args) {
String s1 = new String ("hello");
String s2 = "hello";
String s3 = "hello";
System.out.println(s1==s2); //false
//比较s1和s2的地址值,分别为0x0001和0x001
System.out.println(s2==s3); //true
//比较s2和s3的地址值,都是0x001
System.out.println(s1.equals(s2)); //true
//比较s1和s2的内容
}
}
三者的内容都是hello,为什么会造成这种结果呢?
我们上篇文章已经讲到了==比较引用类型判断的是地址值,而String类的equals方法比较引用类型判断的是内容。
String s1 = new String(“hello”);在堆内存中创建了一个对象 ,在方法区中的字符串常量池中创建了一个”hello”常量值, 地址0x001; 指向new String();
new String()本身就是new出来的,所以也有一个地址值0x0001; 赋值给String s1,指向了String s1;
String s2 直接赋值,在常量池里找,有就直接赋值,把”hello”的地址0x001给了String s2 ,String s2指向了常量池里的”hello” ;
String s3直接赋值,跟s2一样,去常量池里找把”hello”的地址0x001给了String s3,String s3指向了常量池里的”hello” 。
Q2——==和equals()的区别?
上篇文章已经仔细讲过,这里简单再总结一下:
==是一个比较运算符,它能比较基本数据类型,也能比较引用数据类型。
当比较的是基本数据类型时,比较的是两个值是否相同(其实也是在比方法区常量池中的地址),当比较的是引用数据类型是,比较的是两个对象的地址是否相同。
equals方法是Object类中的一个方法 ,它只能比较引用数据类型。
equals方法默认比较的是两个对象的地址值是否相同,但是有些类比如String类,和Integer类就会重写该方法,使其实现不同的功能。
Q3——看程序写结果
String s1 = new String("hello");
String s2 = new String("hello");
System.out.println(s1 == s2);//false //两个都要new,在堆中的地址值不一样
System.out.println(s1.equals(s2));//true //String类的equals方法比较内容
String s3 = new String("hello");
String s4 = "hello";
System.out.println(s3 == s4);//false
System.out.println(s3.equals(s4));//true
String s5 = "hello";
String s6 = "hello";
System.out.println(s5 == s6);//true
System.out.println(s5.equals(s6));//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 StringDemo {
public static void main(String[] args) {
System.out.println("ABC".equals("abc"));
//false 该方法会区分大小写。
System.out.println("ABC".equalsIgnoreCase("abc"));
//true 该方法会忽略大小写
System.out.println("abcde".contains("cd"));
//true 判断字符串中是否包含传进来的字符串
System.out.println("abcde".startsWith("ab"));
//true 判断字符串是不是以传进来的字符串开头
System.out.println("abcde".endsWith("de"));
//true 判断字符串是不是以传进来的字符串结尾
System.out.println("abcde".isEmpty());
//false 判断字符串的内容是否为空
}
}
模拟用户登录
案例演示:
需求:模拟登录,给三次机会,并提示还有几次。
public class StringDemo2 {
public static void main(String[] args) {
String name = "Dave";
String password = "123456";
for (int i = 1; i < 4; i++) {
Scanner scanner = new Scanner(System.in);
System.out.println("please input your name:");
String userN = scanner.next();
//用next不用nextLine,名字中不允许有空格
/* nextLine() 方法会把回车换行空格都录入进去
* next() 碰到回车换行空格就停止录入了 */
Scanner scanner1 = new Scanner(System.in);
//上面是next,下面是nextLine,要重新创建Scanner对象,否则获取不到password
System.out.println("please input your password:");
String userP = scanner1.nextLine();
if (name.equals(userN) & password.equals(userP)) {
System.out.println("Login is successful…");
break;
} else {
if (i == 3) {
System.out.println("Sorry,you have run out of times.");
} else {
System.out.println("Your name and password are wrong,please try again…" + (3 - i) + " more times for you");
}
}
}
}
}
String类的获取功能
* public int length():
* 获取字符串的长度。
* public char charAt(int index):
* 获取指定索引位置的字符
* public int indexOf(int ch):
* 返回指定字符在此字符串中第一次出现处的索引。
* public int indexOf(String str):
* 返回指定字符串在此字符串中第一次出现处的索引。
* 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 StringDemo3 {
public static void main(String[] args) {
String s = "我真的是个好人wzdsghrwzdsghr";
//我们标一下索引,方便理解
//0我1真2的3是4个5好6人7w8z9d10s11g12h13r14w15z16d17s18g19h20r
System.out.println(s.length()); //21
//获取字符串的长度
System.out.println(s.charAt(3)); //是
//获取指定索引位置的字符
System.out.println(s.indexOf("w")); //7
//返回指定字符在此字符串中第一次出现处的索引。
//如果找不到就会返回 -1 ,有时我们会拿 -1 作为判断条件
System.out.println(s.indexOf("好人")); //5
//返回指定字符串在此字符串中第一次出现处的索引。
System.out.println(s.indexOf("w",8)); //14
//返回指定字符在此字符串中从指定位置后第一次出现处的索引。
System.out.println(s.lastIndexOf("h")); //19
//lastIndexOf 从后往前检索,该字符第一次出现的索引
System.out.println(s.substring(14)); //wzdsghr
//从指定位置开始截取字符串, 默认到末尾。
System.out.println(s.substring(7,14)); //wzdsghr
//从指定位置开始到指定位置结束截取字符串。 含头不含尾
}
}
字符串的遍历
- public char charAt(int index):
- 获取指定索引位置的字符
public class StringDemo4 {
public static void main(String[] args) {
String s = "几句是非也无法将我的热情冷却";
for (int i = 0; i < s.length(); i++) {
System.out.print(s.charAt(i));
}
System.out.println();
//从后往前遍历
for (int i = s.length()-1; i >= 0 ; i--) {
System.out.print(s.charAt(i));
}
}
}
//几句是非也无法将我的热情冷却
//却冷情热的我将法无也非是句几
统计不同类型字符个数
A:案例演示:
需求:统计一个字符串中大写字母字符,小写字母字符,数字字符出现的次数。(不考虑其他字符)
public class StringDemo5 {
public static void main(String[] args) {
String s = "AAABCkddfdQEWQE12128929eQQQaaa132121";
int capitalNum = 0;
int lowercaseNum = 0;
int numberNum = 0;
for (int i = 0; i < s.length(); i++) {
//截取每个字符
char c = s.charAt(i);
//我们可以通过比较ASCII码来判断
if (c >= 'A' && c <= 'Z') {
capitalNum++;
} else if (c >= 'a' && c <= 'z') {
lowercaseNum++;
} else if (c >= '0' && c <= '9') {
numberNum++;
}
}
System.out.println("大写字母有" + capitalNum + "个");
System.out.println("小写字母有" + lowercaseNum + "个");
System.out.println("数字有" + numberNum + "个");
}
}
//大写字母有13个
//小写字母有9个
//数字有14个
String类的转换功能
* public byte[] getBytes():
* 把字符串转换为字节数组。
* public char[] toCharArray():
* 把字符串转换为字符数组。
* public static String valueOf(char[] chs):
* 把字符数组转成字符串。
* public static String valueOf(int i):
* 把int类型的数据转成字符串。
* 注意:String类的valueOf方法可以把任意类型的数据转成字符串。
* public String toLowerCase():
* 把字符串转成小写。
* public String toUpperCase():
* 把字符串转成大写。
* public String concat(String str):
* 把字符串拼接。
public class StringDemo6 {
public static void main(String[] args) {
//1、把字符串转化为字节数组getBytes()
String s = "abcde";
byte[] bytes = s.getBytes();
for (int i = 0; i < bytes.length; i++) {
System.out.print(bytes[i] + " ");
}
//我们可以把字节数组再通过构造新String对象逆转换
String string = new String(bytes);
System.out.println(string);
/*97 98 99 100 101 abcde*/
System.out.println("------------------------");
//2、把字符串转换为字符数组toCharArray()
String s1 = "我爱中国";
char[] chars = s1.toCharArray();
for (int i = 0; i < chars.length; i++) {
System.out.print(chars[i] + " ");
}
//逆转换
String string1 = new String(chars);
System.out.println(string1);
/*我 爱 中 国 我爱中国*/
System.out.println("------------------------");
//3、public static String valueOf(char[] chs):
// * 把字符数组转成字符串。
// * public static String valueOf(int i):
// * 把int类型的数据转成字符串。
//注意:String类的valueOf方法可以把任意类型的数据转成字符串。
char[] chars2 = {'我', '爱', '我', '家'};
String string2 = String.valueOf(chars2);
System.out.println(string2);
/*我爱我家*/
int i = 100 + 23 + 454 + 2;
String s2 = i + "我是个好人";
String string3 = String.valueOf(i);
System.out.println(string3);
System.out.println(s2);
/*579
*579我是个好人*/
System.out.println("------------------------");
//4、* public String toLowerCase():
// * 把字符串转成小写。
// * public String toUpperCase():
// * 把字符串转成大写。
System.out.println("FUCKJAVA".toLowerCase());
System.out.println("shitjava".toUpperCase());
/*fuckjava
*SHITJAVA*/
// 5、* public String concat(String str):
// * 把字符串拼接。
String s3 = "abc" + "def" + "ghi";
System.out.println(s3);
String concat = "aaa".concat("bbb").concat("ccc");
System.out.println(concat);
/*abcdefghi
*aaabbbccc*/
}
}
案例演示:
需求:把一个字符串的首字母转成大写,其余为小写。(只考虑英文大小写字母字符)
public class StringDemo7 {
public static void main(String[] args) {
String s = "asfadsfasdfadsfAAAABBBBB";
//先把第一个字母截取出来substring();
String substring = s.substring(0, 1);
//转成大写
String s1 = substring.toUpperCase();
//再把其余字母截取出来并转成小写
String substring1 = s.substring(1);
String s2 = substring1.toLowerCase();
//重新拼接
String concat = s1.concat(s2);
System.out.println(concat);
//Asfadsfasdfadsfaaaabbbbb
}
}
String类的其他功能
/*A:String的替换功能及案例演示
* public String replace(char old,char new)
* 将指定字符进行互换
* public String replace(String old,String new)
* 将指定字符串进行互换*/
public class StringDemo8 {
public static void main(String[] args) {
String replace1 = "我真的喜欢打篮球".replace("我", "他");
String replace2 = "我真的喜欢打篮球".replace("篮球", "排球");
System.out.println(replace1);
System.out.println(replace2);
}
}
B:String的去除字符串两空格及案例演示
public String trim() 去除两端空格
public class StringDemo9 {
public static void main(String[] args){
String s = " sfasdgadsfsdgs ";
System.out.println(s.trim());
//sfasdgadsfsdgs
}
}
案例演示
去除字符串中间空格
public class StringDemo9_2{
public static void main(String[] args) {
//去掉字符串的中间空格
String str = "asfasdf as df ad sf asdfasfds asdfdsafdsa";
String s="";
for (int i = 0; i < str.length(); i++) {
char ch = str.charAt(i);
if(ch==' '){
continue;
}else{
s+=ch;
}
}
System.out.println(s);
}
}
* C:String的按字典顺序比较两个字符串及案例演示
* public int compareTo(String str)
* 会对照ASCII 码表 从第一个字母进行减法运算返回的就是这个减法的结果
* 如果前面几个字母一样会根据两个字符串的长度进行减法运算返回的就是这个减法的结果
* 如果两个字符串一摸一样 返回的就是0
* public int compareToIgnoreCase(String str)\
* 跟上面一样 只是忽略大小写的比较
public class StringDemo10 {
public static void main(String[] args) {
String s = "abc";
int compareTo = s.compareTo("Abc");
System.out.println(compareTo); //32
/*会对照ASCII 码表 从第一个字母进行减法运算返回的就是这个减法的结果,如果两个字符串一模一样,就返回0*/
System.out.println(s.compareTo("abc")); //0
//compareToIgnoreCase()可以忽略大小写进行比较
System.out.println(s.compareToIgnoreCase("Abc")); //0
}
}
把数组转成指定格式的字符串
A:案例演示
需求:把数组中的数据按照指定个格式拼接成一个字符串
举例:
int[] arr = {1,2,3};
拼接结果:
"[1, 2, 3]"
public class StringDemo12 {
public static void main(String[] args) {
int[] arr = {1, 2, 3};
String s="[";
for (int i = 0; i < arr.length; i++) {
if(i==arr.length-1){
s+=arr[i]+"]";
}else{
s+=arr[i]+",";
}
}
System.out.println(s);
}
}
字符串反转
案例演示
需求:把字符串反转
举例:键盘录入"abc"
反转结果:"cba"
public class StringDemo13{
public static void main(String[] args){
System.out.println("请输入字符串:");
Scanner scanner = new Scanner(System.in);
String s1 = scanner.nextLine();
String s2 = "";
for (int i = s1.length()-1; i >= 0; i--) {
char c = s1.charAt(i);
s2+=c;
}
System.out.println(s2);
}
}
在大串中查找小串出现的次数思路图解
需求:统计大串中小串出现的次数
举例:
"woaijavawozhenaijavawozhendeaijavawozhendehenaijavaxinbuxinwoaijavagun”
中java出现了5次
public class StringDemo14 {
public static void main(String[] args) {
String maxStr = "woaijavawozhenaijavawozhendeaijavawozhendehenaijavaxinbuxinwoaijavagun";
String minStr = "java";
int count = 0;
//先查小串第一次出现的索引
int index = maxStr.indexOf(minStr);
while (index != (-1)) {
count++;
//根据索引截取字符串,再赋值给大串
maxStr = maxStr.substring(index + 4);
//再继续查找索引
index = maxStr.indexOf(minStr);
}
System.out.println("java出现了" + count + "次");
//java出现了5次
}
}
public class StringDemo14_2 {
public static void main(String[] args) {
String maxStr = "woaijavawozhenaijavawozhendeaijavawozhendehenaijavaxinbuxinwoaijavagun";
String minStr = "java";
int count = 0;
int index;
while ((index = maxStr.indexOf(minStr)) != -1) {
count++;
// 找到"java" 截取
maxStr = maxStr.substring(index + minStr.length());
}
}
System.out.println("java出现了" + count + "次");
//java出现了5次
}
}