黑马程序员Java课程笔记008
查看上一章:黑马程序员Java课程笔记007API、Scanner、Random和ArrayList类
查看下一章:黑马程序员Java课程笔记009继承与抽象类
第一章 String类
1.1 字符串的概述和特点
java.lang.String
类代表字符串。
API当中说,Java程序的所有字符串字面值
都作为此类的实例实现。
其实就是说:程序当中所有的引号字符串
,都是string类的对象。(就算没有new,也照样是)
字符串的特点:
- 字符串的内容不可变,是
常量
。***【重点】- 正是因为字符串不可改变,所以字符串是可以
共享使用的
,可以达到节省内存
的目的。- 字符串效果上,相当于
char[]字符数组
,但是底层原理是byte[]字节数组
。
1.2 字符串的构造方法和直接创建
创建字符串常见3+1
种方式。
三种构造方法:
public String()
:创建一个空白字符串,不含有任何内容。
public String(cahr[] array)
:根据字符数组的内容,来创建对应的字符串。
public String(byte[] array)
:根据字节数组的内容,来创建对应的字符串。
一种直接创建
: String str = “Hello”; // 右边直接用双引号
【注意】:直接写上双引号,就是字符串对象
。
没有new,jvm帮你new。
按住ctrl点击String可以查看String源码
package cn.itcast.day08.demo01;
public class Demo01String {
public static void main(String[] args) {
// 使用空参构造
String str1 = new String(); // 小括号留空,说明字符串什么内容都没有。
System.out.println("第1个字符串:" + str1);
// 根据字符数组创建字符串
char[] charArray = {
'A', 'B', 'C'};
String str2 = new String(charArray);
System.out.println("第2个字符串:" + str2);
// 根据字节数组创建字符串
byte[] byteArray = {
97, 98, 99};
String str3 = new String(byteArray);
System.out.println("第3个字符串:" + str3);
// 直接创建
String str4 = "Hello";
System.out.println("第4个字符串:" + str4);
}
}
1.3 字符串的常量池
字符串常量池:程序当中直接写上的双引号字符串就在字符串常量池
中。
对于基本类型来说, == 是进行
数值的比较
。
对于引用类型来说, == 是进行【地址值】的比较
。【注意】:1. 对于引用类型来说,==进行的是地址值的比较。
2.双引号直接写
的字符串在常量池当中,new的不在常量池
当中。
package cn.itcast.day08.demo01;
public class Demo02StringPool {
public static void main(String[] args) {
String str1 = "abc";
String str2 = "abc";
char[] charArray = {
'a', 'b', 'c'};
String str3 = new String(charArray);
System.out.println(str1 == str2); // true
System.out.println(str1 == str3); // false
System.out.println(str2 == str3); // false
}
}
1.4 字符串的比较相关方法
==
是进行对象的地址值比较,如果确实需要字符串的内容比较,可以使用两个方法。
public boolean equals(Object obj)
,参数可以是任何对象,只有参数是一个字符串并且内容相同才会给true,否则返回false。
- 任何对象都能用
Object
进行接收。equals方法具有对称性
,也就是a.equals(b)和b.equals(a)效果一样。- 如果比较双方一个常量一个变量,推荐把常量字符串写在前面。
推荐:"abc".equals(str);
不推荐:str.equals("abc");
public boolean equalsIgnoreCase(String str):
忽略大小写,进行内容比较
package cn.itcast.day08.demo02;
public class Demo01StringEquals {
public static void main(String[] args) {
String str1 = "Hello";
String str2 = "Hello";
char[] charArray = {
'H', 'e', 'l', 'l', 'o'};
String str3 = new String(charArray);
System.out.println(str1.equals(str2)); // true
System.out.println(str2.equals(str3)); // true
System.out.println(str3.equals("Hello")); // true
System.out.println("Hello".equals(str1)); // true
String str4 = "hello";
System.out.println(str1.equals(str4)); // false
String str5 = null;
System.out.println("abc".equals(str5)); // 推荐,false
// System.out.println(str5.equals("abc")); // 不推荐, 如果.之前是null,就会报错,空指针异常NullPointException
String strA = "java";
String strB = "JAVA";
System.out.println(strA.equals(strB)); // false,严格区分大小写
System.out.println(strA.equalsIgnoreCase(strB)); // true,忽略大小写
// 只有英文字母区分大小写,其他不区分大小写
System.out.println("一".equalsIgnoreCase("壹")); // false
}
}
1.5 字符串的获取相关方法
String当中与获取相关的方法有:
public int length()
:获取字符串当中含有的字符个数,拿到字符串长度
;
public String concat(String str)
:将当前字符串
和参数字符串
拼接成返回值新的字符串。
public char cahrAt(int index)
:获取指定索引位置的单个字符
。(索引从0
开始)
public int indexOf(String str)
:查找参数字符串在本字符串当中首次出现的索引位置
,如果没有返回值-1。
package cn.itcast.day08.demo02;
public class Demo02StringGet {
public static void main(String[] args) {
// 获取字符串的长度
int length = "adaadsadsad".length();
System.out.println("字符串的长度是:" + length);
// 拼接字符串
String str1 = "Hello";
String str2 = "World";
String str3 = str1.concat(str2);
System.out.println(str1); // Hello,原封不动
System.out.println(str2); // World,原封不动
System.out.println(str3); // HelloWorld,新的字符串
// 获取指定索引位置的单个字符
char c = "Hello".charAt(1);
System.out.println("在一号索引位置的字符是:" + c);
System.out.println("=============");
// 查找参数字符串在本来字符串你当中出现的第一次索引位置
// 如果根本没有,返回-1
String original = "HelloWorld";
int index = original.indexOf("llo");
System.out.println("第一次索引值是:" + index); // 2
}
}
1.6 字符串的截取方法
字符串的截取方法:
public String subString(int index)
:截取从参数位置一直到字符串末尾
,返回新字符串。
public String subString(int begin, int end)
:截取从begin开始,一直到end结束
,中间的字符串。
备注:[bergin, end)
,包含左边,不包含右边。
package cn.itcast.day08.demo02;
public class Demo03SubString {
public static void main(String[] args) {
String str1 = "HelloWorld";
String str2 = str1.substring(5);
System.out.println(str1); // HelloWorld,原封不动
System.out.println(str2); // World,新字符串
System.out.println("=============");
String str3 = str1.substring(4,7);
System.out.println(str3); // oWo
System.out.println("=============");
// 下面这种写法,字符串的内容仍然是没有改变的
// 下面有两个字符串:"Hello","Java"
// strA当中保存的是地址值
// 本来地址值是Hello的0x666
// 后来地址值变成了Java的0x999
// 字符串的内容仍然不可以改变
String strA = "Hello";
System.out.println(strA); // Hello
strA = "Java";
System.out.println(strA); // Java
}
}
1.7 字符串的转换相关方法
String当中与转换相关的常用方法有:
public char[] toCharArray()
:将当前字符串拆分成字符数组作为返回值。
public byte[] getBytes()
:获得当前字符串底层的字节数据。
public String[] replace(CharSequence oldString, CharSequence new String)
: 将所有出现的老字符串替换成新的字符串,返回替换之后的结果字符串。
备注:charSequence
意思就是说可以接收字符串类型
package cn.itcast.day08.demo02;
public class Demo04StringConvert {
public static void main(String[] args) {
// 转换成字符数组
char[] chars = "Hello".toCharArray();
System.out.println(chars[0]);
System.out.println(chars.length);
System.out.println("=========");
// 转换成字节数组
byte[] bytes = "abc".getBytes();
for (int i = 0; i < bytes.length; i++) {
System.out.println(bytes[i]);
}
System.out.println("============");
String str1 = "How do you do?";
String str2 = str1.replace("o","*");
System.out.println(str1); // How do you do?
System.out.println(str2); // H*w d* y*u d*?
System.out.println("=============");
String lang1 = "会不会玩呀!你大爷的!你大爷的!你大爷的!你大爷的!!!";
String lang2 = lang1.replace("你大爷的", "****");
System.out.println(lang2); // 会不会玩呀!****!****!****!****!!!
}
}
1.8 字符串的分割方法
分割字符串的方法:
public String[] split(String regex)
:按照参数的规则
,将字符串切分成为若干部分。
注意事项:
split
方法的参数其实是一个正则表达式
,今后学习。
今天要注意:如果按照英文句点"."
进行切分,必须写"\\."
(两个反斜杠)"."单独出现时,在正则表达式中由于特殊含义,不能正常使用。
package cn.itcast.day08.demo02;
public class Demo05StringSplit {
public static void main(String[] args) {
String str1 = "aaa,bbb,ccc";
String[] array1 = str1.split(",");
for (int i = 0; i < array1.length; i++) {
System.out.println(array1[i]);
}
System.out.println("============");
String str2 = "aaa bbb ccc";
String[] array2 = str2.split(" ");
for (int i = 0; i < array2.length; i++) {
System.out.println(array2[i]);
}
System.out.println("=============");
String str3 = "xxx.uuu.zzz";
String[] array3 = str3.split("\\.");
System.out.println(array3.length);
for (int i = 0; i < array3.length; i++) {
System.out.println(array3[i]);
}
}
}
1.9 练习题
1.9.1 练习一_按指定格式拼接字符串
题目:
定义一个方法,把数组{1,2,3}按照指定格式拼接成一个字符串。参照格式如下:[word1#word2#word3]。
分析:
- 首先准备一个数组,内容是1,2,3
- 定义一个方法,用来将数组编程字符串 三要素: 返回值类型:String 方法列表:fromArrayToString 参数列表:int[]
- 格式:[word1#word2#word3] 用到:for循环、字符串拼接、每个数组元素之前都有一个word字样、分割使用的是#、区分一下是不是最后一个
- 调用方法,得到返回值,并打印结果字符串
package cn.itcast.day08.demo02;
/*
题目:定义一个方法,把数组{1,2,3}按照指定格式拼接成一个字符串。参照格式如下:[word1#word2#word3]。
分析:
1. 首先准备一个数组,内容是1,2,3
2. 定义一个方法,用来将数组编程字符串
三要素:
返回值类型:String
方法列表:fromArrayToString
参数列表:int[]
3. 格式:[word1#word2#word3]
用到:for循环、字符串拼接、每个数组元素之前都有一个word字样、分割使用的是#、区分一下是不是最后一个
4. 调用方法,得到返回值,并打印结果字符串
*/
public class Demo06StringPractise {
public static void main(String[] args) {
int array[] = {
1, 2, 3};
String result = fromArrayToString(array);
System.out.println(result);
}
public static String fromArrayToString(int[] array){
String str = "[";
for (int i = 0; i < array.length; i++) {
if (i == array.length - 1){
str += "word" + array[i] + "]";
break;
}
str += "word"+array[i] + "#";
}
return str;
}
}
1.9.2 练习二_统计输入的字符串中字符的个数
题目:
键盘输入一个字符串,并且统计其中各种字符串出现的次数。
种类有:大写字母、小写字母、数字、其他
思路:
- 既然用到键盘输入,肯定是
Scanner
- 键盘输入的是字符串,那么:
String str = sc.next();
- 定义四个变量,分别代表四种字符各自的出现次数。
- 需要对字符串一个字,一个字检查,String–> cahr[],方法就是
toCharArray
- 遍历char[]字符数组,对当前字符的种类进行判断,并且用四个变量进行++动作
- 打印输出四个变量,分别代表四种字符的出现次数。
package cn.itcast.day08.demo02;
import java.util.Scanner;
/*
题目:
键盘输入一个字符串,并且统计其中各种字符串出现的次数。
种类有:大写字母、小写字母、数字、其他
思路:
1. 既然用到键盘输入,肯定是Scanner
2. 键盘输入的是字符串,那么:String str = sc.next();
3. 定义四个变量,分别代表四种字符各自的出现次数。
4. 需要对字符串一个字,一个字检查,String--> cahr[],方法就是toCharArray
5. 遍历char[]字符数组,对当前字符的种类进行判断,并且用四个变量进行++动作
6. 打印输出四个变量,分别代表四种字符的出现次数。
*/
public class Demo07StringCount {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个字符串");
String input = sc.next(); // 获取键盘输入的一个字符串
int countUpper = 0; // 大写字母
int countLower = 0; // 小写字母
int countNumber = 0; // 数字
int countOther = 0; // 其他字符
char[] chars = input.toCharArray();
for (int i = 0; i < chars.length; i++) {
char ch = chars[i]; // 当前单个字符
if('A' <= ch && ch <= 'Z'){
countUpper++;
}
else if('a' <= ch && ch <= 'z'){
countLower++;
}
else if ('0' <= ch && ch <= '9'){
countNumber++;
}
else {
countOther++;
}
}
System.out.println("大写字母有:" + countUpper);
System.out.println("小写字母有:" + countLower);
System.out.println("数字有:" + countNumber);
System.out.println("其他有:" + countOther);
}
}
第二章 static静态
2.1 静态static关键字概述
一旦用了
static关键字
,那么这样的内容不再属于对象自己,而是属于类
的,所以凡是本类的对象
,都共享同一份。即多个类共享同一份数据。
2.2 静态static关键字修饰成员变量
package cn.itcast.day08.demo03;
public class Student {
private int id; // 学号
private String name; // 姓名
private int age; // 年龄
static String room; // 所在教室
private static int idCounter = 0; // 学号计数器,每当new了一个新对象的时候,计数器++
public Student(){
}
public Student(String name, int age) {
this.name = name;
this.age = age;
this.id = ++idCounter;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
如果一个成员变量使用了static关键字
,那么这个对象不再属于自己
,而是属于所在的类
,多个对象共享同一份数据。
package cn.itcast.day08.demo03;
/*
如果一个成员变量使用了static关键字,那么这个对象不再属于自己,而是属于所在的类,多个对象共享同一份数据。
*/
public class Demo01StaticField {
public static void main(String[] args) {
Student one = new Student("郭靖",19);
one.room = "101教室";
System.out.println("姓名:" + one.getName() + ",年龄:"
+ one.getAge() +",学号:"+one.getId() + ",教室:" + one.room);
Student two = new Student("黄蓉",16);
System.out.println("姓名:" + two.getName() + ",年龄:" + two.getAge()
+ ",学号:" + two.getId() + ",教室:" + two.room);
}
}
2.3 静态static关键字修饰成员方法
MyClass类
package cn.itcast.day08.demo03;
public class MyClass {
int num; // 成员变量
static int numStatic; // 静态变量
// 成员方法
public void method(){
System.out.println("这是一个普通的成员方法。");
// 成员方法可以访问成员变量
System.out.println(num);
// 成员方法可以访问静态变量
System.out.println(numStatic);
}
// 静态方法
public static void methodStatic(){
System.out.println("这是一个静态方法。");
// 静态方法可以访问静态变量
System.out.println(numStatic);
// 静态不能直接访问非静态【重点】
// System.out.println(num); // 错误写法!
// 静态方法中不能使用this关键字。静态方法调用在javac翻译后,直接通过类名调用,不使用对象。
// System.out.println(this); // 错误写法!
}
}
一旦使用static修饰成员方法,那么这就成为了
静态方法
。静态方法不属于对象,而是属于类
的。如果没有static关键字,那么必须首先
创建对象
,然后通过对象才能使用
它。
如果有了static关键字,那么不需要创建对象
,直接
就能通过类名称
来使用
它。
无论是成员变量还是成员方法。如果有了static,都推荐使用类名称进行调用。
静态变量:
类名称.静态变量
静态方法:类名称.静态方法()
注意事项:
- 静态不能直接访问
非静态
。
原因:因为在内存中【先】
有的静态内容,【后】
有的非静态内容。“先人不知道后人。但是后人知道先人”- 静态方法当中不能使用this 原因:
this
代表当前对象,通过谁调用的方法,谁就是当前对象。
package cn.itcast.day08.demo03;
import cn.itcast.day08.demo02.Demo05StringSplit;
/*
一旦使用static修饰成员方法,那么这就成为了静态方法。静态方法不属于对象,而是属于类的。
如果没有static关键字,那么必须首先创建对象,然后通过对象才能使用它。
如果有了static关键字,那么不需要创建对象,直接就能通过类名称来使用它。
无论是成员变量还是成员方法。如果有了static,都推荐使用类名称进行调用。
静态变量:类名称.静态变量
静态方法:类名称.静态方法()
注意事项:
1. 静态不能直接访问非静态。
原因:因为在内存中【先】有的静态内容,【后】有的非静态内容。“先人不知道后人。但是后人知道先人”
2. 静态方法当中不能使用this
原因:this代表当前对象,通过谁调用的方法,谁就是当前对象。
*/
public class Demo02StaticMethod {
public static void main(String[] args) {
MyClass obj = new MyClass(); // 首先创建对象
obj.method(); // 然后才能使用没有static关键字的内容
// 对于静态方法来说,可以通过对象名进行调用,也可以直接通过类名称进行调用
obj.methodStatic(); // 正确,不推荐,容易误以为是普通的成员方法,这种写法在编译之后也会被javac翻译成“类名.静态方法名”
MyClass.methodStatic(); // 正确,推荐,静态方法强烈推荐用类名称来编写
// 对于本类中的静态方法,可以省略类名称
myMethod();
Demo02StaticMethod.myMethod(); // 完全等效
}
public static void myMethod(){
System.out.println("自己的方法!");
}
}
2.4 静态static的内存图
static变量在方法区的静态区中保存。
注意:根据类名称访问静态成员变量的时候,全程和对象没关系,只和类有关系。
package cn.itcast.day08.demo03;
// static变量在方法区的静态区中保存。
// 注意:根据类名称访问静态成员变量的时候,全程和对象没关系,只和类有关系。
public class Demo03StaticStudent {
public static void main(String[] args) {
Student.room = "101教室";
Student one = new Student("郭靖" , 20);
System.out.println("one的姓名:" + one.getName());
System.out.println("one的年龄:" + one.getAge());
System.out.println("one的教室:" + one.room);
System.out.println("one的教室:" + Student.room);
Student two = new Student("黄蓉", 18);
System.out.println("two的姓名:" + two.getName());
System.out.println("two的年龄:" + two.getAge());
System.out.println("two的教室:" + two.room);
System.out.println("two的教室:" + Student.room);
}
}
静态代码块的格式:
public class 类名称 {
static {
// 静态代码块的内容
}}
特点:当第一次用到本类时,静态代码块执行唯一的一次
。
静态内容总是优先于非静态,所以静态代码块比构造方法先执行
。
静态代码块的典型用法:
用来一次性地
对静态成员变量进行赋值。
2.5 静态代码块
package cn.itcast.day08.demo03;
public class Demo04Static {
public static void main(String[] args) {
Person one = new Person();
// 静态代码块执行!
// 构造方法执行!
Person two = new Person();
// 构造方法执行!
}
}
Person类
package cn.itcast.day08.demo03;
public class Person {
static {
System.out.println("静态代码块执行!");
}
public Person(){
System.out.println("构造方法执行!");
}
}
第三章 Arrays工具类
3.1 数组工具类Arrays
java.util.Arrays
是一个与数组相关的工具类,里面提供了大量的静态方法,用来实现数组常见的操作。
public static String toString(数组)
:将参数数组变成字符串(默认格式:[元素1,元素2,元素3,…])
public static void sort(数组)
:按照默认升序(从小到大)对数组的元素进行排序。
备注:
- 如果是
数值
,那么sort默认按照升序从小到大- 如果是
字符串
,sort默认按照字母升序- 如果是
自定义的类型
,那么这个自定义的类需要有Comparable或者Comparator接口的支持。(今后学习)
package cn.itcast.day08.demo04;
import java.util.Arrays;
public class Demo01Arrays {
public static void main(String[] args) {
int[] intArray = {
10, 20, 30};
// 将int数组按照格式变成字符串
String intStr = Arrays.toString(intArray);
System.out.println(intStr);
int[] array1 = {
2, 1, 3, 10, 6};
Arrays.sort(array1);
System.out.println(Arrays.toString(array1));
String[] array2 = {
"bbb","ccc" ,"aaa"};
Arrays.sort(array2);
System.out.println(Arrays.toString(array2));
}
}
3.2 Arrays练习:字符串倒序排列
题目:
请使用Arrays相关的API,将一个随机字符串中的所有字符升序排列,并倒序打印。
package cn.itcast.day08.demo04;
import java.util.Arrays;
/*
题目:
请使用Arrays相关的API,将一个随机字符串中的所有字符升序排列,并倒序打印。
*/
public class Demo02ArraysPractise {
public static void main(String[] args) {
String str = "sdjasdjshfjdgahfdusaifo;doopwieop[qw";
// 如何进行升序排列:sort
// 必须是一个数组,才能用Arrays.sort方法
// String --> 数组,用toCharArray
char[] chars = str.toCharArray();
Arrays.sort(chars); // 对字符数组进行升序排列
// 需要倒序遍历
for (int i = chars.length - 1; i >= 0; i--) {
System.out.println(chars[i]);
}
}
}
第四章 Math类
4.1 数学工具Math类
java.util.Math
类是数学相关的工具类,里面提供了大量的静态方法
,完成与数学运算相关的操作
。
public static double abs(double num)
: 获取绝对值。有多种重载
public static double ceil(double num)
:向上取整。
public static double floor(double num)
:向下取整。
public static long round(double num)
:四舍五入。
Math.PI代表近似的圆周率常量(double)
.
package cn.itcast.day08.demo04;
/*
java.util.Math类是数学相关的工具类,里面提供了大量的静态方法,完成与数学运算相关的操作。
public static double abs(double num): 获取绝对值。有多种重载
public static double ceil(double num):向上取整。
public static double floor(double num):向下取整。
public static long round(double num):四舍五入。
Math.PI代表近似的圆周率常量(double).
*/
public class Demo03Math {
public static void main(String[] args) {
// 获取绝对值
System.out.println(Math.abs(3.14)); // 3.14
System.out.println(Math.abs(0)); // 0
System.out.println(Math.abs(-2.5)); // 2.5
System.out.println("===============");
// 向上取整
System.out.println(Math.ceil(3.9)); // 4.0
System.out.println(Math.ceil(3.1)); // 4.0
System.out.println("===============");
// 向下取整
System.out.println(Math.floor(3.2)); // 4.0
System.out.println(Math.floor(30.9)); // 30.0
System.out.println(Math.floor(31.0)); // 31.0
System.out.println("===============");
// 四舍五入
System.out.println(Math.round(20.5)); // 21
System.out.println(Math.round(20.1)); // 20
System.out.println(Math.PI);
}
}
小学数学真题
题目:
计算在 -10.8 到 5.9 之间,绝对值大于6或者小于2.1的整数有多少个?
分析:
- 既然已经确定了
范围
,for循环- 起点位置-10.8应该可以转换成-10,两种办法;
2.1 可以使用Math.ceil方法
,向上(向正方向)取整
2.2 强转成int
,自动舍弃所有小数位- 每一个数字都是
整数
,所以步进表达式应该是num++,这样每次都是+1的- 如何拿到
绝对值
。Math.abs
方法- 一旦发现了一个数字,需要让
计数器++
进行统计。
备注:
如果使用
Math.ceil
方法,-10.8可以变成 - 10.0。注意double也是可以++的。
package cn.itcast.day08.demo04;
/*
题目:
计算在 -10.8 到 5.9 之间,绝对值大于6或者小于2.1的整数有多少个?
分析:
1. 既然已经确定了范围,for循环
2. 起点位置-10.8应该可以转换成-10,两种办法;
2.1 可以使用Math.ceil方法,向上(向正方向)取整
2.2 强转成int,自动舍弃所有小数位
3. 每一个数字都是整数,所以步进表达式应该是num++,这样每次都是+1的
4. 如何拿到绝对值。Math.abs方法
5. 一旦发现了一个数字,需要让计数器++进行统计。
备注:如果使用Math.ceil方法,-10.8可以变成 - 10.0。注意double也是可以++的。
*/
public class Demo04MathPractise {
public static void main(String[] args) {
int count = 0;
int low = (int)Math.ceil(-10.8);
int up = (int)Math.floor(5.9);
// 这样处理,i就是区间内所有的正式
for(int i = low; i <= up; i++){
int abs = Math.abs(i);
if(abs > 6 || abs < 2.1){
System.out.println(i);
count++;
}
}
System.out.println("总共有"+count + "个数字是满足要求的。");
}
}
查看上一章:黑马程序员Java课程笔记007API、Scanner、Random和ArrayList类
查看下一章:黑马程序员Java课程笔记009继承与抽象类