Skip to content

Latest commit

History

History
1941 lines (1536 loc) · 41 KB

File metadata and controls

1941 lines (1536 loc) · 41 KB

Java 备忘清单

该备忘单是针对 Java 初学者的速成课程,有助于复习 Java 语言的基本语法。

入门

Hello.java

publicclassHello {
// 主要方法publicstaticvoidmain(String[] args)
{
// 输出: Hello, world!System.out.println("Hello, world!");
}
}

编译和运行

$ javac Hello.java
$ java Hello
Hello, world!

变量 Variables

intnum = 5;
floatfloatNum = 5.99f;
charletter = 'D';
booleanbool = true;
Stringsite = "jaywcjlove.github.io";

原始数据类型

数据类型大小默认范围
byte1 byte0-128 ^to^ 127
short2 byte0-2^15^ ^to^ 2^15^-1
int4 byte0-2^31^ ^to^ 2^31^-1
long8 byte0-2^63^ ^to^ 2^63^-1
float4 byte0.0fN/A
double8 byte0.0dN/A
char2 byte\u00000 ^to^ 65535
booleanN/Afalsetrue / false

字符串 Strings

Stringfirst = "John";
Stringlast = "Doe";
Stringname = first + " " + last;
System.out.println(name);

查看: Strings

循环 Loops

Stringword = "QuickRef";
for (charc: word.toCharArray()) {
System.out.print(c + "-");
}
// 输出: Q-u-i-c-k-R-e-f-

查看: Loops

数组 Arrays

char[] chars = newchar[10];
chars[0] = 'a';
chars[1] = 'b';
String[] letters = {"A", "B", "C"};
int[] mylist = {100, 200};
boolean[] answers = {true, false};

查看: Arrays

交换变量 Swap

inta = 1;
intb = 2;
System.out.println(a + " " + b); // 1 2inttemp = a;
a = b;
b = temp;
System.out.println(a + " " + b); // 2 1

类型转换 Type Casting

// Widening// byte<short<int<long<float<doubleinti = 10;
longl = i; // 10// Narrowingdoubled = 10.02;
longl = (long)d; // 10String.valueOf(10); // "10"Integer.parseInt("10"); // 10Double.parseDouble("10"); // 10.0

条件语句 Conditionals

intj = 10;
if (j == 10) {
System.out.println("I get printed");
} elseif (j > 10) {
System.out.println("I don't");
} else {
System.out.println("I also don't");
}

查看: [Conditionals](#条件语句 Conditionals)

用户输入

Scannerin = newScanner(System.in);
Stringstr = in.nextLine();
System.out.println(str);
intnum = in.nextInt();
System.out.println(num);

Java 字符串

基本的

Stringstr1 = "value";
Stringstr2 = newString("value");
Stringstr3 = String.valueOf(123);

字符串连接

Strings = 3 + "str" + 3; // 3str3Strings = 3 + 3 + "str"; // 6strStrings = "3" + 3 + "str"; // 33strStrings = "3" + "3" + "23"; // 3323Strings = "" + 3 + 3 + "23"; // 3323Strings = 3 + 3 + 23; // 29

字符串生成器

StringBuildersb = newStringBuilder(10);

┌───┬───┬───┬───┬───┬───┬───┬───┬───┐
| | | | | | | | | |
└───┴───┴───┴───┴───┴───┴───┴───┴───┘
0123456789

sb.append("Reference");

┌───┬───┬───┬───┬───┬───┬───┬───┬───┐
| R | e | f | e | r | e | n | c | e |
└───┴───┴───┴───┴───┴───┴───┴───┴───┘
0123456789

sb.delete(3, 9);

┌───┬───┬───┬───┬───┬───┬───┬───┬───┐
| R | e | f | | | | | | |
└───┴───┴───┴───┴───┴───┴───┴───┴───┘
0123456789

sb.insert(0, "My ");

┌───┬───┬───┬───┬───┬───┬───┬───┬───┐
| M | y | | R | e | f | | | |
└───┴───┴───┴───┴───┴───┴───┴───┴───┘
0123456789

sb.append("!");

┌───┬───┬───┬───┬───┬───┬───┬───┬───┐
| M | y | | R | e | f | ! | | |
└───┴───┴───┴───┴───┴───┴───┴───┴───┘
0123456789

比较

Strings1 = "QuickRef";
Strings2 = newString("QuickRef");
s1 == s2// falses1.equals(s2) // true// intern 方法获得字符串常量池中的惟一引用s1 == s2.intern() // true"AB".equalsIgnoreCase("ab") // true

操纵

Stringstr = "Abcd";
str.toUpperCase(); // ABCDstr.toLowerCase(); // abcdstr.concat("#"); // Abcd#str.replace("b", "-"); // A-cd" abc ".trim(); // abc"ab".toCharArray(); // {'a', 'b'}

信息

Stringstr = "abcd";
str.charAt(2); // cstr.indexOf("a") // 0str.indexOf("z") // -1str.length(); // 4str.toString(); // abcdstr.substring(2); // cdstr.substring(2,3); // cstr.contains("c"); // truestr.endsWith("d"); // truestr.startsWith("a"); // truestr.isEmpty(); // false

不可变

Stringstr = "hello";
str.concat("world");
// 输出: helloSystem.out.println(str);

Stringstr = "hello";
Stringconcat = str.concat("world");
// 输出: helloworldSystem.out.println(concat);

一旦创建就不能修改,任何修改都会创建一个新的String

Java 数组

声明 Declare

int[] a1;
int[] a2 = {1, 2, 3};
int[] a3 = newint[]{1, 2, 3};
int[] a4 = newint[3];
a4[0] = 1;
a4[1] = 2;
a4[2] = 3; // 正常赋值a4[3] = 4; // 会出现索引越界异常 ArrayIndexOutOfBoundsException

修改 Modify

int[] a = {1, 2, 3};
System.out.println(a[0]); // 1a[0] = 9;
System.out.println(a[0]); // 9System.out.println(a.length); // 3

循环 (读 & 写)

int[] arr = {1, 2, 3};
for (inti=0; i < arr.length; i++) {
arr[i] = arr[i] * 2;
System.out.print(arr[i] + " ");
}
// 输出: 2 4 6

Loop (Read)

String[] arr = {"a", "b", "c"};
for (Stringa: arr) {
System.out.print(a + " ");
}
// 输出: a b c

二维数组 Multidimensional Arrays

int[][] matrix = {{1, 2, 3}, {4, 5}, {6}};
intx = matrix[1][0]; // 4System.out.println(Arrays.deepToString(matrix));
// 输出: [[1, 2, 3], [4, 5], [6]]for (inti = 0; i < matrix.length; ++i) {
for(intj = 0; j < matrix[i].length; ++j) {
System.out.println(matrix[i][j]);
}
}
// 输出: 1 2 3 4 5 6

排序 Sort

char[] chars = {'b', 'a', 'c'};
Arrays.sort(chars);
// [a, b, c]Arrays.toString(chars);

Java 条件语句

运算符

  • +(加法运算符(也用于字符串连接))
  • -(减法运算符)
  • *(乘法运算符)
  • /(分区运算符)
  • %(余数运算符)
  • =(简单赋值运算符)
  • ++(增量运算符;将值增加 1)
  • --(递减运算符;将值减 1)
  • !(逻辑补码运算符;反转布尔值)

  • ==(等于)
  • !=(不等于)
  • >(比...更棒)
  • >=(大于或等于)
  • <(少于)
  • <=(小于或等于)

  • &&条件与
  • ||条件或
  • ?:三元(if-then-else 语句的简写)

  • instanceof(将对象与指定类型进行比较)

  • ~(一元按位补码)
  • <<(签名左移)
  • >>(有符号右移)
  • >>>(无符号右移)
  • &(按位与)
  • ^(按位异或)
  • |(按位包含 OR)

If else

intk = 15;
if (k > 20) {
System.out.println(1);
} elseif (k > 10) {
System.out.println(2);
} else {
System.out.println(3);
}

Switch

intmonth = 3;
Stringstr;
switch (month) {
case1:
str = "January";
break;
case2:
str = "February";
break;
case3:
str = "March";
break;
default:
str = "Some other month";
break;
}
// 输出: Result MarchSystem.out.println("Result " + str);

三元运算符

inta = 10;
intb = 20;
intmax = (a > b) ? a : b;
// 输出: 20System.out.println(max);

逻辑运算符

// 与运算if (condition1 && condition2) {
// 如果 condition1 和 condition2 都成立// 则执行此处的代码
}
// 或运算if (condition1 || condition2) {
// 如果condition1或condition2任意一个成立// 则执行此处的代码
}
// 非运算if (!condition) {
// 如果条件不成立,则执行此处的代码
}

比较运算

// 等于if (a == b) {
// 如果a等于b,则执行此处的代码
}
// 不等于if (a != b) {
// 如果a不等于b,则执行此处的代码
}
// 大于、大于等于、小于、小于等于if (a > b) {}
if (a >= b) {}
if (a < b) {}
if (a <= b) {}

Java 循环

For 循环

for (inti = 0; i < 10; i++) {
System.out.print(i);
}
// 输出: 0123456789

for (inti = 0,j = 0; i < 3; i++,j--) {
System.out.print(j + "|" + i + " ");
}
// 输出: 0|0 -1|1 -2|2

增强的 For 循环

int[] numbers = {1,2,3,4,5};
for (intnumber: numbers) {
System.out.print(number);
}
// 输出: 12345

用于循环数组或列表

While 循环

intcount = 0;
while (count < 5) {
System.out.print(count);
count++;
}
// 输出: 01234

Do While 循环

intcount = 0;
do {
System.out.print(count);
count++;
} while (count < 5);
// 输出: 01234

继续语句

for (inti = 0; i < 5; i++) {
if (i == 3) {
continue;
}
System.out.print(i);
}
// 输出: 0124

中断语句

for (inti = 0; i < 5; i++) {
System.out.print(i);
if (i == 3) {
break;
}
}
// 输出: 0123

Java 面向对象

类的定义

publicclassDog {
privateStringname;
// 构造方法无无返回值,方法名与类名相同// 一个类可以有多个构造方法// Java 默认提供一个无参构造方法(只有在没有显式定义任何构造方法时)publicDog() {
}
publicDog(Stringname) {
this.name = name;
}
}

类中的变量

publicclassDog {
// 成员变量privateStringname;
// 类变量// 多对象将会共享同一个类变量staticintval = 10;
publicvoidSay() {
// 局部变量Stringsentence = "hello";
System.out.println(sentence);
}
}

对象的创建

DogmyDog = newDog(); // 调用无参构造函数DogmyDog2 = newDog("aaa"); // 调用对应参数列表的构造函数// 调用方法myDog.Say();

对象的继承

publicAnimal {
publicStringname;
publicAnimal(Stringname) {
this.name = name;
}
publicvoideat() {
System.out.println("eat something");
}
}
// Dog类继承Animal类publicDogextendsAnimal {
// 调用父类的构造函数publicDog(Stringname){
super(name);
}
}

请注意Java不支持多继承,只能够单继承,但支持多重继承 即,一个类最多只有一个父类,但可以有爷爷类和太爷爷类

Java继承的特点

  • 子类拥有父类中可访问的属性和方法(public、protected 以及同包访问权限的成员)
  • 子类可以有自己的属性、方法
  • 子类可以重写父类的方法

super 与 this

super引用当前类的父类 this引用自身

classAnimal {
voideat() {
System.out.println("animal : eat");
}
}
classDogextendsAnimal {
voideat() {
System.out.println("dog : eat");
}
voideatTest() {
this.eat(); // this 调用自己的方法super.eat(); // super 调用父类方法
}
}

final 关键字

被final 关键字修饰的类不能够被继承 被final 关键字修饰的方法不能被子类重写

Java的重写(Override)与重载(Overload)

重写(Override)

重写者位于被重写者的子类中 重写者的签名必须与被重写者的签名相同

classAnimal {
// 被重写者voidsay(Stringsentence) {
System.out.println("Animal say: " + sentence);
}
}
classDogextendsAnimal {
// 重写者// 重写者位于被重写者的子类 重写一般需要添加 @Override 注解@Overridevoidsay(Stringsentence) { // 签名与被重写者相同System.out.println("Dog say: " + sentence);
}
}

重载(Overload)

重载位于同一类内部 签名必须不同

publicclassOverloading {
publicinttest(){
System.out.println("test1");
return1;
}
publicvoidtest(inta) {
System.out.println("test2");
}
//以下两个参数类型顺序不同publicStringtest(inta,Strings){
System.out.println("test3");
return"returntest3";
}
publicStringtest(Strings,inta){
System.out.println("test4");
return"returntest4";
}
}

Java 抽象类

抽象类不能被实例化为对象,因此,抽象类必须被继承才能够使用 抽象类使用abstract 关键字进行修饰

publicabstractclassAnimal {
Stringname;
publicAnimal(Stringname) {
this.name = name;
}
}
publicclassDogextendsAnimal {
publicDog(Stringname) {
super(name);
}
}

使用abstract 关键字修饰的方法是抽象方法 抽象方法必须包含在抽象类中 子类必须重写父类中的所有抽象方法,除非子类也是抽象类

publicabstractclassAnimal {
Stringname;
publicAnimal(Stringname) {
this.name = name;
}
publicabstractvoidsay();
}
publicclassDogextendsAnimal {
publicDog(Stringname) {
super(name);
}
publicvoidsay(){
System.out.println("Dog");
}
}

Java 接口

接口的定义

与类的继承不同,接口可以继承多个接口

[可见性修饰符] interface接口名称 [extends其他接口名列表] {
// 声明变量// 抽象方法
}

接口的实现

一个类可以实现多个接口 类必须实现接口的所有方法,除非该类是抽象类

publicinterfaceAnimal {
publicvoideat();
publicvoidsay();
}
publicclassDogimplementsAnimal {
publicvoideat() {
System.out.println("Dog eat something");
}
publicvoidsay() {
System.out.println("Dog say something");
}
}

Java 多线程

创建线程

// 实现Runnable接口publicclassRunnableThreadimplementsRunnable {
@Overridepublicvoidrun() {
// todo something
}
}

实现Callable接口,T 替换成实际类型

publicclassCallableTaskimplementsCallable<T> {
@OverridepublicTcall() throwsException {
// todo somethingreturnnull;
}
}

继承Thrad类

publicclassExtendsThreadextendsThread {
@Overridepublicvoidrun() {
// todo something
}
}

运行线程

publicstaticvoidmain(String[] args) throwsExecutionException, InterruptedException {
newThread(newRunnableThread()).start();
newExtendsThread().start();
FutureTask<Integer> integerFutureTask = newFutureTask<>(newCallableTask());
integerFutureTask.run();
}

线程池

  • corePoolSize: 核心线程数
  • maximumPoolSize: 最大线程数
  • keepAliveTime: 线程空闲时间
  • TimeUnit: 线程空闲时间单位
  • workQueue: 线程等待队列
  • threadFactory: 线程创建工厂
  • handler: 拒绝策略
ThreadPoolExecutorthreadPoolExecutor
= newThreadPoolExecutor(
2, 5,
5, TimeUnit.SECONDS,
newArrayBlockingQueue<>(10),
newDefaultThreadFactory("pollName"),
newThreadPoolExecutor.CallerRunsPolicy()
);
// 内置的线程池, 不推荐生产使用Executors.newCachedThreadPool();
Executors.newFixedThreadPool(10);
Executors.newScheduledThreadPool(10);
Executors.newSingleThreadExecutor();

synchronized

// 代码块synchronized(obj) {
...
}
// 实例方法同步publicsynchronizedvoidmethodName() {
...
}
// 静态方法同步publicstaticsynchronizedvoidmethodName() {
...
}

线程编排

// CountDownLatchCountDownLatchcountDownLatch = newCountDownLatch(2);
newThread(() -> {
try {
...
}finally {
countDownLatch.countDown();
}
}).start();
countDownLatch.await();

CompletableFuture

CompletableFuture<Void> task1 = CompletableFuture.runAsync(() -> {});
CompletableFuture<Void> task2 = CompletableFuture.runAsync(() -> {});
CompletableFuture<Void> task3 = CompletableFuture.runAsync(() -> {});
CompletableFuture.allOf(task1, task2, task3).get();

Semaphore

Semaphoresemaphore = newSemaphore(5);
try {
semaphore.acquire();
} finally {
semaphore.release();
}

ThreadLocal

ThreadLocal<Integer> threadLocal
= newThreadLocal<>();

使用完之后一定要记得 remove, 否则会内存泄露

threadLocal.set(1);
threadLocal.get();
threadLocal.remove();

线程等待与唤醒

// 需要synchronized修饰的代码块才能使用wait();
notify();
notifyAll();
// 使用lock的条件唤醒ReentrantLocklock = newReentrantLock();
Conditioncondition= lock.newCondition();
lock.lock();
try{
// 当前线程唤醒或等待condition.await();
condition.signal();
condition.signalAll();
} finally {
lock.unlock();
}
// LockSupport,可以先unpark,后续park不会阻塞线程LockSupport.park(obj);
LockSupport.unpark(thread);

Java 框架搜集

Java 集合

集合Interface有序已排序线程安全复制Nullable
ArrayListListYNNYY
VectorListYNYYY
LinkedListList, DequeYNNYY
CopyOnWriteArrayListListYNYYY
HashSetSetNNNNOne null
LinkedHashSetSetYNNNOne null
TreeSetSetYYNNN
CopyOnWriteArraySetSetYNYNOne null
ConcurrentSkipListSetSetYYYNN
HashMapMapNNNN (key)One null(key)
HashtableMapNNYN (key)N (key)
LinkedHashMapMapYNNN (key)One null(key)
TreeMapMapYYNN (key)N (key)
ConcurrentHashMapMapNNYN (key)N
ConcurrentSkipListMapMapYYYN (key)N
ArrayDequeDequeYNNYN
PriorityQueueQueueYNNYN
ConcurrentLinkedQueueQueueYNYYN
ConcurrentLinkedDequeDequeYNYYN
ArrayBlockingQueueQueueYNYYN
LinkedBlockingDequeDequeYNYYN
PriorityBlockingQueueQueueYNYYN

ArrayList

List<Integer> nums = newArrayList<>();
// 添加nums.add(2);
nums.add(5);
nums.add(8);
// 检索System.out.println(nums.get(0));
// 为循环迭代编制索引for (inti = 0; i < nums.size(); i++) {
System.out.println(nums.get(i));
}
nums.remove(nums.size() - 1);
nums.remove(0); // 较慢,因为需要移动后续元素for (Integervalue : nums) {
System.out.println(value);
}
// lambda 打印元素nums.forEach(
e -> System.out.println(e.toString())
);

HashMap

Map<Integer, String> m = newHashMap<>();
m.put(5, "Five");
m.put(8, "Eight");
m.put(6, "Six");
m.put(4, "Four");
m.put(2, "Two");
// 检索System.out.println(m.get(6));
// Lambda forEachm.forEach((key, value) -> {
Stringmsg = key + ": " + value;
System.out.println(msg);
});

ConcurrentHashMap

ConcurrentHashMap<Integer, String> m
= newConcurrentHashMap<>();
m.put(100, "Hello");
m.put(101, "Geeks");
m.put(102, "Geeks");
// 移除m.remove(101, "Geeks");
// 如果不存在,就添加,存在就不变更m.putIfAbsent(103, "Hello");
// 替换m.replace(101, "Hello", "For");
System.out.println(m);

HashSet

Set<String> set = newHashSet<>();
if (set.isEmpty()) {
System.out.println("Empty!");
}
set.add("dog");
set.add("cat");
set.add("mouse");
set.add("snake");
set.add("bear");
if (set.contains("cat")) {
System.out.println("Contains cat");
}
set.remove("cat");
for (Stringelement : set) {
System.out.println(element);
}
set.forEach(
e -> System.out.println(e.toString())
);

ArrayDeque

Deque<String> a = newArrayDeque<>();
// 使用 add()a.add("Dog");
// 使用 addFirst()a.addFirst("Cat");
// 使用 addLast()a.addLast("Horse");
// [Cat, Dog, Horse]System.out.println(a);
// 访问元素System.out.println(a.peek());
// 移除元素System.out.println(a.pop());

Java I/O流

常见的类和操作

字节流

  • InputStream 字节输入流的抽象基类
  • FileInputStream 从文件中读取字节的输入流
  • ByteArrayInputStream 从字节数组中读取字节的输入流
  • OutputStream 字节输出流的抽象基类
  • FileOutputStream 向文件中写入字节的输出流
  • ByteArrayOutputStream 将字节写入到字节数组的输出流

字符流

  • Reader 字符输入流的抽象基类
  • FileReader 从文件中读取字符的输入流
  • BufferedReader 带缓冲区的字符输入流
  • InputStreamReader 字节流到字符流的桥接器
  • Writer 字符输出流的抽象基类
  • FileWriter 向文件中写入字符的输出流
  • BufferedWriter 带缓冲区的字符输出流
  • OutputStreamWriter 字符流到字节流的桥接器

对象流

  • ObjectInputStream 从输入流中读取Java对象的流
  • ObjectOutputStream 将Java对象写入输出流的流

缓冲流

  • BufferedInputStream 带缓冲区的字节输入流
  • BufferedOutputStream 带缓冲区的字节输出流
  • BufferedReader 带缓冲区的字符输入流
  • BufferedWriter 带缓冲区的字符输出流

数据流

  • DataInputStream 从输入流中读取基本数据类型的数据
  • DataOutputStream 将基本数据类型数据写入输出流

文件类

  • File 文件和目录路径名的抽象表示
  • FileReader 从文件中读取字符的输入流
  • FileWriter 向文件中写入字符的输出流

输入输出异常处理

  • IOException Java I/O操作中的通用异常
  • FileNotFoundException 当试图打开指定文件失败时抛出
  • EOFException 在尝试读取流的末尾时抛出

其他流

  • PrintStream 打印格式化表示的对象的输出流
  • PrintWriter 格式化的文本输出流
  • RandomAccessFile 随机访问文件的类,支持读取和写入操作

字节流

// 文件输入流 (注意:需要手动关闭或使用 try-with-resources)InputStreaminputStream
= newFileInputStream("input.txt");
// 文件输出流 (注意:需要手动关闭或使用 try-with-resources)OutputStreamoutputStream
= newFileOutputStream("output.txt");
// 缓冲字节输入流InputStreambufferedInputStream
= newBufferedInputStream(inputStream);
// 缓冲字节输出流OutputStreambufferedOutputStream
= newBufferedOutputStream(outputStream);

字符流

// 文件字符输入流ReaderfileReader
= newFileReader("input.txt");
// 文件字符输出流WriterfileWriter
= newFileWriter("output.txt");
// 缓冲字符输入流ReaderbufferedFileReader
= newBufferedReader(
newFileReader("input.txt")
);
// 缓冲字符输出流WriterbufferedFileWriter
= newBufferedWriter(
newFileWriter("output.txt")
);

数据流

// 数据输入流DataInputStreamdataInputStream
= newDataInputStream(inputStream);
// 数据输出流DataOutputStreamdataOutputStream
= newDataOutputStream(outputStream);

对象流

// 对象输入流ObjectInputStreamobjectInputStream
= newObjectInputStream(inputStream);
// 对象输出流ObjectOutputStreamobjectOutputStream
= newObjectOutputStream(outputStream);

序列化与反序列化

序列化对象到文件

try (
ObjectOutputStreamobjectOutputStream
= newObjectOutputStream(newFileOutputStream("object.dat"))
) {
objectOutputStream.writeObject(object);
}

从文件反序列化对象

try (
ObjectInputStreamobjectInputStream
= newObjectInputStream(newFileInputStream("object.dat"))
) {
Objectobject = objectInputStream.readObject();
}

标准输入输出流

标准输入流

InputStreamstandardInputStream
= System.in;

标准输出流

PrintStreamstandardOutputStream
= System.out;

基本操作

// 读取字节数据intbyteData = inputStream.read();
// 写入字节数据outputStream.write(byteData);
// 读取字符数据intcharData = reader.read();
// 写入字符数据writer.write(charData);

关闭流

// 关闭输入流inputStream.close();
// 关闭输出流outputStream.close();

Java Stream 流

创建流

从集合创建流

List<String> list = Arrays.asList("a", "b", "c");
Stream<String> streamFromList = list.stream();

从数组创建流

String[] array = {"d", "e", "f"};
Stream<String> streamFromArray = Arrays.stream(array);

创建空流

Stream<String> emptyStream = Stream.empty();

创建无限流

Stream<Integer> infiniteStream = Stream.iterate(0, n -> n + 2);

中间操作

// 过滤Stream<String> filteredStream = list.stream().filter(
s -> s.startsWith("a")
);
// 映射Stream<Integer> mappedStream = list.stream().map(String::length);
// 排序Stream<String> sortedStream = list.stream().sorted();
// 去重Stream<String> distinctStream = list.stream().distinct();
// 截断Stream<String> limitedStream = list.stream().limit(2);
// 跳过Stream<String> skippedStream = list.stream().skip(1);

终端操作

// 聚合操作Optional<String> anyElement = list.stream().findAny();
Optional<String> firstElement = list.stream().findFirst();
longcount = list.stream().count();
Optional<String> maxElement = list.stream()
.max(Comparator.naturalOrder());
Optional<String> minElement = list.stream()
.min(Comparator.naturalOrder());
// 检查匹配booleananyMatch = list.stream().anyMatch(s -> s.contains("a"));
booleanallMatch = list.stream().allMatch(s -> s.length() == 1);
booleannoneMatch = list.stream().noneMatch(s -> s.contains("z"));
// 归约Optional<String> reducedString = list.stream()
.reduce((s1, s2) -> s1 + s2);
StringreducedStringWithIdentity = list.stream()
.reduce("Start:", (s1, s2) -> s1 + s2);
// 收集List<String> collectedList = list.stream()
.collect(Collectors.toList());
Set<String> collectedSet = list.stream()
.collect(Collectors.toSet());
Map<Integer, String> collectedMap = list.stream()
.collect(
Collectors.toMap(String::length, Function.identity())
);

并行流

List<String> list = Arrays.asList("a", "b", "c", "d", "e");
List<String> upperCaseList = list.parallelStream()
.map(String::toUpperCase)
.collect(Collectors.toList());

反射

这些是使用 Java 反射时常见的操作。使用反射需要注意性能和安全性问题,尽量避免在性能要求高的地方过度使用。

获取 Class 对象

// 通过类名获取Class对象Class<?> clazz1 = MyClass.class;
// 通过对象获取Class对象MyClassobj = newMyClass();
Class<?> clazz2 = obj.getClass();
// 通过完整类名字符串获取Class对象Class<?> clazz3 = Class.forName("com.example.MyClass");

获取类的信息

获取类的名称

StringclassName = clazz.getName();

获取类的修饰符

intmodifiers = clazz.getModifiers();

获取类的包信息

Packagepkg = clazz.getPackage();

获取类的父类

Class<?> superClass = clazz.getSuperclass();

获取类实现的接口

Class<?>[] interfaces = clazz.getInterfaces();

创建对象实例

// 使用默认构造函数创建对象(注意:newInstance() 已废弃)MyClassinstance = (MyClass) clazz.getDeclaredConstructor().newInstance();
// 使用带参数的构造函数创建对象Constructor<?> constructor = clazz.getConstructor(String.class, int.class);
MyClassinstanceWithArgs = (MyClass) constructor.newInstance("example", 123);

获取和设置字段值

// 获取字段值Fieldfield = clazz.getDeclaredField("fieldName");
field.setAccessible(true); // 如果字段是私有的,需要设置可访问Objectvalue = field.get(instance);
// 设置字段值field.set(instance, newValue);

处理泛型

// 获取泛型信息TypegenericType = field.getGenericType();

调用方法

// 获取方法Methodmethod = clazz.getDeclaredMethod("methodName", parameterTypes);
method.setAccessible(true); // 如果方法是私有的,需要设置可访问// 调用方法Objectresult = method.invoke(instance, args);

其他常用操作

// 判断是否是数组、枚举、注解等booleanisArray = clazz.isArray();
booleanisEnum = clazz.isEnum();
booleanisAnnotation = clazz.isAnnotation();
// 获取构造函数、字段、方法等Constructor<?>[] constructors = clazz.getConstructors();
Field[] fields = clazz.getDeclaredFields();
Method[] methods = clazz.getDeclaredMethods();

处理注解

// 获取注解信息Annotationannotation = field.getAnnotation(MyAnnotation.class);

方法引用

方法引用

Java 的 Consumer 接口里的 accept 方法接受参数但不返回值。要让它打印传入的参数,可以这样做:

Consumer<String> test = newConsumer<String>() {
@Overridepublicvoidaccept(Strings) {
System.out.println(s);
}
};
test.accept("test");

更简单的,我们可以直接传入Lambda表达式

Consumer<String> test = System.out::println;

方法引用通过方法的名字指向一个方法,使语言构造更简洁,减少冗余代码。

使用方式

  • 引用方法
  • 引用构造方法
  • 引用数组

静态方法引用

Comparator<Integer> comparator = Math::max;
intresult = comparator.compare(1, 2);
// 返回 -1 BinaryOperator<Integer> maxOperator = Math::max;
intresult = maxOperator.apply(1, 2);
// 返回 2

实例方法引用

Stringstr = "HELLO";
Supplier<String> lowerCaseSupplier = str::toLowerCase;
StringlowerCase = lowerCaseSupplier.get();
// 返回 "hello"

构造方法引用

Supplier<String> supplier = String::new;
Stringstr = supplier.get();
// 返回一个空字符串

数组构造方法引用

Function<Integer, String[]> function = String[]::new;
String[] array = function.apply(5);
// 返回长度为 5 的空字符串数组

对象中的方法引用

StringsomeStr = "HELLO";
Supplier<String> lowerCaseSupplier = someStr::toLowerCase;
StringlowerCase = lowerCaseSupplier.get();
// 返回 "hello"

对象中的静态方法引用

SomeClasssomeObject = newSomeClass();
Supplier<Integer> methodSupplier = someObject::staticMethod;
intresult = methodSupplier.get();
// 调用静态方法

杂项 Misc

访问修饰符

修饰符ClassPackageSubclassWorld
publicYYYY
protectedYYYN
no modifierYYNN
privateYNNN

常用表达

Stringtext = "I am learning Java";
// 删除所有空格text.replaceAll("\\s+", "");
// 拆分字符串text.split("\\|");
text.split(Pattern.quote("|"));

查看: Regex in java

注释 Comment

// 我是单行注释!/*而我是一个多行注释!*//** * 这个 * 是 * 文档 * 注释 */

关键字

  • abstract
  • continue
  • for
  • new
  • switch
  • assert
  • default
  • goto
  • package
  • synchronized
  • boolean
  • do
  • if
  • private
  • this
  • break
  • double
  • implements
  • protected
  • throw
  • byte
  • else
  • import
  • public
  • throws
  • case
  • enum
  • instanceof
  • return
  • transient
  • catch
  • extends
  • int
  • short
  • try
  • char
  • final
  • interface
  • static
  • void
  • class
  • finally
  • long
  • strictfp
  • volatile
  • const
  • float
  • native
  • super
  • while

数学方法

方法说明
Math.max(a,b)ab 的最大值
Math.min(a,b)ab 的最小值
Math.abs(a)a 的绝对值
Math.sqrt(a)a 的平方根
Math.pow(a,b)b 的幂
Math.round(a)最接近的整数
Math.sin(ang)正弦
Math.cos(ang)ang 的余弦
Math.tan(ang)ang 的切线
Math.asin(ang)ang 的反正弦
Math.log(a)a 的自然对数
Math.toDegrees(rad)弧度转角度
Math.toRadians(deg)角度转弧度

异常 Try/Catch/Finally

try {
// something
} catch (Exceptione) {
// 建议使用日志框架记录异常logger.error("发生异常", e);
// 或者至少使用标准错误流// e.printStackTrace();
} finally {
System.out.println("总是执行");
}

util工具类

  • ArrayDeque: 可调整大小的数组双端队列,实现了Deque接口
  • Arrays: 提供操作数组的静态方法,如排序、搜索、比较等
  • Collections: 包含操作集合或返回集合的静态方法
  • Date: 表示特定时间瞬间,精度为毫秒
  • Dictionary: 抽象父类,可用于键值对映射,例如Hashtable
  • EnumMap: 专门用于枚举键的Map实现
  • EnumSet: 专门用于枚举键的Set实现
  • Formatter: 提供对布局、对齐、数字、字符串和日期/时间数据的格式化支持,以及特定于语言环境的输出
  • SecureRandom: 生成安全的伪随机数流的实例
  • UUID: 表示不可变的通用唯一标识符
  • Vector: 实现了可增长的对象数组
  • LocalDate: 表示无时区的日期,仅包含年月日,不可变且线程安全,适用于Java 8及更高版本
  • LocalTime: 表示无时区的时间,仅包含时分秒,不可变且线程安全,适用于Java 8及更高版本
  • LocalDateTime: 表示无时区的日期时间,包含年月日时分秒,不可变且线程安全,适用于Java 8及更高版本

Collections 工具类

// 计算出现频率List<Integer> list = newArrayList<>();
list.add(1);
list.add(2);
list.add(2);
list.add(3);
list.add(3);
list.add(3);
intfrequency = Collections
.frequency(list, 2); // frequency = 2

操纵数据库

JDBC

Stringurl = "jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=UTC";
Stringuser = "root";
Stringpassword = "123456";
Stringsql = "SELECT 1 as a, '2' as b";
StringpreparedSql = "SELECT * FROM t_user WHERE id = ?";
Connectionconn = null;
Statementsm = null;
ResultSetrs = null;
try {
// 1.注册驱动Class.forName("com.mysql.cj.jdbc.Driver");
} catch (ClassNotFoundExceptione) {
// 驱动找不到thrownewRuntimeException(e);
}
// 2.建立连接try (Connectionconnection = DriverManager.getConnection(url, user, password)) {
conn = connection;
// 3.创建Statement对象try (Statementstatement = connection.createStatement()) {
sm = statement;
// 4.执行SQL语句try (ResultSetresultSet = statement.executeQuery(sql)) {
rs = resultSet;
// 5.处理结果集while (resultSet.next()) {
// 按照列名取值System.out.println(resultSet.getLong("a"));
// 按照索引取值System.out.println(resultSet.getString(2));
}
}
}
// 3.创建PreparedStatement对象try (PreparedStatementpreparedStatement = connection.prepareStatement(preparedSql)) {
sm = preparedStatement;
preparedStatement.setLong(1, 1_000L);
// 4.执行SQL语句try (ResultSetresultSet = preparedStatement.executeQuery()) {
rs = resultSet;
// 5.处理结果集while (resultSet.next()) {
System.out.println(resultSet.getLong("id"));
System.out.println(resultSet.getString(2));
}
}
}
} catch (SQLExceptione) {
// 数据库异常thrownewRuntimeException(e);
} finally {
// 6.关闭资源// 上面的try块里已经自动关闭,否则(JDK 7以前)按照以下顺序关闭// 先打开的后关闭,后打开的先关闭if (null != rs) {
try {
rs.close();
} catch (SQLExceptionignored) {
}
}
if (null != sm) {
try {
sm.close();
} catch (SQLExceptionignored) {
}
}
if (null != conn) {
try {
conn.close();
} catch (SQLExceptionignored) {
}
}
// 也可以直接工具类, 注意顺序IOUtils.close(rs);
IOUtils.close(sm);
IOUtils.close(conn);
}

JDBC注册驱动

Class.forName("com.mysql.cj.jdbc.Driver");
DriverManager.registerDriver(neworg.postgresql.Driver());
// 支持多个同时注册System.setProperty("jdbc.drivers", "com.mysql.cj.jdbc.Driver:org.postgresql.Driver");

另见