Java基础部分总结【常用类-1】
- Scanner类
- Random类
- String类
- StringBuilder类和StringBuffer类
- Arrays类
Scanner类
一个可以解析基本类型和字符串的简单文本扫描器。
构造方法
Scanner(InputStream source)
构造一个新的 Scanner,它生成的值是从指定的输入流扫描的。
成员方法代码演示
- 使用try/catch来判断输入数据格式的准确性
public class ScannerDemo {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);// System.in 系统输入指的是通过键盘录入数据
while (true) {
System.out.println("请输入一个整数:");
try {// 如果使用了try/catch则不需要使用hasNextInt()判断
int i = sc.nextInt(); // int nextInt(),将输入信息的下一个标记扫描为一个 int-->在这里完成的输入
System.out.println("i=" + i);
break;
}
catch (Exception e) {
System.out.println("输入错误,请重新输入");
sc.nextLine();// 如果输入错误则清空缓冲区中的数据,否则将会一直读取到错误的数据
}
}
}
}
- 使用sc.hasNextInt()判断输入格式的正确性
public class ScannerDemo {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);// System.in 系统输入指的是通过键盘录入数据
while (true) {
System.out.println("请输入一个整数:");
if (sc.hasNextInt()) {// 如果通过使用 nextInt() 方法,此扫描器输入信息中的下一个标记可以解释为默认基数中的一个 int 值,则返回 true。-->在这里完成的输入
int i = sc.nextInt(); // int nextInt(),将输入信息的下一个标记扫描为一个 int
System.out.println("i=" + i);
break;
}
else {
System.out.println("请输入整数!");
sc.nextLine();
}
}
}
}
注意:
当输入数据的格式错误的时候,需要清空缓冲区才能在下一次输入的时候获取到正确的数据,可以使用nextLine()方法来清空。
nextLine()和next()的区别:
-
next():
- 1、一定要读取到有效字符后才可以结束输入。
- 2、对输入有效字符之前遇到的空白,next() 方法会自动将其去掉。
- 3、只有输入有效字符后才将其后面输入的空白作为分隔符或者结束符。
- 4、next() 不能得到带有空格的字符串。
-
nextLine():【可用于清空缓冲区使用】
- 1、以Enter为结束符,也就是说 nextLine()方法返回的是输入回车之前的所有字符。
- 2、可以获得空白。
public class ScannerDemo {
public static void main(String[] args) {
System.out.println("请键盘输入:");
Scanner sc = new Scanner(System.in);// System.in 系统输入指的是通过键盘录入数据-->在这里完成的输入
//键盘输入"[三个空格]abcd[两个空格]abc[一个空格]a"-->注意空格
// 使用nextLine()
// 接收到回车前的所以字符,包括空格
if (sc.hasNextLine()) { // -->此处进行输入
String line = sc.nextLine();
// 回车作为结束符,空格不作为结束符,可以输出空格键
System.out.println("采用nextLine()输入的数据为:" + line); // out: 采用nextLine()输入的数据为: abcd abc a
}
//上面的输入被nextLine()读走了,缓冲区没有字符串,因此需要重新输入"[三个空格]abcd[两个空格]abc[一个空格]a"
System.out.println("请键盘输入:");
if (sc.hasNext()) { // -->此处进行输入
String next = sc.next();
// 对输入有效字符之前遇到的空白,next() 方法会自动将其去掉。
// 只有输入有效字符后才将其后面输入的空白作为分隔符或者结束符--->abcd后的第一个空格作为了结束符
System.out.println("采用next()输入的数据为:" + next); //out 采用next()输入的数据为:abcd
}
}
}
Random类
构造方法
-
public Random() //创建一个新的随机数生成器。
此构造方法将随机数生成器的种子设置为某个值,该值与此构造方法的所有其他调用所用的值完全不同。 -
public Random(long seed) //使用单个 long 种子创建一个新的随机数生成器
注意:
1、查看无参构造的源码,可以看到随机的种子是一个纳秒级别的时间,因此不可能得到重复的种子。
public Random() {
this(seedUniquifier() ^ System.nanoTime());
}
2、相同种子数的Random对象,相同次数生成的随机数字是完全相同的。也就是说,两个种子数相同的Random对象,第一次生成的随机数字完全相同,第二次生成的随机数字也完全相同。
3、种子数只是随机算法的起源数字,和生成的随机数字的区间无关。
成员方法
public int nextInt(int n) :返回一个伪随机数,范围在 0 (包括)和 指定值 n (不包括)之间的int值。
public class RandomDemo {
public static void main(String[] args) {
Random rand1 = new Random(); // 无参构造
// 设置相同的种子
Random rand2 = new Random(10); // 设置随机种子为10
Random rand3 = new Random(10); // 设置随机种子为10
//设置随机数产生的范围
int i = rand1.nextInt(20);
int j = rand2.nextInt(30);
int k = rand3.nextInt(30);
System.out.println("i=" + i); //out1:19 out2:4 out3:8
System.out.println("j=" + j); //out1:3 out2:3 out3:3
System.out.println("k=" + k); //out:3 out2:3 out3:3
}
}
Tips:
- 可以看出当设置了随机数种子seed后,不管运行几次,输出的结果都是一样的;
- 当设置的随机数种子和随机数的取值范围相同时,输出的随机数也相同;
- 当设置的随机数种子相同但随机数范围不同时,输出的结果不同,但多次输出的结果相同;
也就是说,设置了随机数种子,那么每次产生的随机数都是相同的,即只是产生了唯一的一个随机数;
随机数范围和nextInt(int n) 和n有关
一些应用
- 用于概率
for (int j = 0; j < 10; j++) {
int i = rand1.nextInt(100);
if (i > 90) { // 用于概率,90%的概率
System.out.println(i);
}
}
- 产生区间的随机数
// 产生[i,j]之间的随机数
// 产生[10,20]之间的随机数
int k = rand1.nextInt(10)+10;
System.out.println(k);
- 生成不重复的随机数【利用集合】
public static ArrayList getDiffNO(int n) {
// 生成 [0-n) 个不重复的随机数
// list 用来保存这些随机数
ArrayList list = new ArrayList();
Random rand = new Random();
boolean[] bool = new boolean[n];
int num = 0;
for (int i = 0; i < n; i++) {
do {
// 如果产生的数相同继续循环
num = rand.nextInt(n);
}
while (bool[num]);
bool[num] = true;
list.add(num);
}
return list;
}
String类
- java.lang.String 类代表字符串。Java程序中所有的字符串文字(例如 “abc” )都可以被看作是实现此类的实例。
- 类 String 中包括用于检查各个字符串的方法,比如用于比较字符串,搜索字符串,提取子字符串以及创建具有翻译为大写或小写的所有字符的字符串的副本。
构造函数
- 最简单的创建方式:位于字符串常量池
String s1=“abc”;
- 通过使用平台的默认字符集解码指定的 byte 数组,构造一个新的 String。
String(byte[] bytes)
字符串存储的区域: 【后文有详细描述】
String s1 = "abc"; // 常量池
String s2 = new String("abc"); // 堆内存中
常用方法
判断是否相等
-
public boolean equals (Object anObject) :将此字符串与指定对象进行比较。
-
public boolean equalsIgnoreCase (String anotherString) :将此字符串与指定对象进行比较,忽略大小写。
特别注意:
- 对于基本类型来说,==是比较数值的大小;
- 对于引用类型来说,==是比较地址值;
- String是一个引用类型,进行比较的是地址值,要想进行字符串的内容是否相同,使用equals方法;
- 当比较双方一个为常量一个为变量时,推荐把常量字符串放在前面。
String s1="abc";
String s2="abc";
char[] charArray=new char[]{'a','b','c'};
String s3=new String(charArray);
String s3="ABC";
System.out.println(s1==s2);//true 地址比较
System.out.println(s1==s3);//false
System.out.println(s1==s3);//false
System.out.println(s1.equals(s2));// true 地址所对应的值比较
System.out.println(s1.equals(s3));// true 地址所对应的值比较
System.out.println(s1==s4); // false
System.out.println(s1.equalsIgnoreCase(s4)); // true 排除大小写比较值
System.out.println("abc".equals(s1)); // 当比较双方其中一个为常量"abc"时,常量放在前面否则如果非常量为Null时,会报错 //ture
String s5 = null; //System.out.println(s5.equals("abc")); // 报错 NullPointerException 空指针异常
获取功能的方法
-
public int length () :返回此字符串的长度。
-
public String concat (String str) :将指定的字符串连接到该字符串的末尾。
-
public char charAt (int index) :返回指定索引处的 char值。
-
public int indexOf (String str) :返回指定子字符串第一次出现在该字符串内的索引。
-
public String substring (int beginIndex) :返回一个子字符串,从beginIndex开始截取字符串到字符串结尾。
-
public boolean endsWith(String suffix) : 测试此字符串是否以指定的后缀结束
-
public String substring (int beginIndex, int endIndex) :返回一个子字符串,从beginIndex到endIndex截取字符串。含beginIndex,不含endIndex。
注意和C#中的区别,C#中参数是(首索引,截取的长度)
public class stringTest {
public static void main(String[] args) {
//Test 03 获取方法
String str1 = "1123asnjajsdjaj";
System.out.println("字符串的长度:" + str1.length()); // length字符串的长度 字符串的长度:15
String str2 = "Hello";
String str3 = " World!";
String str4 = str2.concat(str3);//concat 字符串拼接
System.out.println(str4); // Hello World!
char ch = str1.charAt(5);//charAt()获取指定索引的字符
System.out.println(ch); // s
int ich= str1.indexOf(ch);//indexOf()获取指定字符的索引
System.out.println(ich); // 5
String str5=str1.substring(0,4);//[begin,end)
System.out.println(str5); // 1123
}
}
获取功能的方法
-
public char[] toCharArray () :将此字符串转换为新的字符数组。
-
public byte[] getBytes () :使用平台的默认字符集将该 String编码转换为新的字节数组。
-
public String replace (CharSequence target, CharSequence replacement) :将与target匹配的字符串使用replacement字符串替换。
-
public String trim(): 返回字符串的副本,忽略前导空白和尾部空白。
//Test 04 与转换相关
String str1 = "1123asnjajsdjaj";
//1、转换成字符数组
char[] chars = str1.toCharArray();
System.out.println(chars[4]);//a
//2、转换成字节数组
byte[] bytes = str1.getBytes();
for (byte aByte : bytes) {
System.out.println(aByte); // 49 49 50 51...
}
//3、 字符串替换
// -->去掉所有空格
String str2 = " 1111 111 11 ";
String strRpc = str2.replace(" ", "");
System.out.println(strRpc); // "111111111"
//去掉首、末空格
String strTrim = str2.trim();
System.out.println(strTrim); //"1111 111 11"
字符串常量池问题
-
当一个字符串是一个字面量时,它会被放到一个常量池中,等待复用。
// 当一个字符串是一个字面量时,它会被放到一个常量池中,等待复用。
String str1 = "abc"; // 在字符串常量池中创建
String str2 = "abc"; // 已经在常量池中存在,不需要重复创建
String str3 = "a" + "b" + "c"; // 已经在常量池中存在,不需要重复创建
String str4 = new String("abc"); // 在堆中创建
String str5 = "ab"; // 先在常量池中创建了"ab",地址指向str5,
String str6 = str5 + "c"; // 在创建StringBuilder对象,通过 append 连接得到abc ,再调用toString() 转换得到的地址指向str6
System.out.println(str1 == str2); // true
System.out.println(str1 == str3); // true
System.out.println(str1 == str4); // false
System.out.println(str1 == str6); // false
System.out.println(str4 == str6); // false
StringBuilder类和StringBuffer类
需求:
由于String类的对象内容不可改变,所以每当进行字符串拼接时,总是会在内存中创建一个新的对象。例如:
public class StringDemo {
public static void main(String[] args) {
String s = "Hello";
s += "World";
System.out.println(s);
}
}
在API中对String类有这样的描述:字符串是常量,它们的值在创建后不能被更改。
根据这句话分析我们的代码,其实总共产生了三个字符串,即 “Hello” 、 “World” 和 “HelloWorld” 。引用变量s首
先指向 Hello 对象,最终指向拼接出来的新字符串对象,即 HelloWord 。
由此可知,如果对字符串进行拼接操作,每次拼接,都会构建一个新的String对象,既耗时,又浪费空间。为了解决
这一问题,可以使用 java.lang.StringBuilder 类。
产生:
StringBuilder又称为可变字符序列,它是一个类似于String的字符串缓冲区,通过某些方法调用可以改变该序列的长度和内容。
- StringBuilder是个字符串的缓冲区,即它是一个容器,容器中可以装很多字符串。并且能够对其中的字符串进行各种操作。
- 它的内部拥有一个数组用来存放字符串内容,进行字符串拼接时,直接在数组中加入新内容。StringBuilder会自动维护数组的扩容。(默认16字符空间,超过自动扩充)。
StringBuilder类继承了AbstractStringBuilder抽象类,AbstractStringBuilder抽象类中有byte[] value的数组,和String类比较,其没有final修饰,因此可变。
当超过16个字符时自动扩充的原理:
当超过16个字符时,系统重新在堆中申请一块内存空间,将原来的数组中的数据拷贝过去,来替代原来的数组。因此,StringBuilder对象的地址并没有改变。【相当于二级指针】
- StringBuilder原理
- 自动扩充原理
构造方法
-
public StringBuilder() :构造一个空的StringBuilder容器。
-
public StringBuilder(String str) :构造一个StringBuilder容器,并将字符串添加进去
StringBuilder sb1 = new StringBuilder();
StringBuilder sb2 = new StringBuilder("1212121212");
常用方法
-
public StringBuilder append(…) :添加任意类型数据的字符串形式,并返回当前对象自身。
append方法具有多种重载形式,可以接收任意类型的参数。任何数据作为参数都会将对应的字符串内容添加到
StringBuilder中。
代码
StringBuilder builder = new StringBuilder();
StringBuilder builder1 = builder.append(100); // int
StringBuilder builder2 = builder.append("111"); // char
StringBuilder builder3 = builder.append(true); // bool
System.out.println(builder); // 100111true
// 可以看出添加后的地址没有改变
System.out.println(builder==builder1); // true
System.out.println(builder==builder2); // true
System.out.println(builder==builder3); // true
System.out.println(builder1==builder2); // true
备注:StringBuilder已经覆盖重写了Object当中的toString方法
-
public String toString() :将当前StringBuilder对象转换为String对象。
通过toString方法,StringBuilder对象将会转换为不可变的String对象。
public class Demo16StringBuilder {
public static void main(String[] args) {
// 链式创建
StringBuilder sb = new StringBuilder("Hello").append("World").append("Java");
// 调用方法
String str = sb.toString();
System.out.println(str); // HelloWorldJava
}
}
StringBuilder sb = new StringBuilder("Hello").append("World").append("Java");
因为append的返回值类型还是StringBuilder类型的,所有可以继续所有append方法,且返回的是其本身。
基本没什么用,优先考虑用StringBuilder。
Arrays类
java.util.Arrays 此类包含用来操作数组的各种方法,比如排序和搜索等。其所有方法均为静态方法,调用起来
非常简单。
方法
public static String toString(int[] a) :返回指定数组内容的字符串表示形式。
public static void sort(int[] a) :对指定的 int 型数组按数字升序进行排序。
public class ArraysDemo {
public static void main(String[] args) {
int[] arr = {2, 12, 3, 34, 15, 6};
System.out.println(arr);
String s = Arrays.toString(arr); // [I@1e643faf
System.out.println("排序前:" + s); // 排序前:[2, 12, 3, 34, 15, 6]
Arrays.sort(arr);
System.out.println("排序后:"+Arrays.toString(arr)); // 排序后:[2, 3, 6, 12, 15, 34]
System.out.println(Str.endsWith("adc")); // true
}
}