用Jdk17的风格书写代码
我想通过Java不同版本的编程特性去解决一下开发中会遇到的问题,帮我们快速理解和学习新特性,后续我会不断的收集和补充这些问题,目前比较可惜的是我还没有对不同的jdk版本的单元测试代码进行banchmark……
Q1:在给定的字符串中取出出现次数Top3的字母,但是可能会出现并列情况,所以我们的结果应该是[k=[char1,chat2,……],……]
- A:jdk8之前
1 |
|
- A:jdk8之后,jdk16之前
1 |
|
- A:jdk16之后,更适用于可读性更好的业务代码
1 |
|
Q2:猜数字游戏:一位玩家想一个单词,另一位通过单词长度尝试猜该玩家所想的单词,如果同位置上的字母相同,则在猜测的单词上该字母大写返回,如果同位置上没有,但是其它位置有则不变(只匹配一次),如果同位置不匹配且它位置未出现则用.替换.
1 |
|
- 封装重构之后,看似变长了,但是可读性更高了
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
57
58
59
60
61
62
63
64
65
66
67
68public record Wordless(String hiddenAsStr) {
public String guess(String guessAsStr) {
Guess guess = new Guess(guessAsStr);
Hidden hidden = new Hidden(hiddenAsStr);
return IntStream.range(0, guess.length()).mapToObj(i -> {
if (guess.hasALetterAtPosition(i).thatIsWellPlacedIn(hidden)) {
return Character.toString(guess.codePointAt(i)).toUpperCase();
} else if (guess.hasALetterAtPosition(i).thatIsNotWellPlacedIn(hidden)) {
return Character.toString(guess.codePointAt(i));
} else {
return ".";
}
}).collect(Collectors.joining());
}
}
record Hidden(String hidden, boolean[] used) {
public Hidden(String hidden) {
this(hidden, new boolean[hidden.length()]);
}
public int codePointAt(int i) {
return this.hidden.codePointAt(i);
}
public int length() {
return this.hidden.length();
}
public boolean match(GuessWithIndex guessWithIndex, int guessIndex, int hiddenIndex) {
if (used[hiddenIndex]) {
return false;
}
boolean match = guessWithIndex.guess().codePointAt(guessIndex) == hidden.codePointAt(hiddenIndex);
if (match) {
used[hiddenIndex] = true;
}
return match;
}
}
record Guess(String guess) {
public int length() {
return this.guess.length();
}
public GuessWithIndex hasALetterAtPosition(int i) {
return new GuessWithIndex(this, i);
}
public int codePointAt(int i) {
return this.guess.codePointAt(i);
}
}
record GuessWithIndex(Guess guess, int index) {
public boolean thatIsWellPlacedIn(Hidden hidden) {
return hidden.match(this, index, index);
}
public boolean thatIsNotWellPlacedIn(Hidden hidden) {
return IntStream.range(0, hidden.length())
.filter(i -> index != i)
.filter(i -> guess.codePointAt(i) != hidden.codePointAt(i))
.anyMatch(i -> hidden.match(this, index, i));
}
}1
2
3
4
5
6
7
8@Test
public void testGuess() {
Wordless wordless = new Wordless("aaaab");
Assertions.assertEquals(wordless.guess("ccccc"), ".....");
Assertions.assertEquals(wordless.guess("ccacc"), "..A..");
Assertions.assertEquals(wordless.guess("ccacb"), "..A.B");
Assertions.assertEquals(wordless.guess("bbacc"), "b.A..");
} - 继续重构,引入密闭类和switch case表达式
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89public record Wordless(String hiddenAsStr) {
public String guess(String guessAsStr) {
Guess guess = new Guess(guessAsStr);
Hidden hidden = new Hidden(hiddenAsStr);
return IntStream.range(0, guess.length()).mapToObj(index -> switch (guess.checkCharterAtPosition(index).with(hidden)) {
case WELL_PLACED letter -> Character.toString(letter.codePoint()).toUpperCase();
case NOT_WELL_PLACED letter -> Character.toString(letter.codePoint());
case ABSEND letter -> ".";
}).collect(Collectors.joining());
}
}
record Hidden(String hidden, boolean[] used) {
public Hidden(String hidden) {
this(hidden, new boolean[hidden.length()]);
}
public int codePointAt(int i) {
return this.hidden.codePointAt(i);
}
public int length() {
return this.hidden.length();
}
public boolean match(GuessWithIndex guessWithIndex, int guessIndex, int hiddenIndex) {
if (used[hiddenIndex]) {
return false;
}
boolean match = guessWithIndex.guess().codePointAt(guessIndex) == hidden.codePointAt(hiddenIndex);
if (match) {
used[hiddenIndex] = match;
}
return match;
}
}
record Guess(String guess) {
public int length() {
return this.guess.length();
}
public GuessWithIndex hasALetterAtPosition(int i) {
return new GuessWithIndex(this, i);
}
public int codePointAt(int i) {
return this.guess.codePointAt(i);
}
public GuessWithIndex checkCharterAtPosition(int index) {
return new GuessWithIndex(this,index);
}
}
record GuessWithIndex(Guess guess, int index) {
public boolean thatIsWellPlacedIn(Hidden hidden) {
return hidden.match(this, index, index);
}
public boolean thatIsNotWellPlacedIn(Hidden hidden) {
return IntStream.range(0, hidden.length()).filter(i -> index != i)
.filter(i -> guess.codePointAt(i) != hidden.codePointAt(i))
.anyMatch(i -> hidden.match(this, index, i));
}
public Letter with(Hidden hidden) {
if (thatIsWellPlacedIn(hidden)) {
return new WELL_PLACED(this.guess.codePointAt(this.index));
} else if (thatIsNotWellPlacedIn(hidden)) {
return new NOT_WELL_PLACED(this.guess.codePointAt(this.index));
} else {
return new ABSEND();
}
}
}
sealed interface Letter permits WELL_PLACED, NOT_WELL_PLACED, ABSEND {
}
record WELL_PLACED(int codePoint) implements Letter {
}
record NOT_WELL_PLACED(int codePoint) implements Letter {
}
record ABSEND() implements Letter {
}1
2
3
4
5
6
7
8@Test
public void testGuess() {
Wordless wordless = new Wordless("aaaab");
Assertions.assertEquals(wordless.guess("ccccc"), ".....");
Assertions.assertEquals(wordless.guess("ccacc"), "..A..");
Assertions.assertEquals(wordless.guess("ccacb"), "..A.B");
Assertions.assertEquals(wordless.guess("bbacc"), "b.A..");
}
用Jdk17的风格书写代码
https://vegetablest.github.io/2023/08/12/用jdk17的风格书写代码/