Professional Documents
Culture Documents
Java笔记
Java笔记
Eg: [10,99]
Math.random()的范围为[0,1)
0*(99 - 10 + 1) + 10=10
1*(99 - 10 + 1) + 10=100
[10,100)就是[10,99]
注意括号的位置!
公式:int num = (int)(Math.random() * (99 - 10 + 1) + 10);
Calendar
Scan
如何从键盘获取不同类型的变量:需要使用 Scanner 类
具体实现步骤:
1.导包:import java.util.Scanner;
2.Scanner 的实例化:Scanner scan = new Scanner(System.in);
3.调用 Scanner 类的相关方法(next() / nextXxx()),来获取指定类型的
变量
注意:
需要根据相应的方法,来输入指定类型的值。如果输入的数据类型与要求的类型
不匹配时,会报异常:InputMisMatchException
导致程序终止。
示例代码:
String name = scan.next();
int age = scan.nextInt();
double weight = scan.nextDouble();
boolean isLove = scan.nextBoolean();
//对于 char 型的获取,Scanner 没有提供相关的方法。只能获取一个字符串
System.out.println("请输入你的性别:(男/女)");
String gender = scan.next();//"男"
char genderChar = gender.charAt(0);//获取索引为 0 位置上的
字符
System.out.println(genderChar);
Array
一、一维数组的使用
(一)一维数组的使用:声明
1. 动态初始化:数组声明且为数组元素分配空间与赋值的操作分开
进行
2.静态初始化:在定义数组的同时就为数组元素分配空间并赋值
//错误的写法:
// int[] arr1 = new int[];
// int[5] arr2 = new int[5];
// int[] arr3 = new int[3]{1,2,3};
(三)如何获取数组的长度。属性:length
System.out.println(names.length);//5
(四)数组元素的默认初始化值
* > 数组元素是整型:0
* > 数组元素是浮点型:0.0
* > 数组元素是 char 型:0 或'\u0000'(就是空字符),而非'0'(不
是数字 0)
* > 数组元素是 boolean 型:false
*
* > 数组元素是引用数据类型:null 不是"null"(不是文字 null),
区别:· null 是一个关键字,表示空引用,而 "null" 是一个字符串字面值,表示包含
字符序列 "null" 的字符串。
· null 通常用于初始化引用变量,或者表示引用变量当前不指向任何对象;而 "null"
只是一个普通的字符串,可以用于表示字符串内容为 "null" 的情况
二、二维数组的使用
(一)二维数组的声明和初始化
1.初始化
(1)静态初始化
int[][] arr1 = new int[][]{{1,2,3},{4,5},{6,7,8}};
(2)动态初始化
//动态初始化 1
String[][] arr2 = new String[3][2];
//动态初始化 2
String[][] arr3 = new String[3][];//此时如果继续直接
System.out.println(arr3[1][0]);会报错因为此时还没有指定第二维有几
个元素
(3)错误的情况
// String[][] arr4 = new String[][4];没有指定 1 维就指定二维
// String[4][3] arr5 = new String[][];不能写在前面
// int[][] arr6 = new int[4][3]{{1,2,3},{4,5},{6,7,8}};一维
4 个元素,二维 3 个元素和后面一维 3 个元素,二维不固定不 match
//也是正确的写法:
int[] arr4[] = new int[][]{{1,2,3},{4,5,9,10},{6,7,8}};
int[] arr5[] = {{1,2,3},{4,5},{6,7,8}};
2.如何调用数组的指定位置的元素
System.out.println(arr1[0][1]);//2
4.如何遍历二维数组
5.二维数组的使用:
* 规定:二维数组分为外层数组的元素,内层数组的元素
* int[][] arr = new int[4][3];
* 外层元素:arr[0],arr[1]等
* 内层元素:arr[0][0],arr[1][2]等
*
* ⑤ 数组元素的默认初始化值
* 针对于初始化方式一:比如:int[][] arr = new int[4][3];
* 外层元素的初始化值为:地址值
* 内层元素的初始化值为:与一维数组初始化情况相同
*
* 针对于初始化方式二:比如:int[][] arr = new int[4][];
* 外层元素的初始化值为:null
* 内层元素的初始化值为:不能调用,否则报错。
String[][] arr2 = new String[4][2];
System.out.println(arr2[1]);//地址值
System.out.println(arr2[1][1]);//null
对比:
double[][] arr3 = new double[4][];
System.out.println(arr3[1]);//null,因为还没有指定第二维的
数组,所以暂时就看成是一维数组;为什么是 null 不是 double 型的默认值
0.0,因为是二维数组,第一维是引用类型,是 null,和下面 float 的代码差
别对比一下
// System.out.println(arr3[1][0]);//报错
float[][] arr1 = new float[4][3];
System.out.println(arr1[0]);//地址值
System.out.println(arr1[0][0]);//0.0
java.util.Arrays
1.比较 2 个数组是否相等
boolean isEquals = Arrays.equals(arr1, arr2);
2. 输出数组信息,不是地址值
int[] arr1 = new int[]{1,2,3,4};
System.out.println(Arrays.toString(arr1));//“[1, 2, 3, 4]”
3. 将指定值填充到数组之中
Arrays.fill(arr1,10);//[10, 10, 10, 10]全变成 10 了
4. 对数组进行排序
Arrays.sort(arr2);//从小到大
5. 对数组进行查找
int[] arr3 = new int[]{-98,-34,2,34,54,66,79,105,210,333};
int index = Arrays.binarySearch(arr3, 210);
if(index >= 0){
System.out.println(index);//8
}else{
System.out.println("未找到");
}
6.冒泡排序注意点,容易错
// 数组排序
public void sort(int[] arr) {
// 冒泡排序
for (int i = 0; i < arr.length - 1; i++) {
}
}
//错误的:交换数组中指定两个位置元素的值
// public void swap(int i,int j){
// int temp = i;
// i = j;
// j = temp;
// }
//正确的:交换数组中指定两个位置元素的值
public void swap(int[] arr,int i,int j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
算法的考查:数组的复制、反转、查找(线性
查找、二分法查找)
2. 数组的反转
//方法一:
// for(int i = 0;i < arr.length / 2;i++){
// String temp = arr[i];
// arr[i] = arr[arr.length - i -1];
// arr[arr.length - i -1] = temp;
// }
//方法二:
// for(int i = 0,j = arr.length - 1;i < j;i++,j--){
// String temp = arr[i];
// arr[i] = arr[j];
// arr[j] = temp;
// }
3.遍历
System.out.println();
4.查找(或搜索)
(1)线性查找:
if(dest.equals(arr[i])){//string 用 equals,数字用==
System.out.println("找到了指定的元素,位置为:" +
i);
isFlag = false;
break;
}
}
if(isFlag){
System.out.println("很遗憾,没有找到的啦!");
(2)二分法查找:(熟悉)一半一半来
//前提:所要查找的数组必须有序。
int[] arr2 = new int[]{-98,-
34,2,34,54,66,79,105,210,333};
if(isFlag1){
System.out.println("很遗憾,没有找到的啦!");
}
if (arr4[middle1] == value1) {
System.out.println("已找到");
isFlag = false;
break;
} else if (arr4[middle1] > value1) {
end1 = middle1;
} else {
// 此处将 head 更新为 middle,可能导致死循环
head1 = middle1;
}
}
if (isFlag) {
System.out.println("找不到");
}
*/
/*如果不加减 1
* 第一轮:head=0 end=5 middle=2
* 第二轮:head=2 end=5 middle=3
* 第三轮:head=3 end=5 middle=4
* 第四轮:head=4 end=5 middle=4
* 以下就会陷入 while 循环,因为 head 永远都不等于或大于 end
* 通过将 head 更新为 middle + 1,可以确保每次迭代都将范围缩
小,
* 直到 head 和 end 相等或 head 大于 end,从而正确结束查找。
* */
}
}
5.数组的冒泡排序的实现
228 总结属性赋值的过程
总结:属性赋值的先后顺序
① 默认初始化:String name;
② 显式初始化: int age = 1;
③ 构造器中初始化:
public User(int a){
age = a;
}
* ④ 通过"对象.方法" 或 "对象.属性"的方式,赋值
public void setAge(int a){
age = a;
}
* 以上操作的先后顺序:① - ② - ③ - ④
//242.Eclipse 快捷键
package com.atguigu.java;
import java.sql.Date;
import java.util.ArrayList;
import java.util.HashMap;
/*
Eclipse 中的快捷键:
* 1.补全代码的声明:alt + /
* 2.快速修复: ctrl + 1
* 3.批量导包:ctrl + shift + o
* 4.使用单行注释:ctrl + /
* 5.使用多行注释: ctrl + shift + /
* 6.取消多行注释:ctrl + shift + \
* 7.复制指定行的代码:ctrl + alt + down 或 ctrl + alt + up
* 8.删除指定行的代码:ctrl + d
* 9.上下移动代码:alt + up 或 alt + down
* 10.切换到下一行代码空位:shift + enter
* 11.切换到上一行代码空位:ctrl + shift + enter
* 12.如何查看源码:ctrl + 选中指定的结构 或 ctrl + shift + t
* 13.退回到前一个编辑的页面:alt + left
* 14.进入到下一个编辑的页面(针对于上面那条来说的):alt + right
* 15.光标选中指定的类,查看继承树结构:ctrl + t
* 16.复制代码: ctrl + c
* 17.撤销: ctrl + z
* 18.反撤销: ctrl + y
* 19.剪切:ctrl + x
* 20.粘贴:ctrl + v
* 21.保存: ctrl + s
* 22.全选:ctrl + a
* 23.格式化代码: ctrl + shift + f
* 24.选中数行,整体往后移动:tab
* 25.选中数行,整体往前移动:shift + tab
* 26.在当前类中,显示类结构,并支持搜索指定的方法、属性等:ctrl + o
* 27.批量修改指定的变量名、方法名、类名等:alt + shift + r
* 28.选中的结构的大小写的切换:变成大写: ctrl + shift + x
* 29.选中的结构的大小写的切换:变成小写:ctrl + shift + y
* 30.调出生成 getter/setter/构造器等结构: alt + shift + s
* 31.显示当前选择资源(工程 or 文件)的属性:alt + enter
* 32.快速查找:参照选中的 Word 快速定位到下一个 :ctrl + k
*
* 33.关闭当前窗口:ctrl + w
* 34.关闭所有的窗口:ctrl + shift + w
* 35.查看指定的结构使用过的地方:ctrl + alt + g
* 36.查找与替换:ctrl + f
* 37.最大化当前的 View:ctrl + m
* 38.直接定位到当前行的首位:home
* 39.直接定位到当前行的末位:end
*/
重写的规定:
**************************************************************
********
* 子类和父类中的同名同参数的方法要么都声明为非 static 的(考虑重
写),要么都声明为 static 的(不是重写)。static 的一定不可以被重写,
只有非 static 才可以被重写
多态性
方法:编译,看左边;运行,看右边
对象的多态性,只适用于方法,不适用于属性(属性是编译和运行都看左边)
== 和 equals() 区别
*
* 一、回顾 == 的使用:
* == :运算符
* 1. 可以使用在基本数据类型变量和引用数据类型变量中
* 2. 如果比较的是基本数据类型变量:比较两个变量保存的数据是否相等。
(不一定类型要相同)
* 如果比较的是引用数据类型变量:比较两个对象的地址值是否相同.即
两个引用是否指向同一个对象实体
* 补充: == 符号使用时,必须保证符号左右两边的变量类型一致。用“==”
进行比较时,符号两边的数据类型必须兼容(可自动转换的基本数据类型除外),
否则编译出错
*
* 二、equals()方法的使用:
* 1. 是一个方法,而非运算符
* 2. 只能适用于引用数据类型
* 3. Object 类中 equals()的定义:
* public boolean equals(Object obj) {
return (this == obj);
}
* 说明:Object 类中定义的 equals()和==的作用是相同的:比较两个对
象的地址值是否相同.即两个引用是否指向同一个对象实体
*
* 4. 像 String、Date、File、包装类等都重写了 Object 类中的 equals()方
法。重写以后,比较的不是
* 两个引用的地址是否相同,而是比较两个对象的"实体内容"是否相同。
*
* 5. 通常情况下,我们自定义的类如果使用 equals()的话,也通常是比较
两个对象的"实体内容"是否相同。那么,我们
* 就需要对 Object 类中的 equals()进行重写.
* 重写的原则:比较两个对象的实体内容是否相同.
6. 任何情况下,x.equals(null),永远返回是“false”;
7. x.equals(和 x 不同类型的对象)永远返回是“false”。
*/
特殊:char
int i = 10;
char c = 10;
System.out.println(i == c);//true,可以和 char 直接比较,注意这边
的 10 没有单引号,如果是‘10’,则指向的 ASC 码不是 10
char c1 = 'A';
char c2 = 65;
System.out.println(c1 == c2);//true
特殊:string
String s1 = "BB";
String s2 = "BB";
System.out.println(s1 == s2);//true
//因为 BB 是常量,所以指向同一个地址
比较:
this.name.equals(cust.name),这里面的 name 是 string 类型,但是是引
用的地址所以只能用 equals
引用类型:
重写 equals
自动生成的 equals()
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Customer other = (Customer) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
手动重写的 equals
if (this == obj) {
// return true;
// }
//
// if(obj instanceof Customer){
// Customer cust = (Customer)obj;
// //比较两个对象的每个属性是否都相同,引用数据类型要用 equals
了,不能用==了,age 是基本数据类型所以是==
//// if(this.age == cust.age &&
this.name.equals(cust.name)){
//// return true;
//// }else{
//// return false;
//// }
//
// //或
// return this.age == cust.age &&
this.name.equals(cust.name);
// }else{
// return false;
//
// }
包装类
一、字符串转换成基本数据类型
(1)通过包装类的构造器实现:
int i = new Integer(“12”);
(2)通过包装类的 parseXxx(String s)静态方法:
Float f = Float.parseFloat(“12.1”);
二、基本数据类型转换成字符串
(1)调用字符串重载的 valueOf()方法:
String fstr = String.valueOf(2.34f);
(2)更直接的方式:
String intStr = 5 + “”
三、包装类在实际开发中用的最多的在于字符串变为基本数
据类型。
Day13-java2-WrapperTest 全部代码
//303 基本数据类型转换为包装类
//306 基本数据类型包装类与 string 的相互转换
package com.atguigu.java2;
import org.junit.Test;
/*
* 包装类的使用:
* 1.java 提供了 8 种基本数据类型对应的包装类,使得基本数据类型的变量
具有类的特征
*
* 2.掌握的:基本数据类型、包装类、String 三者之间的相互转换
*
*
*
*/
public class WrapperTest {
//String 类型 --->基本数据类型、包装类:调用包装类的
parseXxx(String s)
@Test
public void test5(){
String str1 = "123";
//错误的情况:
// int num1 = (int)str1;
// Integer in1 = (Integer)str1;
//可能会报 NumberFormatException
int num2 = Integer.parseInt(str1);
System.out.println(num2 + 1);
/*
* JDK 5.0 新特性:自动装箱 与自动拆箱
*/
@Test
public void test3(){
// int num1 = 10;
// //基本数据类型-->包装类的对象
// method(num1);
//自动装箱:基本数据类型 --->包装类
int num2 = 10;
Integer in1 = num2;//自动装箱
boolean b1 = true;
Boolean b2 = b1;//自动装箱
//自动拆箱:包装类--->基本数据类型
System.out.println(in1.toString());
int i1 = in1.intValue();
System.out.println(i1 + 1);
//基本数据类型 --->包装类:调用包装类的构造器
@Test
public void test1(){
class Order{
boolean isMale;
Boolean isFemale;//默认值是 null,因为现在它是一个类(引用数据类
型)了,不再是基本数据类型了
}
Junit
/*
* Java 中的 JUnit 单元测试
*
* 步骤:
* 1.选中当前工程(如 day13) - 右键选择:build path - add
libraries - JUnit 4 - 下一步
* 2.创建 Java 类,进行单元测试。
* 此时的 Java 类要求:① 此类是 public 的 ②此类提供公共的无参的构
造器
* 3.此类中声明单元测试方法。
* 此时的单元测试方法:方法的权限是 public,没有返回值,没有形参
*
* 4.此单元测试方法上需要声明注解:@Test,并在单元测试类中导入:
import org.junit.Test;
*
* 5.声明好单元测试方法以后,就可以在方法体内测试相关的代码。
* 6.写完代码以后,左键双击单元测试方法名,右键:run as - JUnit
Test
*
* 说明:
* 1.如果执行结果没有任何异常:绿条
* 2.如果执行结果出现异常:红条
*
* 或者直接写@test 然后程序会报错,然后点一下 build path 就会把上面的
步骤都做完
*/
或者直接写@test 然后程序会报错,然后点一下 build path 就会把上面的步
骤都做完
@Test
public void testToString(){
String s2 = "MM";
System.out.println(s2.toString());
}
1. 代码块的作用:用来初始化类、对象
2. 代码块如果有修饰的话,只能使用 static.除此之前不能用 public, void
等去修饰
3. 分类:静态代码块 vs 非静态代码块
静态代码块:用 static 修饰的代码块
1. 可以有输出语句。
2. 可以对类的属性、类的声明进行初始化操作。
3. 除了调用非静态的结构外,还可以调用静态的变量或方法。
4. 若有多个非静态的代码块,那么按照从上到下的顺序依次执行。
5. 每次创建对象的时候,都会执行一次。且先于构造器执行。
由父及子,静态先行
注意 1:main 方法虽然是程序的入口,但是也是一个普通的静态方法,
所以需要先加载类再加载方法,
注意 2:先加载完父类的非 static block 然后加载父类的 constructor,再
加载子类的非 static block 然后加载子类的 constructor。
执行顺序
1.类:,类的属性,方法,构造器一起加载,没有先后顺序
2.对属性可以赋值的位置:
* ① 默认初始化
* ② 显式初始化/⑤ 在代码块中赋值,(按照先后顺序,谁后出现就是修改前
面的)
* ③ 构造器中初始化
* ④ 有了对象以后,可以通过"对象.属性"或"对象.方法"的方式,进行赋值
* 执行的先后顺序:① - ② / ⑤ - ③ - ④
Final
Abstract day15
用 abstract 关键字来修饰一个类,这个类叫做抽象类。
用 abstract 来修饰一个方法,该方法叫做抽象方法。
抽象方法:只有方法的声明,没有方法的实现。以分号结束:
比如:public abstract void talk();
含有抽象方法的类必须被声明为抽象类。
抽象类不能被实例化。抽象类是用来被继承的,抽象类的子类必须重
写父类的抽象方法,并提供方法体。若没有重写全部的抽象方法,仍
为抽象类。
不能用 abstract 修饰变量、代码块、构造器;
不能用 abstract 修饰私有方法、静态方法、final 的方法、final 的类。
接口 day15
接口(interface)是抽象方法和常量值定义的集合。
接口的特点:
用 interface 来定义。
接口中的所有成员变量都默认是由 public static final 修饰的。
接口中的所有抽象方法都默认是由 public abstract 修饰的。
接口中没有构造器。
接口采用多继承机制。
接口定义举例
public interface Runner {
public static final int ID = 1;
public abstract void start();
public abstract void run();
public abstract void stop();
}
定义 Java 类的语法格式:先写 extends,后写 implements
class SubClass extends SuperClass implements InterfaceA{ }
一个类可以实现多个接口,接口也可以继承其它接口。
实现接口的类中必须提供接口中所有方法的具体实现内容,方可实
例化。否则,仍为抽象类。
接口的主要用途就是被实现类实现。(面向接口编程)
与继承关系类似,接口与实现类之间存在多态性
接口和类是并列关系,或者可以理解为一种特殊的类。从本质上讲,
接口是一种特殊的抽象类,这种抽象类中只包含常量和方法的定义
(JDK7.0 及之前),而没有变量和方法的实现
Java 快捷键
//输入 fori+回车快速生成下面的循环
//ctrl+o 搜索方法
//快捷键:new MyThread()+.var 就可以补全前面的 MyThread myThread,不用自己一个个打了;
//注意不是 new MyThread();+.var
//快捷键 new Thread()+"ctrl+alt+/"就可以快速查看有哪些 parameters
//alt+shift+s 快速创建各种构造器,getset 方法等
//快速包裹 trycatchfinally 快捷键:alter+shift+z
Ctrl+shift+T 快速查找各种 api 文档