目录
Java基础快速浏览
基本结构
/**
* 可以用来自动创建文档的注释
*/
public class Hello {
public static void main(String[] args) {
// 向屏幕输出文本:
System.out.println("Hello, world!");
/* 多行注释开始
注释内容
注释结束 */
}
} // class定义结束
public
修饰符,表示公开
class
类
Hello
类名
public static void main(String[] args)
Java入口程序基本写法
数据类型
基本类型
- 整形 int、long、short、byte -->精确
- 浮点型 float、double–>不精确
- 字符型 char–>单引号
'
- 布尔型 boolean
引用类型
- 字符串string–>变的是指向,null表示不指向任何对象,null!=“”
- 数组 类型[] {}
- 所有的class类型和interface类型
流程控制
输出
System.out.println()
System.out.print()
System.out.printf()//可以格式化输出
输入
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in); // 创建Scanner对象
System.out.print("Input your name: "); // 打印提示
String name = scanner.nextLine(); // 读取一行输入并获取字符串
System.out.print("Input your age: "); // 打印提示
int age = scanner.nextInt(); // 读取一行输入并获取整数
System.out.printf("Hi, %s, you are %d\n", name, age); // 格式化输出
}
}
占位符 | 说明 |
---|---|
%d | 格式化输出整数 |
%x | 格式化输出十六进制整数 |
%f | 格式化输出浮点数 |
%e | 格式化输出科学计数法表示的浮点数 |
%s | 格式化字符串 |
判断
if else
switch
循环
while——不一定会被执行
do while——至少执行一次
for
for each——遍历数组元素,无索引for(int n : array)
break——穿透性,跳出当前整个循环
continue——跳出本次循环,继续下次
面向对象
- 类:字段、方法、构造方法
- 方法重载overload–>名同参数不同返回值同
- 继承extends:父类、子类
- 方法覆写override–>子类同父类方法同名同参同返回
- 抽象类abstract:方法没有执行语句,只定义
- 接口:没有字段的抽象类
- 静态static:共享
- 接口implement实现、类new实现实例
Java核心类
字符串
-
引用类,本身class,
String s2 = new String(new char[] {'H', 'e', 'l', 'l', 'o', '!'});
不可变 -
比较用
equal()
,不能用==
,忽略大小比较equalsIgnoreCase()
-
判断是否包含字符
contains()
-
字符索引
indexOf()
、lastIndexOf()
-
判断首/尾字符是否为
startWith()
、endWith()
-
提取子串
substring()
,闭合区间[) -
去除首尾空白符
trim()
-
是否为空
isEmpty()
,是否为空白isBlank()
-
替换
replace()
-
分割,字符串变数组
split()
-
拼接,数组变字符串
String.join()
-
类型转换,其他变为字符串
String.valueOf()
-
类型转换,其他变为int
Integer.parseInt()
-
类型转换,其他变布尔
Boolean.parseBoolean()
-
类型转换,字符与字符串
-
char[] cs = "Hello".toCharArray(); // String -> char[] String s = new String(cs); // char[] -> String
字符编码
ASCII、GB2312、Unicode、UTF-8
基本类的包装类型
java.lang.[基本类型]
int-->java.lang.Integer
int可与Integer赋值时自动转换
int
变为Integer
的赋值写法–>自动装箱(Auto Boxing)Integer
变为int
的赋值写法–>自动拆箱(Auto Unboxing)
JavaBean
符合以下条件的类:
-
若干
private
实例字段 -
通过
public
方法来读写实例字段 -
读写方法符合
-
// 读方法: public Type getXyz() // 写方法: public void setXyz(Type value)
枚举类
enum Weekday {
SUN, MON, TUE, WED, THU, FRI, SAT;
}
目的:使编译器可以在编译期自动检查出所有可能的潜在错误
-
- 类型错误
int day = 1; if (day == Weekday.SUN) { // Compile error: bad operand types for binary operator '==' }
- 不可能引用到非枚举的值
Weekday x = Weekday.SUN; // ok! Weekday y = Color.RED; // Compile error: incompatible types
-
引用类型,但可用“==”比较
-
就是class,继承自
java.lang.Enum
,且无法被继承 -
可用于switch
-
可以为enum编写构造方法、字段和方法。enum的构造方法要声明为
private
,字段强烈建议声明为final
-
每个枚举值就是实例,有方法:
String s = Weekday.SUN.name(); // "SUN",常量名 int n = Weekday.MON.ordinal(); // 1,常量的顺序
BigInteger
- 用来表示任意大小的整数
- 是不变类,并且继承自
Number
BigDecimal
- 用于表示精确的小数,常用于财务计算
compareTo()
比较两个BigDecimal的值,不要使用equals()!!!
常用工具类
-
Math
.PI//常量,3.14159... .E//2.718... .abs()//绝对值 .max()//最大值 .min()//最小值 .pow(x,y)//x的y次方 .sqrt(x)//根号x .exp(x)//e的x次方 .log(x)//以e为底的x的对数 .log10(x)//以10为底的x的对数 .sin()//三角函数 .cos() .tan() .acos()
-
Random
Math.random()//[0,1) // 区间在[MIN, MAX)的随机数 public class Main { public static void main(String[] args) { double x = Math.random(); // x的范围是[0,1) double min = 10; double max = 50; double y = x * (max - min) + min; // y的范围是[10,50) long n = (long) y; // n的范围是[10,50)的整数 System.out.println(y); System.out.println(n); } } Random r = new Random(); r.nextInt(); // 2071575453,每次都不一样 r.nextInt(10); // 5,生成一个[0,10)之间的int r.nextLong(); // 8811649292570369305,每次都不一样 r.nextFloat(); // 0.54335...生成一个[0,1)之间的float r.nextDouble(); // 0.3716...生成一个[0,1)之间的double //伪随机数,每次生成特定的随机数列 public class Main { public static void main(String[] args) { Random r = new Random(12345); for (int i = 0; i < 10; i++) { System.out.println(r.nextInt(100)); } // 51, 80, 41, 28, 55... } }
-
SecureRandom
不可预测的安全的随机数
SecureRandom sr = new SecureRandom(); System.out.println(sr.nextInt(100)); //实际使用的时候,可以优先获取高强度的安全随机数生成器,如果没有提供,再使用普通等级的安全随机数生成器 public class Main { public static void main(String[] args) { SecureRandom sr = null; try { sr = SecureRandom.getInstanceStrong(); // 获取高强度安全随机数生成器 } catch (NoSuchAlgorithmException e) { sr = new SecureRandom(); // 获取普通的安全随机数生成器 } byte[] buffer = new byte[16]; sr.nextBytes(buffer); // 用安全随机数填充buffer System.out.println(Arrays.toString(buffer)); } }
异常处理
异常
throwable–>error、exception
error
OutOfMemoryError
:内存耗尽NoClassDefFoundError
:无法加载某个ClassStackOverflowError
:栈溢出
exception逻辑处理问题
NumberFormatException
:数值类型的格式错误FileNotFoundException
:未找到文件SocketException
:读取网络失败
exception逻辑编写问题
NullPointerException
:对某个null
的对象调用方法或字段IndexOutOfBoundsException
:数组索引越界
捕获异常
-
try...catch
针对语句,可能发生异常的代码放到
try {...}
中,然后使用catch
捕获对应的Exception
及其子类 -
throws Xxx
针对方法定义,表示该方法可能抛出的异常类型
public class Main { public static void main(String[] args) throws Exception { byte[] bs = toGBK("中文"); System.out.println(Arrays.toString(bs)); } static byte[] toGBK(String s) throws UnsupportedEncodingException { // 用指定编码转换String为byte[]: return s.getBytes("GBK"); } }
-
try ... catch ... finally
finally语句保证了有无异常都会执行,总是最后执行,它是可选的
public static void main(String[] args) { try { process1(); process2(); process3(); } catch (UnsupportedEncodingException e) { System.out.println("Bad encoding"); } catch (IOException e) { System.out.println("IO error"); } finally { System.out.println("END"); } }
某些情况下,可以没有
catch
,只使用try ... finally
结构void process(String file) throws IOException { try { ... } finally { System.out.println("END"); } }
-
捕获多种异常
public static void main(String[] args) { try { process1(); process2(); process3(); } catch (IOException | NumberFormatException e) { // IOException或NumberFormatException System.out.println("Bad input"); } catch (Exception e) { System.out.println("Unknown error"); } }
抛出异常
printStackTrace可以打印异常的传播栈,对于调试非常有用
e.printStackTrace();
public class Main {
public static void main(String[] args) {
try {
process1();
} catch (Exception e) {
e.printStackTrace();
}
}
static void process1() {
try {
process2();
} catch (NullPointerException e) {
throw new IllegalArgumentException(e);
}
}
static void process2() {
throw new NullPointerException();
}
}
还可以:自定义异常、使用断言、打印日志(SLF4J+Logback)
反射
指程序在运行期可以拿到一个对象的所有信息
注解
- 放在Java源码的类、方法、字段、参数前的一种特殊“注释”
- 注解可以配置参数,没有指定配置的参数使用默认值
@interface
定义注解- 可定义多个参数和默认值,核心参数使用
value
名称 - 元注解(可以修饰其他注解):@Target、@Retention、@Inherited
泛型
- 定义一种模板,例如
ArrayList<T>
,然后在代码中为用到的类创建对应的ArrayList<类型>
- 可以把
ArrayList<Integer>
向上转型为List<Integer>
(T
不能变!),但不能把ArrayList<Integer>
向上转型为ArrayList<Number>
(T
不能变成父类) - 使用泛型时,把泛型参数
<T>
替换为需要的class类型,例如:ArrayList<String>
,ArrayList<Number>
等 - 可以省略编译器能自动推断出的类型,例如:
List<String> list = new ArrayList<>();
- 可以在接口中定义泛型类型,实现此接口的类必须实现正确的泛型类型
集合
如果一个Java对象可以在内部持有若干其他Java对象,并对外提供访问接口,我们把这种Java对象称为集合。
接口:
List
:一种有序列表的集合,例如,按索引排列的Student
的List
Set
:一种保证没有重复元素的集合,例如,所有无重复名称的Student
的Set
Map
:一种通过键值(key-value)查找的映射表集合,例如,根据Student
的name
查找对应Student
的Map
实现类:
ArrayList
,LinkedList
等
List
最常用ArrayList
List<String> list = new ArrayList<>();
- 在末尾添加一个元素:
void add(E e)
- 在指定索引添加一个元素:
void add(int index, E e)
- 删除指定索引的元素:
int remove(int index)
- 删除某个元素:
int remove(Object e)
- 获取指定索引的元素:
E get(int index)
- 获取链表大小(包含元素的个数):
int size()
遍历for each
public class Main {
public static void main(String[] args) {
List<String> list = List.of("apple", "pear", "banana");
for (String s : list) {
System.out.println(s);
}
}
}
Map
最常用HashMap
Map<String, Student> map = new HashMap<>();
- 添加/修改:put(key,value)
- 获取:get(key)
遍历
public class Main {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<>();
map.put("apple", 123);
map.put("pear", 456);
map.put("banana", 789);
for (String key : map.keySet()) {
Integer value = map.get(key);
System.out.println(key + " = " + value);
}
}
}
public class Main {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<>();
map.put("apple", 123);
map.put("pear", 456);
map.put("banana", 789);
for (Map.Entry<String, Integer> entry : map.entrySet()) {
String key = entry.getKey();
Integer value = entry.getValue();
System.out.println(key + " = " + value);
}
}
}
EnumMap
如果Map
的key是enum
类型,推荐使用EnumMap
EnumMap
有序
Properties
用Properties
读取配置文件非常简单。Java默认配置文件以.properties
为扩展名,每行以key=value
表示,以#
课开头的是注释
Set
存储不重复的元素集合,相当于只存储key、不存储value的Map
最常用HashSet
Set<String> set = new HashSet<>();
- 将元素添加进
Set<E>
:boolean add(E e)
- 将元素从
Set<E>
删除:boolean remove(Object e)
- 判断是否包含元素:
boolean contains(Object e)
遍历
public class Main {
public static void main(String[] args) {
Set<String> set = new HashSet<>();
set.add("apple");
set.add("banana");
set.add("pear");
set.add("orange");
for (String s : set) {
System.out.println(s);
}
}
}
TreeSet
有序
Queue
队列,先进先出
- 通过
add()
/offer()
方法将元素添加到队尾; - 通过
remove()
/poll()
从队首获取元素并删除; - 通过
element()
/peek()
从队首获取元素但不删除。
PriorityQueue
优先队列,从队首获取元素时,总是获取优先级最高的元素
Deque
双端队列
- 将元素添加到队尾或队首:
addLast()
/offerLast()
/addFirst()
/offerFirst()
; - 从队首/队尾获取元素并删除:
removeFirst()
/pollFirst()
/removeLast()
/pollLast()
; - 从队首/队尾获取元素但不删除:
getFirst()
/peekFirst()
/getLast()
/peekLast()
; - 总是调用
xxxFirst()
/xxxLast()
以便与Queue
的方法区分开; - 避免把
null
添加到队列
Stack
栈,后进先出
- 把元素压栈:
push(E)
; - 把栈顶的元素“弹出”:
pop(E)
; - 取栈顶元素但不弹出:
peek(E)
。
Iterator
迭代器,通过Iterator
对象遍历集合的模式
Java的集合类都可以使用for each
循环
- 对任何集合都采用同一种访问模型;
- 调用者对集合内部结构一无所知;
- 集合类返回的
Iterator
对象知道如何迭代。
Collections
提供了一组工具方法来方便使用集合类
- 创建空集合;
- 创建单元素集合;
- 创建不可变集合;
- 排序/洗牌等操作。
IO
File
File f = new File("C:\\Windows\\notepad.exe");
- 创建
File
对象本身不涉及IO操作; - 可以获取路径/绝对路径/规范路径:
getPath()
/getAbsolutePath()
/getCanonicalPath()
; - 可以获取目录的文件和子目录:
list()
/listFiles()
; - 可以创建或删除文件和目录。
InputStream
最基本的输入流
FileInputStream
是InputStream
的一个子类
public void readFile() throws IOException {
try (InputStream input = new FileInputStream("src/readme.txt")) {
int n;
while ((n = input.read()) != -1) {
System.out.println(n);
}
} // 编译器在此自动为我们写入finally并调用close()
}
OutputStream
最基本的输出流
public void writeFile() throws IOException {
try (OutputStream output = new FileOutputStream("out/readme.txt")) {
output.write("Hello".getBytes("UTF-8")); // Hello
} // 编译器在此自动为我们写入finally并调用close()
}