Default Changelist
AioServer.java FactoryAndStrategy.java LeetCode25.java LeetCode49.java LeetCode61.java LeetCode71.java LeetCode73.java LeetCode114.java LeetCode141.java LeetCode228.java LeetCode289.java LeetCode290.java LeetCode703.java SingletonPattern.java ThreadDemo1.java AndStrategy类,使用策略模式优化支付方式。 这些更改包括对单例模式的实现、线程控制的改进、LeetCode问题的解决以及设计模式的应用。
This commit is contained in:
parent
33dffb6b07
commit
6d49b27147
@ -0,0 +1,58 @@
|
|||||||
|
package cn.whaifree.designPattern.Factory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 1.0
|
||||||
|
* @Author whai文海
|
||||||
|
* @Date 2024/9/22 21:14
|
||||||
|
* @注释
|
||||||
|
*/
|
||||||
|
public class FactoryAndStrategy {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Factory factory = new Factory();
|
||||||
|
Pay pay = factory.getPay(PayType.WX);
|
||||||
|
pay.pay(100);
|
||||||
|
Pay pay2 = factory.getPay(PayType.WX);
|
||||||
|
pay2.pay(200);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Pay{
|
||||||
|
void pay(int price);
|
||||||
|
}
|
||||||
|
|
||||||
|
static class WxPay implements Pay {
|
||||||
|
@Override
|
||||||
|
public void pay(int price) {
|
||||||
|
System.out.println("微信支付:" + price);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static class AliPay implements Pay {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void pay(int price) {
|
||||||
|
System.out.println("支付宝支付:" + price);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static class Factory{
|
||||||
|
public Pay getPay(PayType payType){
|
||||||
|
return payType.pay;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum PayType {
|
||||||
|
WX(new WxPay()),
|
||||||
|
ALI(new AliPay()), // 单例
|
||||||
|
;
|
||||||
|
|
||||||
|
private Pay pay;
|
||||||
|
|
||||||
|
PayType(Pay pay) {
|
||||||
|
this.pay = pay;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -3,12 +3,41 @@ package cn.whaifree.designPattern;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Scanner;
|
import java.util.Scanner;
|
||||||
import java.util.function.BiConsumer;
|
|
||||||
|
|
||||||
public class SingletonPattern {
|
public class SingletonPattern {
|
||||||
|
|
||||||
|
static class LazySingleton {
|
||||||
|
private static LazySingleton instance;
|
||||||
|
|
||||||
|
private LazySingleton() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static LazySingleton getInstance() {
|
||||||
|
if (instance == null) {
|
||||||
|
instance = new LazySingleton();
|
||||||
|
}
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class HungrySingleton {
|
||||||
|
private static final HungrySingleton instance = new HungrySingleton();
|
||||||
|
|
||||||
|
private HungrySingleton() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HungrySingleton getInstance() {
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Main{
|
class Main{
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
87
src/main/java/cn/whaifree/leetCode/Array/LeetCode228.java
Normal file
87
src/main/java/cn/whaifree/leetCode/Array/LeetCode228.java
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
package cn.whaifree.leetCode.Array;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.channels.AsynchronousFileChannel;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.nio.file.StandardOpenOption;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 1.0
|
||||||
|
* @Author whai文海
|
||||||
|
* @Date 2024/9/22 14:56
|
||||||
|
* @注释
|
||||||
|
*/
|
||||||
|
public class LeetCode228 {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws IOException {
|
||||||
|
AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open(Paths.get("D:\\project\\LeetCode\\README.md"), StandardOpenOption.READ);
|
||||||
|
ByteBuffer buffer = ByteBuffer.allocate(1024);
|
||||||
|
Future<Integer> result = fileChannel.read(buffer, 0);
|
||||||
|
while (!result.isDone()) {
|
||||||
|
// do something
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
int[] nums = {0, 2};
|
||||||
|
System.out.println(new Solution().summaryRanges(nums));
|
||||||
|
}
|
||||||
|
|
||||||
|
class Solution {
|
||||||
|
|
||||||
|
// public List<String> summaryRanges(int[] nums) {
|
||||||
|
// List<String> path = new ArrayList<>();
|
||||||
|
// List<String> res = new ArrayList<>();
|
||||||
|
// for (int i = 1; i < nums.length; i++) {
|
||||||
|
// if (nums[i] != nums[i - 1]) {
|
||||||
|
// StringBuilder str = new StringBuilder();
|
||||||
|
// for (int j = 0; j < path.size()-1; j++) {
|
||||||
|
// str.append(path.get(j));
|
||||||
|
// str.append("->");
|
||||||
|
// }
|
||||||
|
// str.append(path.get(path.size() - 1));
|
||||||
|
// path.clear();
|
||||||
|
// }
|
||||||
|
// path.add(String.valueOf(nums[i]));
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
public List<String> summaryRanges(int[] nums) {
|
||||||
|
|
||||||
|
|
||||||
|
List<String> res = new ArrayList<>();
|
||||||
|
|
||||||
|
int left = 0;
|
||||||
|
int right = 1;
|
||||||
|
while (right < nums.length) {
|
||||||
|
if (nums[right] != nums[right - 1] + 1) {
|
||||||
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
|
stringBuilder.append(nums[left]);
|
||||||
|
if (left != right - 1) {
|
||||||
|
stringBuilder.append("->");
|
||||||
|
stringBuilder.append(nums[right - 1]);
|
||||||
|
}
|
||||||
|
res.add(stringBuilder.toString());
|
||||||
|
left = right;
|
||||||
|
}
|
||||||
|
right++;
|
||||||
|
}
|
||||||
|
if (left < nums.length) {
|
||||||
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
|
stringBuilder.append(nums[left]);
|
||||||
|
if (left != right - 1) {
|
||||||
|
stringBuilder.append("->");
|
||||||
|
stringBuilder.append(nums[right - 1]);
|
||||||
|
}
|
||||||
|
res.add(stringBuilder.toString());
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
102
src/main/java/cn/whaifree/leetCode/Array/LeetCode289.java
Normal file
102
src/main/java/cn/whaifree/leetCode/Array/LeetCode289.java
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
package cn.whaifree.leetCode.Array;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 1.0
|
||||||
|
* @Author whai文海
|
||||||
|
* @Date 2024/9/23 11:08
|
||||||
|
* @注释
|
||||||
|
*/
|
||||||
|
public class LeetCode289 {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
int[][] board = new int[][]{{0, 1, 0}, {0, 0, 1}, {1, 1, 1}, {0, 0, 0}};
|
||||||
|
new Solution().gameOfLife(board);
|
||||||
|
for (int[] ints : board) {
|
||||||
|
System.out.println(Arrays.toString(ints));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Solution {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 为了保证当前修改后的状态不会影响下一个状态的判定,设置另外的状态
|
||||||
|
* 如题所示,只有三种:
|
||||||
|
* 1. 如果当前是活细胞,但是变成了死细胞,那么设置为-1
|
||||||
|
* 2. 如果当前是活细胞,仍然是活细胞,那么不变仍为1
|
||||||
|
* 3. 如果当前是死细胞,但是变成了活细胞,那么设置为2
|
||||||
|
* 那么最后遍历修改完状态之后,将-1修改回为0,2修改回为1
|
||||||
|
* @param board
|
||||||
|
*/
|
||||||
|
public void gameOfLife(int[][] board) {
|
||||||
|
//设置方向来遍历某个节点周围的另外几个节点
|
||||||
|
int[] ner = new int[]{-1,0,1};
|
||||||
|
//获取行和列
|
||||||
|
int rows = board.length;
|
||||||
|
int cols = board[0].length;
|
||||||
|
//遍历每一个节点格子
|
||||||
|
for (int row = 0; row < rows; row++) {
|
||||||
|
for (int col = 0; col < cols; col++) {
|
||||||
|
//设置当前节点周围的存活细胞的数量
|
||||||
|
int liveNer = 0;
|
||||||
|
/**
|
||||||
|
* 当前节点是[ i , j ]
|
||||||
|
* [i-1,j-1] [i-1,j] [i-1,j+1]
|
||||||
|
* [ i ,j-1] [ i ,j] [ i ,j+1]
|
||||||
|
* [i+1,j-1] [i+1,j] [i+1,j+1]
|
||||||
|
* 那么以当前节点为中心,要求周围的节点,则最多是3*3形式
|
||||||
|
* 并且所有的行和列都是用当前节点+1或者-1或者不变构成
|
||||||
|
* 所以我们设置 ner = {-1,0,1} 来形成遍历
|
||||||
|
*/
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
for (int j = 0; j < 3; j++) {
|
||||||
|
//必须保证不计算当前节点(不计算自己)
|
||||||
|
if (!(ner[i]==0 && ner[j]==0)){
|
||||||
|
//当前节点的相邻节点坐标
|
||||||
|
int r = row+ner[i];
|
||||||
|
int c = col+ner[j];
|
||||||
|
/**判断当前周围节点的存活状态,要求满足两个状态
|
||||||
|
* 1. 必须保证要在 board 矩阵中
|
||||||
|
* 2. 并且**起始状态要是存活,则当前状态为1或者-1都可以(因为这两个状态都表示起始状态为活细胞)**
|
||||||
|
**/
|
||||||
|
if ((r >= 0 && r < rows) && (c >= 0 && c < cols) && (Math.abs(board[r][c]) == 1)) {
|
||||||
|
// -1和1 初始状态都是活细胞
|
||||||
|
liveNer++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**开始判断当前节点的存活状态
|
||||||
|
* 因为遍历到当前节点的时候,还没有开始修改细胞状态,所以还是0和1的细胞状态
|
||||||
|
* 那么只需要判断状态变化的即可,否则状态不变
|
||||||
|
**/
|
||||||
|
if ((board[row][col]==1) && ( liveNer>3 || liveNer<2)){
|
||||||
|
// -1 代表这个细胞过去是活的现在死了
|
||||||
|
board[row][col]=-1;
|
||||||
|
}
|
||||||
|
if (board[row][col]==0 && ( liveNer==3)){
|
||||||
|
// 2 代表这个细胞过去是死的现在活了
|
||||||
|
board[row][col]=2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//再把额外的状态修改回去
|
||||||
|
for (int row = 0; row < rows; row++) {
|
||||||
|
for (int col = 0; col < cols; col++) {
|
||||||
|
if (board[row][col] == 2) {
|
||||||
|
board[row][col] = 1;
|
||||||
|
}
|
||||||
|
if (board[row][col] == -1){
|
||||||
|
board[row][col] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
51
src/main/java/cn/whaifree/leetCode/Array/LeetCode703.java
Normal file
51
src/main/java/cn/whaifree/leetCode/Array/LeetCode703.java
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
package cn.whaifree.leetCode.Array;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.PriorityQueue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 1.0
|
||||||
|
* @Author whai文海
|
||||||
|
* @Date 2024/9/22 15:14
|
||||||
|
* @注释
|
||||||
|
*/
|
||||||
|
public class LeetCode703 {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
KthLargest kthLargest = new KthLargest(3, new int[]{});
|
||||||
|
System.out.println(kthLargest.add(3));
|
||||||
|
System.out.println(kthLargest.add(5));
|
||||||
|
System.out.println(kthLargest.add(10));
|
||||||
|
System.out.println(kthLargest.add(9));
|
||||||
|
System.out.println(kthLargest.add(4));
|
||||||
|
}
|
||||||
|
|
||||||
|
class KthLargest {
|
||||||
|
|
||||||
|
PriorityQueue<Integer> priorityQueue = null;
|
||||||
|
int size = 0;
|
||||||
|
|
||||||
|
// 小顶堆 第k
|
||||||
|
public KthLargest(int k, int[] nums) {
|
||||||
|
priorityQueue = new PriorityQueue<>();
|
||||||
|
this.size = k;
|
||||||
|
for (int num : nums) {
|
||||||
|
priorityQueue.offer(num);
|
||||||
|
if (priorityQueue.size() > k) {
|
||||||
|
priorityQueue.poll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int add(int val) {
|
||||||
|
priorityQueue.offer(val);
|
||||||
|
if (priorityQueue.size() > size) {
|
||||||
|
priorityQueue.poll();
|
||||||
|
}
|
||||||
|
return priorityQueue.peek();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
52
src/main/java/cn/whaifree/leetCode/Array/LeetCode73.java
Normal file
52
src/main/java/cn/whaifree/leetCode/Array/LeetCode73.java
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
package cn.whaifree.leetCode.Array;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 1.0
|
||||||
|
* @Author whai文海
|
||||||
|
* @Date 2024/9/23 9:18
|
||||||
|
* @注释
|
||||||
|
*/
|
||||||
|
public class LeetCode73 {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
int[][] matrix = new int[][]{{1, 1, 1}, {1, 0, 1}, {1, 1, 1}};
|
||||||
|
new Solution().setZeroes(matrix);
|
||||||
|
for (int[] ints : matrix) {
|
||||||
|
System.out.println(Arrays.toString(ints));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class Solution {
|
||||||
|
public void setZeroes(int[][] matrix) {
|
||||||
|
|
||||||
|
int yLen = matrix.length;
|
||||||
|
boolean[] row = new boolean[yLen];
|
||||||
|
int xLen = matrix[0].length;
|
||||||
|
boolean[] col = new boolean[xLen];
|
||||||
|
|
||||||
|
|
||||||
|
for (int y = 0; y < yLen; y++) {
|
||||||
|
for (int x = 0; x < xLen; x++) {
|
||||||
|
if (matrix[y][x] == 0) {
|
||||||
|
row[y] = true;
|
||||||
|
col[x] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int y = 0; y < yLen; y++) {
|
||||||
|
for (int x = 0; x < xLen; x++) {
|
||||||
|
if (row[y] || col[x]) {
|
||||||
|
matrix[y][x] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
49
src/main/java/cn/whaifree/leetCode/Hash/LeetCode290.java
Normal file
49
src/main/java/cn/whaifree/leetCode/Hash/LeetCode290.java
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
package cn.whaifree.leetCode.Hash;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 1.0
|
||||||
|
* @Author whai文海
|
||||||
|
* @Date 2024/9/22 13:09
|
||||||
|
* @注释
|
||||||
|
*/
|
||||||
|
public class LeetCode290 {
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
String pattern = "abbc";
|
||||||
|
String s = "dog cat cat dog";
|
||||||
|
System.out.println(new Solution().wordPattern(pattern, s));
|
||||||
|
}
|
||||||
|
|
||||||
|
class Solution {
|
||||||
|
public boolean wordPattern(String pattern, String s) {
|
||||||
|
Map<Character, String> map = new HashMap<>();
|
||||||
|
Map<String, Character> map2 = new HashMap<>();
|
||||||
|
s = s.trim();
|
||||||
|
String[] split = s.split(" ");
|
||||||
|
if (pattern.length() != split.length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int len = pattern.length();
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
char key1 = pattern.charAt(i);
|
||||||
|
String key2 = split[i];
|
||||||
|
if (!map.containsKey(key1)) {
|
||||||
|
map.put(key1, key2);
|
||||||
|
}
|
||||||
|
if (!map2.containsKey(key2)) {
|
||||||
|
map2.put(key2, key1);
|
||||||
|
}
|
||||||
|
if (!map.get(key1).equals(key2) || map2.get(key2) != key1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
128
src/main/java/cn/whaifree/leetCode/Hash/LeetCode49.java
Normal file
128
src/main/java/cn/whaifree/leetCode/Hash/LeetCode49.java
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
package cn.whaifree.leetCode.Hash;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 1.0
|
||||||
|
* @Author whai文海
|
||||||
|
* @Date 2024/9/22 13:22
|
||||||
|
* @注释
|
||||||
|
*/
|
||||||
|
public class LeetCode49 {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
String[] strs = {"eat", "tea", "tan", "ate", "nat", "bat"};
|
||||||
|
System.out.println(new Solution().groupAnagrams(strs));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class Solution {
|
||||||
|
public List<List<String>> groupAnagrams(String[] strs) {
|
||||||
|
Map<String, List<String>> map = new HashMap<>();
|
||||||
|
for (String str : strs) {
|
||||||
|
char[] charArray = str.toCharArray(); // 排序后 key 一样
|
||||||
|
Arrays.sort(charArray);
|
||||||
|
String key = new String(charArray);
|
||||||
|
if (!map.containsKey(key)) {
|
||||||
|
map.put(key, new ArrayList<>());
|
||||||
|
}
|
||||||
|
map.get(key).add(str);
|
||||||
|
}
|
||||||
|
return new ArrayList<>(map.values());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class Solution1 {
|
||||||
|
/**
|
||||||
|
* 统计每个字母出现的个数,并按照a2b1c4这种格式变成String,作为key
|
||||||
|
*
|
||||||
|
* 统计次数ON*M
|
||||||
|
* @param strs
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public List<List<String>> groupAnagrams(String[] strs) {
|
||||||
|
|
||||||
|
List<List<String>> res = new ArrayList<>();
|
||||||
|
Map<String, List<String>> map = new HashMap<>();
|
||||||
|
for (String str : strs) {
|
||||||
|
int[] count = new int[26];
|
||||||
|
for (int i = 0; i < str.length(); i++) {
|
||||||
|
int index = str.charAt(i) - 'a';
|
||||||
|
count[index]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
|
for (int i = 0; i < count.length; i++) {
|
||||||
|
if (count[i] != 0) {
|
||||||
|
// a12b19这种形式
|
||||||
|
stringBuilder.append((char) ('a' + i));
|
||||||
|
stringBuilder.append(count[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String key = stringBuilder.toString();
|
||||||
|
if (!map.containsKey(key)) {
|
||||||
|
map.put(key, new ArrayList<>());
|
||||||
|
}
|
||||||
|
map.get(key).add(str);
|
||||||
|
}
|
||||||
|
return new ArrayList<>(map.values());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// class Solution {
|
||||||
|
//
|
||||||
|
// static List<Integer> anagrams = null;
|
||||||
|
// static List<List<String>> res = null;
|
||||||
|
// public List<List<String>> groupAnagrams(String[] strs) {
|
||||||
|
// int[][] nums = new int[strs.length][26];
|
||||||
|
// for (int i = 0; i < strs.length; i++) {
|
||||||
|
// String str = strs[i];
|
||||||
|
// for (int j = 0; j < str.length(); j++) {
|
||||||
|
// nums[i][str.charAt(j) - 'a']++;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// anagrams = new ArrayList<>();
|
||||||
|
// res = new ArrayList<>();
|
||||||
|
// backTracking(strs, nums, 0);
|
||||||
|
// return res;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public static void backTracking(String[] strs, int[][] map, int start) {
|
||||||
|
// if (start >= map.length - 1) {
|
||||||
|
// List<String> anagram = new ArrayList<>();
|
||||||
|
// for (Integer a : anagrams) {
|
||||||
|
// anagram.add(strs[a]);
|
||||||
|
// }
|
||||||
|
// res.add(new ArrayList<>(anagram));
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if (!anagrams.isEmpty() && !match(map, anagrams.get(anagrams.size() - 1), start)) {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// for (int i = start; i < map.length; i++) {
|
||||||
|
// anagrams.add(i);
|
||||||
|
// backTracking(strs, map, i + 1);
|
||||||
|
// anagrams.remove(anagrams.size() - 1);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public static boolean match(int[][] map, int a, int b) {
|
||||||
|
// int[] A = map[a];
|
||||||
|
// int[] B = map[b];
|
||||||
|
// for (int i = 0; i < 26; i++) {
|
||||||
|
// if (A[i] != B[i]) return false;
|
||||||
|
// }
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
package cn.whaifree.leetCode.LinkedList;
|
||||||
|
|
||||||
|
import cn.whaifree.leetCode.model.ListNode;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 1.0
|
||||||
|
* @Author whai文海
|
||||||
|
* @Date 2024/9/23 12:54
|
||||||
|
* @注释
|
||||||
|
*/
|
||||||
|
public class LeetCode141 {
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
ListNode listNode = ListNode.listNodeFromArray(new int[]{1});
|
||||||
|
// listNode.next.next.next = listNode;
|
||||||
|
System.out.println(new Solution().hasCycle(listNode));
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Solution {
|
||||||
|
public boolean hasCycle(ListNode head) {
|
||||||
|
if (head == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (head.next == null) {
|
||||||
|
return false; // 只有一个节点
|
||||||
|
}
|
||||||
|
ListNode slow = head;
|
||||||
|
ListNode fast = head.next;
|
||||||
|
while (slow != fast) {
|
||||||
|
if (fast == null || fast.next == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
slow = slow.next;
|
||||||
|
fast = fast.next.next;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,62 @@
|
|||||||
|
package cn.whaifree.leetCode.LinkedList;
|
||||||
|
|
||||||
|
import cn.whaifree.leetCode.model.ListNode;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 1.0
|
||||||
|
* @Author whai文海
|
||||||
|
* @Date 2024/9/23 13:43
|
||||||
|
* @注释
|
||||||
|
*/
|
||||||
|
public class LeetCode25 {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
ListNode head = ListNode.listNodeFromArray(new int[]{1, 2, 3, 6, 7, 8, 9, 20});
|
||||||
|
// new Solution().reverse(null, head, 3).printList();
|
||||||
|
new Solution().reverseKGroup(head, 2).printList();
|
||||||
|
}
|
||||||
|
|
||||||
|
class Solution {
|
||||||
|
public ListNode reverseKGroup(ListNode head, int k) {
|
||||||
|
ListNode pre = new ListNode(-1, head);
|
||||||
|
return reverseRange(pre.next, k);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pre往后k个元素翻转
|
||||||
|
* @param pre
|
||||||
|
* @param k
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public ListNode reverseRange(ListNode pre, int k) {
|
||||||
|
ListNode index = pre;
|
||||||
|
ListNode nextNode = pre;
|
||||||
|
int i = 0;
|
||||||
|
while (i < k && nextNode != null) {
|
||||||
|
nextNode = nextNode.next;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if (i < k) {
|
||||||
|
return pre;
|
||||||
|
}
|
||||||
|
ListNode reverseAfterHead = reverse(null, index, k);
|
||||||
|
index.next = reverseRange(nextNode, k);
|
||||||
|
return reverseAfterHead;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ListNode reverse(ListNode pre, ListNode after,int k) {
|
||||||
|
if (k <= 0) {
|
||||||
|
return pre;
|
||||||
|
}
|
||||||
|
if (after == null) {
|
||||||
|
return pre;
|
||||||
|
}
|
||||||
|
ListNode next = after.next;
|
||||||
|
after.next = pre;
|
||||||
|
return reverse(after, next, k - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
107
src/main/java/cn/whaifree/leetCode/LinkedList/LeetCode61.java
Normal file
107
src/main/java/cn/whaifree/leetCode/LinkedList/LeetCode61.java
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
package cn.whaifree.leetCode.LinkedList;
|
||||||
|
|
||||||
|
import cn.whaifree.leetCode.model.ListNode;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 1.0
|
||||||
|
* @Author whai文海
|
||||||
|
* @Date 2024/9/23 14:25
|
||||||
|
* @注释
|
||||||
|
*/
|
||||||
|
public class LeetCode61 {
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
ListNode head = ListNode.listNodeFromArray(new int[]{1,2,3});
|
||||||
|
new Solution().rotateRight(head, 3).printList();
|
||||||
|
}
|
||||||
|
class Solution {
|
||||||
|
public ListNode rotateRight(ListNode head, int k) {
|
||||||
|
if (head == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
int len = 0;
|
||||||
|
ListNode tmpHead = head;
|
||||||
|
while (tmpHead!= null) {
|
||||||
|
len++;
|
||||||
|
tmpHead = tmpHead.next;
|
||||||
|
}
|
||||||
|
|
||||||
|
k %= len;
|
||||||
|
if (k == 0) {
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
|
ListNode pre = new ListNode(-1, head);
|
||||||
|
ListNode indexPre = pre;
|
||||||
|
ListNode indexAfter = pre;
|
||||||
|
for (int i = 0; i < k ; i++) {
|
||||||
|
indexAfter = indexAfter.next;
|
||||||
|
}
|
||||||
|
while (indexAfter.next != null) {
|
||||||
|
indexAfter = indexAfter.next;
|
||||||
|
indexPre = indexPre.next;
|
||||||
|
}
|
||||||
|
ListNode tmp = indexPre.next;
|
||||||
|
indexPre.next = null;
|
||||||
|
indexAfter.next = pre.next;
|
||||||
|
pre.next = tmp;
|
||||||
|
return pre.next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void tes1t() {
|
||||||
|
ListNode listNode = ListNode.listNodeFromArray(new int[]{1,2,3});
|
||||||
|
new Solution2().rotateRight(listNode, 4).printList();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class Solution1 {
|
||||||
|
// public ListNode rotateRight(ListNode head, int k) {
|
||||||
|
// ListNode pre = new ListNode(-1, head);
|
||||||
|
// ListNode preIndex = pre;
|
||||||
|
// ListNode afterIndex = pre;
|
||||||
|
// for (int i = 0; i < k && afterIndex != null; i++) {
|
||||||
|
// afterIndex = afterIndex.next;
|
||||||
|
// }
|
||||||
|
// while (afterIndex.next != null) {
|
||||||
|
// afterIndex = afterIndex.next;
|
||||||
|
// preIndex = preIndex.next;
|
||||||
|
// }
|
||||||
|
// afterIndex.next = pre.next;
|
||||||
|
// ListNode next = preIndex.next;
|
||||||
|
// preIndex.next = null;
|
||||||
|
// return next;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
class Solution2 {
|
||||||
|
public ListNode rotateRight(ListNode head, int k) {
|
||||||
|
if (head == null) {
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
ListNode pre = new ListNode(-1, head);
|
||||||
|
int len = 0;
|
||||||
|
ListNode index = pre;
|
||||||
|
while (index.next != null) {
|
||||||
|
len++;
|
||||||
|
index = index.next;
|
||||||
|
}
|
||||||
|
|
||||||
|
int add = len - k % len; // |a|k| 中的a部分
|
||||||
|
if (add == 0) {
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
|
index.next = pre.next;
|
||||||
|
ListNode tmp = pre;
|
||||||
|
for (int i = 0; i < add; i++) {
|
||||||
|
tmp = tmp.next;
|
||||||
|
}
|
||||||
|
ListNode cd = tmp.next;
|
||||||
|
tmp.next = null;
|
||||||
|
return cd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
92
src/main/java/cn/whaifree/leetCode/Stack/LeetCode71.java
Normal file
92
src/main/java/cn/whaifree/leetCode/Stack/LeetCode71.java
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
package cn.whaifree.leetCode.Stack;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Deque;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 1.0
|
||||||
|
* @Author whai文海
|
||||||
|
* @Date 2024/9/22 15:29
|
||||||
|
* @注释
|
||||||
|
*/
|
||||||
|
public class LeetCode71 {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
new Thread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
List<int[]> res = new ArrayList<>();
|
||||||
|
while (true) {
|
||||||
|
System.out.println("ADD");
|
||||||
|
res.add(new int[100000]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
new Thread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
List<int[]> res = new ArrayList<>();
|
||||||
|
while (true) {
|
||||||
|
System.out.println(1000);
|
||||||
|
try {
|
||||||
|
Thread.sleep(1000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
System.out.println(new Solution().simplifyPath("/.../../.."));
|
||||||
|
}
|
||||||
|
|
||||||
|
class Solution {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* . 当前目录
|
||||||
|
* .. 父亲目录
|
||||||
|
* ///*n /// // / 变为/
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* - 碰到.. 出栈
|
||||||
|
* - 碰到. 忽略
|
||||||
|
* - N*\// 都忽略
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param path
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String simplifyPath(String path) {
|
||||||
|
Deque<String> stack = new LinkedList<>();
|
||||||
|
String[] split = path.split("/");
|
||||||
|
for (int i = 0; i < split.length; i++) {
|
||||||
|
String s = split[i];
|
||||||
|
if (s.equals("/")||s.isEmpty()||s.equals(".")) {
|
||||||
|
continue;
|
||||||
|
} else if (s.equals("..")) {
|
||||||
|
if (!stack.isEmpty()) {
|
||||||
|
stack.pop();
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
stack.push(s);
|
||||||
|
}
|
||||||
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
|
while (!stack.isEmpty()) {
|
||||||
|
stringBuilder.append("/");
|
||||||
|
stringBuilder.append(stack.pollLast());
|
||||||
|
}
|
||||||
|
return stringBuilder.isEmpty() ? "/" : stringBuilder.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
92
src/main/java/cn/whaifree/leetCode/Tree/LeetCode114.java
Normal file
92
src/main/java/cn/whaifree/leetCode/Tree/LeetCode114.java
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
package cn.whaifree.leetCode.Tree;
|
||||||
|
|
||||||
|
import cn.whaifree.leetCode.model.TreeNode;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.Deque;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 1.0
|
||||||
|
* @Author whai文海
|
||||||
|
* @Date 2024/9/23 17:31
|
||||||
|
* @注释
|
||||||
|
*/
|
||||||
|
public class LeetCode114 {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
TreeNode treeNode = TreeNode.constructTreeByArray(new Integer[]{0, 1, 2, 3, 4, 5, 6});
|
||||||
|
new Solution().flatten(treeNode);
|
||||||
|
treeNode.printTree();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class Solution {
|
||||||
|
public void flatten(TreeNode root) {
|
||||||
|
if (root == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Deque<TreeNode> deque = new LinkedList<>();
|
||||||
|
deque.push(root);
|
||||||
|
TreeNode tmp = root;
|
||||||
|
while (!deque.isEmpty()) {
|
||||||
|
TreeNode pop = deque.pop();
|
||||||
|
if (pop != null) {
|
||||||
|
if (pop.right != null) {
|
||||||
|
deque.push(pop.right);
|
||||||
|
}
|
||||||
|
if (pop.left != null) {
|
||||||
|
deque.push(pop.left);
|
||||||
|
}
|
||||||
|
deque.push(pop);
|
||||||
|
deque.push(null);
|
||||||
|
}else {
|
||||||
|
TreeNode nextPop = deque.pop();
|
||||||
|
if (nextPop != tmp) {
|
||||||
|
tmp.right = nextPop;
|
||||||
|
tmp.left = null;
|
||||||
|
tmp = tmp.right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test2() {
|
||||||
|
TreeNode treeNode = TreeNode.constructTreeByArray(new Integer[]{0, 1, 2, 3, 4, 5, 6});
|
||||||
|
new Solution2().flatten(treeNode);
|
||||||
|
treeNode.printTree();
|
||||||
|
}
|
||||||
|
|
||||||
|
class Solution2 {
|
||||||
|
public void flatten(TreeNode root) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (root == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
subFlatten(root);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TreeNode subFlatten(TreeNode root) {
|
||||||
|
TreeNode left = root.left;
|
||||||
|
TreeNode right = root.right;
|
||||||
|
TreeNode tmp = root;
|
||||||
|
root.left = null;
|
||||||
|
if (left != null) {
|
||||||
|
root.right = left;
|
||||||
|
tmp = subFlatten(left); // tmp会返回一节的最后一个尾巴节点
|
||||||
|
}
|
||||||
|
if (right != null) {
|
||||||
|
tmp.right = right; // 把前面的right拿过来再往下
|
||||||
|
tmp = subFlatten(right);
|
||||||
|
}
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -64,7 +64,7 @@ public class ThreadDemo1 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
countDownLatch.await();
|
countDownLatch.await(10, TimeUnit.SECONDS);
|
||||||
|
|
||||||
new Thread(() -> System.out.println("上面的9个执行完了,轮到我了 wait complete!")).start();
|
new Thread(() -> System.out.println("上面的9个执行完了,轮到我了 wait complete!")).start();
|
||||||
|
|
||||||
|
211
src/main/java/cn/whaifree/test/io/AioServer.java
Normal file
211
src/main/java/cn/whaifree/test/io/AioServer.java
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
package cn.whaifree.test.io;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.ServerSocket;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.channels.*;
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 1.0
|
||||||
|
* @Author whai文海
|
||||||
|
* @Date 2024/9/22 20:29
|
||||||
|
* @注释
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public class AioServer {
|
||||||
|
public static void main(String[] args) throws IOException, InterruptedException {
|
||||||
|
// 创建一个单线程的线程池
|
||||||
|
ExecutorService executorService = Executors.newSingleThreadExecutor();
|
||||||
|
|
||||||
|
// 创建一个异步通道组,使用线程池
|
||||||
|
AsynchronousChannelGroup group = AsynchronousChannelGroup.withThreadPool(executorService);
|
||||||
|
// 打开一个异步服务器套接字通道,并绑定到8080端口
|
||||||
|
AsynchronousServerSocketChannel serverChannel = AsynchronousServerSocketChannel.open(group).bind(new InetSocketAddress(8080));
|
||||||
|
|
||||||
|
// 创建一个计数器,用于等待服务器接受连接
|
||||||
|
CountDownLatch latch = new CountDownLatch(1);
|
||||||
|
// 服务器通道接受连接,并指定一个完成处理器
|
||||||
|
serverChannel.accept(null, new AcceptCompletionHandler(latch));
|
||||||
|
|
||||||
|
// 等待服务器接受连接
|
||||||
|
latch.await();
|
||||||
|
// 关闭通道组
|
||||||
|
group.shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 完成处理器,用于处理服务器接受连接的事件
|
||||||
|
static class AcceptCompletionHandler implements CompletionHandler<AsynchronousSocketChannel, Void> {
|
||||||
|
private final CountDownLatch latch;
|
||||||
|
|
||||||
|
public AcceptCompletionHandler(CountDownLatch latch) {
|
||||||
|
this.latch = latch;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void completed(AsynchronousSocketChannel result, Void attachment) {
|
||||||
|
try {
|
||||||
|
Thread.sleep(5000);
|
||||||
|
// 向客户端发送消息
|
||||||
|
result.write(ByteBuffer.wrap("Hello from server".getBytes()), null, new WriteCompletionHandler());
|
||||||
|
// 关闭客户端通道
|
||||||
|
result.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
// 计数器减一
|
||||||
|
latch.countDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void failed(Throwable exc, Void attachment) {
|
||||||
|
// 打印异常信息
|
||||||
|
exc.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 完成处理器,用于处理服务器发送消息的事件
|
||||||
|
static class WriteCompletionHandler implements CompletionHandler<Integer, Void> {
|
||||||
|
@Override
|
||||||
|
public void completed(Integer result, Void attachment) {
|
||||||
|
// 打印消息发送成功
|
||||||
|
System.out.println("Message sent");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void failed(Throwable exc, Void attachment) {
|
||||||
|
// 打印异常信息
|
||||||
|
exc.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class BioServer {
|
||||||
|
public static void main(String[] args) throws IOException {
|
||||||
|
// 创建一个服务器套接字,并绑定到8080端口
|
||||||
|
ServerSocket serverSocket = new ServerSocket(8080);
|
||||||
|
System.out.println("Server started");
|
||||||
|
|
||||||
|
// 无限循环,等待客户端连接
|
||||||
|
while (true) {
|
||||||
|
// 接受客户端连接
|
||||||
|
Socket socket = serverSocket.accept();
|
||||||
|
// 创建一个新的线程处理客户端连接
|
||||||
|
new Thread(new ClientHandler(socket)).start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 客户端处理器,用于处理客户端连接
|
||||||
|
static class ClientHandler implements Runnable {
|
||||||
|
private final Socket socket;
|
||||||
|
|
||||||
|
public ClientHandler(Socket socket) {
|
||||||
|
this.socket = socket;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try (BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
|
||||||
|
PrintWriter out = new PrintWriter(socket.getOutputStream(), true)) {
|
||||||
|
|
||||||
|
String inputLine;
|
||||||
|
// 循环读取客户端发送的消息
|
||||||
|
while ((inputLine = in.readLine()) != null) {
|
||||||
|
// 打印接收到的消息
|
||||||
|
System.out.println("Received: " + inputLine);
|
||||||
|
// 向客户端发送消息
|
||||||
|
out.println("Echo: " + inputLine);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class NioServer {
|
||||||
|
public static void main(String[] args) throws IOException {
|
||||||
|
// 打开一个选择器
|
||||||
|
Selector selector = Selector.open();
|
||||||
|
// 打开一个服务器套接字通道
|
||||||
|
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
|
||||||
|
// 设置通道为非阻塞模式
|
||||||
|
serverSocketChannel.configureBlocking(false);
|
||||||
|
// 绑定到8080端口
|
||||||
|
serverSocketChannel.bind(new InetSocketAddress(8080));
|
||||||
|
// 注册选择器,监听接受事件
|
||||||
|
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
|
||||||
|
|
||||||
|
// 无限循环,等待事件发生
|
||||||
|
while (true) {
|
||||||
|
// 选择器选择准备好的通道
|
||||||
|
selector.select();
|
||||||
|
// 遍历所有准备好的通道
|
||||||
|
for (SelectionKey key : selector.selectedKeys()) {
|
||||||
|
// 如果是接受事件
|
||||||
|
if (key.isAcceptable()) {
|
||||||
|
// 处理接受事件
|
||||||
|
handleAccept(serverSocketChannel, selector);
|
||||||
|
// 如果是读取事件
|
||||||
|
} else if (key.isReadable()) {
|
||||||
|
// 处理读取事件
|
||||||
|
handleRead(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 清空选择器中的事件
|
||||||
|
selector.selectedKeys().clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理接受事件
|
||||||
|
private static void handleAccept(ServerSocketChannel serverSocketChannel, Selector selector) throws IOException {
|
||||||
|
// 接受客户端连接
|
||||||
|
SocketChannel clientChannel = serverSocketChannel.accept();
|
||||||
|
// 设置通道为非阻塞模式
|
||||||
|
clientChannel.configureBlocking(false);
|
||||||
|
// 注册选择器,监听读取事件
|
||||||
|
clientChannel.register(selector, SelectionKey.OP_READ);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理读取事件
|
||||||
|
private static void handleRead(SelectionKey key) throws IOException {
|
||||||
|
// 获取客户端通道
|
||||||
|
SocketChannel clientChannel = (SocketChannel) key.channel();
|
||||||
|
// 创建一个缓冲区
|
||||||
|
ByteBuffer buffer = ByteBuffer.allocate(1024);
|
||||||
|
// 读取客户端发送的消息
|
||||||
|
int read = clientChannel.read(buffer);
|
||||||
|
// 如果读取到了消息
|
||||||
|
if (read > 0) {
|
||||||
|
// 将缓冲区切换到读模式
|
||||||
|
buffer.flip();
|
||||||
|
// 创建一个字节数组,用于存储读取到的消息
|
||||||
|
byte[] data = new byte[read];
|
||||||
|
// 将缓冲区中的数据读取到字节数组中
|
||||||
|
buffer.get(data);
|
||||||
|
// 将字节数组转换为字符串
|
||||||
|
String message = new String(data);
|
||||||
|
// 打印接收到的消息
|
||||||
|
System.out.println("Received: " + message);
|
||||||
|
// 向客户端发送消息
|
||||||
|
clientChannel.write(ByteBuffer.wrap(("Echo: " + message).getBytes()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user