Java Programming Notes

Posted by saltyfishyjk on 2023-01-02
Words 1k and Reading Time 5 Minutes
Viewed Times

Java Programming Notes

Part 0 前言

笔者的Java水平和需求的Java水平有显著差距菜狗是这样的,这里整理一些常用的知识。

Part 1 容器

PriorityQueue优先队列

官方文档:PriorityQueue

自定义类和排序方法

  • 设计自定义类,继承Comparable接口并重写compareTo方法,形如下例
1
2
3
4
5
6
7
8
9
10
11
12
13
class SellOrder implements Comparable<SellOrder> {
int price;
int amount;

public SellOrder(int price, int amount) {
this.price = price;
this.amount = amount;
}

public int compareTo(SellOrder o) {
return this.price - o.price;
}
}
  • 以该类为容器元素类型,形如下例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
class Solution {
public int getNumberOfBacklogOrders(int[][] orders) {
int MOD = 1000000007;
PriorityQueue<SellOrder> sellOrders = new PriorityQueue<>();
PriorityQueue<BuyOrder> buyOrders = new PriorityQueue<>();

int len = orders.length;
for (int i = 0; i < len; i++) {
int priceNow = orders[i][0];
int amountNow = orders[i][1];
int orderType = orders[i][2];
if (orderType == 0) {
// 采购订单buy
while (amountNow > 0) {
if (sellOrders.isEmpty()) {
break;
}
SellOrder sellOrder = sellOrders.poll();
if (sellOrder.price <= priceNow) {
if (sellOrder.amount > amountNow) {
sellOrder.amount = sellOrder.amount - amountNow;
amountNow -= amountNow;
sellOrders.add(sellOrder);
break;
} else if (sellOrder.amount < amountNow) {
/* 说明当前订单还有没匹配完的部分,继续匹配 */
amountNow -= sellOrder.amount;
} else {
/* 正好匹配消除 */
amountNow -= amountNow;
break;
}
} else {
/* 说明不匹配,把sell订单添加回去并退出循环 */
sellOrders.add(sellOrder);
break;
}
}
if (amountNow > 0) {
BuyOrder buyOrder = new BuyOrder(priceNow, amountNow);
buyOrders.add(buyOrder);
}
}
}
int ans = 0;
while (!sellOrders.isEmpty()) {
SellOrder sellOrder = sellOrders.poll();
ans = (ans + sellOrder.amount) % MOD;
}
while (!buyOrders.isEmpty()) {
BuyOrder buyOrder = buyOrders.poll();
ans = (ans + buyOrder.amount) % MOD;
}
return ans;
}
}

对于上例中PriorityQueue,其内部元素是SellOrder对象,因此自动奥找SellOrder重载的compareTo方法进行排序。

Integer的大根堆

Java的容器PriorityQueue缺省是小根堆,因此想要构造大根堆需要额外完成比较器并传入构造器,举例如下:

1
2
3
4
5
6
PriorityQueue<Integer> heap = new PriorityQueue<>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
});

ArrayList数组列表

ArrayList 是动态数组。

声明 ArrayList 对象

1
2
3
4
5
6
class Solution {
public void func() {
// 声明一个元素类型为 Integer 的 ArrayList 对象
ArrayList<Integer> arrayList = new ArrayList<>();
}
}

声明二维 ArrayList 对象

1
2
3
4
5
6
7
8
9
class Soltution {
public void func() {
// 声明一个元素为 ArrayList<Integer> 对象的 ArrayList 对象
ArrayList<ArrayList<Integer>> arrayList = new ArrayList<>();
// 将一个 ArrayList<Integer> 对象插入二维 ArrayList 对象中
ArrayList<Integer> element = new ArrayList<>();
arrayList.add(element);
}
}

边遍历边删除

参考文章:ConcurrentModificationException异常

当遇到该需求时,需要使用迭代器进行遍历,同时使用迭代器提供的方法进行删除,才可以避免错误。在多线程时,还需要考虑额外的问题。举例如下(单线程):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
class Worker implements Comparable<Worker> {
int leftToRight;
int pickOld;
int rightToLeft;
int putNew;
int id;
int endTime = 0;

public Worker(int leftToRight,
int pickOld,
int rightToLeft,
int putNew,
int id) {
this.leftToRight = leftToRight;
this.pickOld = pickOld;
this.rightToLeft = rightToLeft;
this.putNew = putNew;
this.id = id;
}

public Worker(int leftToRight,
int pickOld,
int rightToLeft,
int putNew,
int id,
int endTime) {
this(leftToRight, pickOld, rightToLeft, putNew, id);
this.endTime = endTime;
}
}

ArrayList<Worker> workL = new ArrayList<>();
Iterator<Worker> iterator = workL.iterator();
while (iterator.hasNext()) {
Worker now = iterator.next();
if (now.endTime <= cur) {
// workL.remove(now);
iterator.remove();
waitL.add(now);
move = true;
}
}

Part 2 数组

声明数组对象

1
2
3
4
5
6
7
8
9
class Solution {
public void func() {
// 声明大小为 100 的数组
int[] arr1 = new int[100];
// 声明大小为 N 的数组
int N;
int[] arr2 = new int[N];
}
}

声明二维数组对象

1
2
3
4
5
6
7
8
class Solution {
public void func() {
// 声明第 1 维大小为 100 的二维数组
int[][] arr = new int[100][];
// 插入时需要再每次声明一维数组
arr[0] = new int[10];
}
}

一维数组排序

1
2
3
4
5
6
7
8
9
class Solution {
public void func() {
int[] nums = {3, 5, 1, 2, 4};
// 使用Arrays.sort进行排序(默认升序)
Arrays.sort(nums);
// 使用 Lambda 表达式降序排序
Arrays.sort(nums, (a, b)->Integer.compare(b, a));
}
}

二维数组排序

1
2
3
4
5
6
7
class Solution {
public void func() {
int[][] arr;
// 二维数组的元素是一维数组,两个一维数组比较时以其第0个元素升序排序
Arrays.sort(arr, (a, b)->a[0]-b[0]);
}
}

Part 3 其他

公约数

辗转相除法的while循环实现

1
2
3
4
5
6
7
8
9
public static int gcd(int a, int b) {
int tmp;
while (b != 0) {
c = a % b;
a = b;
b = c;
}
return a;
}

This is copyright.