文档更新与代码优化

- 文档中已添加关于字符串、字节和void数据类型的说明,以完善NumPy数据类型部分。
- 修复了用户创建操作中的SQL错误,确保UUID正确分配给新用户记录。
- 调整了EntityClass内的重新加载机制,使其能够遵循给定的`flush`参数,防止在刷新时错误地刷新新实体。
This commit is contained in:
whaifree 2024-09-02 00:57:08 +08:00
parent ae7654ad39
commit 2c56c727b1
17 changed files with 1188 additions and 75 deletions

View File

@ -17,6 +17,12 @@
<dependencies>
<dependency>
<groupId>com.github.phantomthief</groupId>
<artifactId>simple-pool</artifactId>
<version>0.1.17</version>
</dependency>
<!--spring-->
<dependency>

View File

@ -0,0 +1,130 @@
package cn.whaifree.dataStructure.heap;
import cn.whaifree.leetCode.model.TreeNode;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/9/1 1:47
* @注释
*/
public class MyHeap {
@Test
public void test() {
Heap heap = new Heap();
PriorityQueue<Integer> priorityQueue = new PriorityQueue<>();
// 测试数据
int[] testData = {5, 3, 8, 1, 2, 7, 4, 6};
// 插入数据
for (int val : testData) {
heap.add(val);
priorityQueue.add(val);
}
while (!heap.heap.isEmpty() && !priorityQueue.isEmpty()) {
int customTop = heap.getMin();
int pqTop = priorityQueue.peek();
System.out.println("Custom Heap Top: " + customTop + ", PriorityQueue Top: " + pqTop);
if (customTop != pqTop) {
System.out.println("Heaps are inconsistent.");
return;
}
heap.pop();
priorityQueue.poll();
}
}
class Heap {
List<Integer> heap = null;
public Heap() {
heap = new ArrayList<>();
}
public void add(int val) {
// 放到最后
heap.add(heap.size(), val);
// 向上调整
adjustDown();
}
public void adjustUp() {
int noLeaf = (heap.size() - 2) / 2;
while (noLeaf >= 0) {
int left = noLeaf * 2 + 1;
int right = noLeaf * 2 + 2;
int maxIn = noLeaf;
if (left < heap.size() && heap.get(left) < heap.get(noLeaf)) {
maxIn = left;
}
if (right < heap.size() && heap.get(right) < heap.get(noLeaf)) {
maxIn = right;
}
swap(maxIn, noLeaf);
noLeaf--;
TreeNode.constructTree(heap.toArray(value -> new Integer[0]));
}
}
public void swap(int i, int j) {
int temp = heap.get(i);
heap.set(i, heap.get(j));
heap.set(j, temp);
}
public void pop() {
swap(0, heap.size() - 1);
heap.remove(heap.size() - 1);
adjustDown();
}
/**
* 从头部向下调整
*/
public void adjustDown() {
// int half = heap.size() >>> 1;
// int k = 0;
// while (k < half) {
// int left = k * 2 + 1;
// int right = k * 2 + 2;
// int minIn = k;
// if (left < heap.size() && heap.get(left) < heap.get(k)) {
// minIn = left;
// }
// if (right < heap.size() && heap.get(right) < heap.get(k)) {
// minIn = right;
// }
// if (minIn != k) {
// swap(minIn, k);
// } else {
// break;
// }
// }
}
public int getMin() {
return heap.get(0);
}
}
}

View File

@ -1,4 +1,4 @@
package cn.whaifree.dataStructure;/*
package cn.whaifree.dataStructure.heap;/*
* Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*

View File

@ -0,0 +1,88 @@
package cn.whaifree.designPattern.ChainPattern.rule;
import cn.hutool.core.lang.Validator;
/**
*
* 责任链模式
*
* @version 1.0
* @Author whai文海
* @Date 2024/8/31 17:33
* @注释
*/
public class NoIfElse {
public static void main(String[] args) {
VerifyEmailRule verifyEmailRule = new VerifyEmailRule();
verifyEmailRule.appendRuleChain(new VerifyPhoneRule());
System.out.println(verifyEmailRule.processLogic("13648765326"));
}
}
interface IRuleChain {
IRuleChain appendRuleChain(IRuleChain ruleChain);
IRuleChain getNextRuleChain();
Object processLogic(Object inputData);
}
abstract class AbstractRuleChain implements IRuleChain {
IRuleChain next;
@Override
public IRuleChain appendRuleChain(IRuleChain ruleChain) {
next = ruleChain;
return next;
}
@Override
public IRuleChain getNextRuleChain() {
return next;
}
@Override
public Object processLogic(Object inputData) {
if (next != null) {
return next.processLogic(inputData);
}else {
return inputData;
}
}
}
class VerifyEmailRule extends AbstractRuleChain{
@Override
public Object processLogic(Object inputData) {
// 具体执行方法
boolean email = Validator.isEmail((CharSequence) inputData);
if (email) {
System.out.println("email:" + email);
}else {
System.out.println("no email:" + email);
}
return super.processLogic(inputData);
}
}
class VerifyPhoneRule extends AbstractRuleChain{
@Override
public Object processLogic(Object inputData) {
// 具体执行方法
boolean phone = Validator.isMobile((CharSequence) inputData);
if (phone) {
System.out.println("phone:" + phone);
}else {
System.out.println("no phone:" + phone);
}
return super.processLogic(inputData);
}
}

View File

@ -0,0 +1,18 @@
package cn.whaifree.designPattern;
/**
*
* 干掉if else 的设计模式
*
* @version 1.0
* @Author whai文海
* @Date 2024/8/31 17:16
* @注释
*/
public class NoIElse {
}

View File

@ -0,0 +1,90 @@
package cn.whaifree.interview.Meituan;
import java.util.Scanner;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/8/31 21:10
* @注释
*/
public class TestDemo {
@org.junit.Test
public void test() {
int[] nums = {999999993,999999993,999999993,999999993,999999993};
int k = 999999993;
System.out.println(Test.find1(nums, k));
}
/**
* <a href="https://www.nowcoder.com/exam/test/82794641/detail?pid=52205528&examPageSource=Company&testCallback=https%3A%2F%2Fwww.nowcoder.com%2Fexam%2Fcompany%3FcurrentTab%3Drecommand%26jobId%3D100%26keyword%3D2024%26selectStatus%3D0%26tagIds%3D179&testclass=%E8%BD%AF%E4%BB%B6%E5%BC%80%E5%8F%91">...</a>
*/
static class Test {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext hasNextLine 的区别
int num = in.nextInt();
int k = in.nextInt();
int[] nums = new int[num];
for (int i = 0; i < num; i++) {
nums[i] = in.nextInt();
}
System.out.println(find(nums, k));
}
/**
* 最长字数组满足平均==k
*
* @param nums
* @param k
*/
public static int find(int[] nums, int k) {
int left = 0;
int right = 0;
long nowSum = 0;
int maxLen = Integer.MIN_VALUE;
while (right < nums.length) {
nowSum += nums[right];
while (left <= right && nowSum > (long) k * (right - left + 1)) {
nowSum -= nums[left];
left++;
}
if ((long) k * (right - left + 1) == nowSum) {
maxLen = Math.max(maxLen, right - left + 1);
}
right++;
}
return maxLen == Integer.MIN_VALUE ? -1 : maxLen;
}
/**
* 最长字数组满足平均==k
*
* @param nums
* @param k
*/
public static int find1(int[] nums, int k) {
int maxLen = Integer.MIN_VALUE;
for (int i = 0; i < nums.length; i++) {
long nowSum = 0;
for (int j = i; j < nums.length; j++) {
nowSum += nums[j];
if (nowSum == (long) k * (j - i + 1)) {
maxLen = Math.max(maxLen, j - i + 1);
}
}
}
return maxLen == Integer.MIN_VALUE ? -1 : maxLen;
}
}
}

View File

@ -0,0 +1,51 @@
package cn.whaifree.leetCode.Array;
import org.junit.Test;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/9/1 2:21
* @注释
*/
public class LeetCode169
{
@Test
public void test()
{
int[] nums = {2,2,1,1,1,2,2};
Solution solution = new Solution();
int i = solution.majorityElement(nums);
System.out.println(i);
}
class Solution {
/**
* 遍历每个元素
* count 为现在出现最多的数
* - 如果count = 0
* - 这个元素出现的次数>=之前元素出现的个数
* 所以基准变为这个元素
* count = item == base : 1:-1
*
* 如果是这个元素+1,不是这个元素-1
*
* @param nums
* @return
*/
public int majorityElement(int[] nums) {
int count = 0;
Integer candidate = null;
for (int num : nums) {
if (count == 0) {
candidate = num;
System.out.println("基准元素:" + candidate);
}
count += (num == candidate) ? 1 : -1;
}
return candidate;
}
}
}

View File

@ -1,6 +1,5 @@
package cn.whaifree.leetCode.Array;
import cn.whaifree.leetCode.model.TreeNode;
import org.junit.Test;
import java.util.Arrays;
@ -147,81 +146,81 @@ public class LeetCode215 {
// System.out.println(i);
}
@Test
public void test188()
{
new sol().findKthLargest(new int[]{3, 2, 1, 5, 6, 4}, 3);
// @Test
// public void test188()
// {
// new sol().findKthLargest(new int[]{3, 2, 1, 5, 6, 4}, 3);
//
//
// }
// class sol{
// /**
// * 3
// * / \
// * / \
// * 5 -2147483648
// * /
// * 2 右边那个有问题所以不行
// * @param nums
// * @param k
// * @return
// */
// public int findKthLargest(int[] nums, int k) {
// Heap heap = new Heap(k);
// for (int num : nums) {
// heap.add(num);
// }
// return 1;
// }
// }
}
class sol{
/**
* 3
* / \
* / \
* 5 -2147483648
* /
* 2 右边那个有问题所以不行
* @param nums
* @param k
* @return
*/
public int findKthLargest(int[] nums, int k) {
Heap heap = new Heap(k);
for (int num : nums) {
heap.add(num);
}
return 1;
}
}
class Heap{
int[] heap = null;
public Heap(int k) {
this.heap = new int[k + 1];
Arrays.fill(this.heap, Integer.MIN_VALUE);
}
public void add(int num) {
heap[heap.length - 1] = num;
shiftUp(heap, heap.length - 1);
}
/**
* 固定长度的让其 shiftUp
* @param nums
* @param numIndex numsIndex 位置上移
*/
public void shiftUp(int[] nums, int numIndex) {
int k = numIndex;
while (k > 0) {
int parent = (k - 1) / 2;
// if (nums[numIndex] < nums[parent]) { // 小顶堆
if (nums[k] > nums[parent]) { // 大顶堆
// 小顶堆小的上移
swap(nums, parent, k);
k = parent;
}else {
break;
}
TreeNode.constructTreeByArrayWithInteger(nums);
}
}
public void swap(int[] nums, int start, int end) {
int temp = nums[start];
nums[start] = nums[end];
nums[end] = temp;
}
}
// class Heap{
//
//
// int[] heap = null;
//
// public Heap(int k) {
// this.heap = new int[k + 1];
// Arrays.fill(this.heap, Integer.MIN_VALUE);
// }
//
// public void add(int num) {
// heap[heap.length - 1] = num;
// shiftUp(heap, heap.length - 1);
// }
//
//
// /**
// * 固定长度的让其 shiftUp
// * @param nums
// * @param numIndex numsIndex 位置上移
// */
// public void shiftUp(int[] nums, int numIndex) {
// int k = numIndex;
// while (k > 0) {
// int parent = (k - 1) / 2;
//// if (nums[numIndex] < nums[parent]) { // 小顶堆
// if (nums[k] > nums[parent]) { // 大顶堆
// // 小顶堆小的上移
// swap(nums, parent, k);
// k = parent;
// }else {
// break;
// }
// TreeNode.constructTreeByArrayWithInteger(nums);
// }
//
// }
//
// public void swap(int[] nums, int start, int end) {
// int temp = nums[start];
// nums[start] = nums[end];
// nums[end] = temp;
// }
//
// }
class Solution {
public int findKthLargest(int[] nums, int k) {

View File

@ -0,0 +1,104 @@
package cn.whaifree.leetCode.Stack;
import org.junit.Test;
import java.util.*;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/9/1 0:52
* @注释
*/
public class LeetCode155 {
@Test
public void test2() {
MinStack minStack = new MinStack();
// ["MinStack","push","push","push","getMin","pop","top","getMin"]
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
System.out.println(minStack.getMin());
minStack.pop();
System.out.println(minStack.top());
System.out.println(minStack.getMin());
}
class MinStack {
static class Item{
Integer item;
Integer minV;
public Item(Integer item, Integer minV) {
this.item = item;
this.minV = minV;
}
}
Deque<Item> itemStack = null;
public MinStack() {
itemStack = new ArrayDeque<>();
}
public void push(int val) {
// 找到当前最小值
Integer minNow = Math.min(getMin(), val);
Item item = new Item(val, minNow);
itemStack.push(item);
}
public void pop() {
itemStack.pop();
}
public int top() {
if (itemStack.isEmpty()) {
return Integer.MAX_VALUE;
}
return itemStack.peek().item;
}
public int getMin() {
if (itemStack.isEmpty()) {
return Integer.MAX_VALUE;
}
return itemStack.peek().minV;
}
}
/**
* Your MinStack object will be instantiated and called as such:
* MinStack obj = new MinStack();
* obj.push(val);
* obj.pop();
* int param_3 = obj.top();
* int param_4 = obj.getMin();
*/
@Test
public void test() {
MinStack minStack = new MinStack();
// ["MinStack","push","push","push","getMin","pop","top","getMin"]
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
System.out.println(minStack.getMin());
minStack.pop();
System.out.println(minStack.top());
System.out.println(minStack.getMin());
}
/**
* Your MinStack object will be instantiated and called as such:
* MinStack obj = new MinStack();
* obj.push(val);
* obj.pop();
* int param_3 = obj.top();
* int param_4 = obj.getMin();
*/
}

View File

@ -0,0 +1,103 @@
package cn.whaifree.leetCode.String;
import org.junit.Test;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/8/31 14:57
* @注释
*/
public class LeetCode165 {
@Test
public void test() {
Solution2 solution = new Solution2();
int result = solution.compareVersion("1.01.2", "1.001");
System.out.println(result);
}
class Solution2 {
/**
* 双指针不断计算有效长度
* @param version1
* @param version2
* @return
*/
public int compareVersion(String version1, String version2) {
int v1Index = 0;
int v2Index = 0;
while (v1Index < version1.length() || v2Index < version2.length()) {
int tmpV1Sum = 0;
while (v1Index < version1.length() && version1.charAt(v1Index) != '.') {
tmpV1Sum += tmpV1Sum * 10 + version1.charAt(v1Index) - '0';
v1Index++;
}
v1Index++; // 跳过.
int tmpV2Sum = 0;
while (v2Index < version2.length() && version2.charAt(v2Index) != '.') {
tmpV2Sum += tmpV2Sum * 10 + version2.charAt(v2Index) - '0';
v2Index++;
}
v2Index++; // 跳过.
if (tmpV1Sum < tmpV2Sum) {
return -1;
} else if (tmpV1Sum > tmpV2Sum) {
return 1;
}
}
return 0;
}
}
class Solution {
/**
* 1.2 1.10
* 1.01 1.001
* 1.0.0.0
*
*
* @param version1
* @param version2
* @return
*/
public int compareVersion(String version1, String version2) {
String[] splitV1 = version1.split("\\.");
String[] splitV2 = version2.split("\\.");
if (splitV1.length < splitV2.length) {
splitV1 = fill(splitV1, splitV2.length);
}else {
splitV2 = fill(splitV2, splitV1.length);
}
// 现在两边一样长了
for (int i = 0; i < splitV1.length; i++) {
Integer v1 = Integer.valueOf(splitV1[i]);
Integer v2 = Integer.valueOf(splitV2[i]);
if (v1 > v2) {
return 1;
} else if (v1 < v2) {
return -1;
}
}
return 0;
}
public String[] fill(String[] split, int newLen) {
String[] tmp = new String[newLen];
int i = 0;
for (; i < split.length; i++) {
tmp[i] = split[i];
}
for (; i < tmp.length; i++) {
tmp[i] = "0";
}
return tmp;
}
}
}

View File

@ -0,0 +1,53 @@
package cn.whaifree.redo.redoAll;
import org.junit.Test;
import java.util.Deque;
import java.util.LinkedList;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/8/31 18:15
* @注释
*/
public class LeetCode20 {
@Test
public void test() {
Solution solution = new Solution();
String s = "()()[]([])";
boolean valid = solution.isValid(s);
System.out.println(valid);
}
class Solution {
public boolean isValid(String s) {
char[] charArray = s.toCharArray();
Deque<Character> stack = new LinkedList<>();
for (int i = 0; i < charArray.length; i++) {
char c = charArray[i];
if (c == '(' || c == '[' || c == '{') {
stack.push(c);
} else {
if (stack.isEmpty()) {
return false;
}
Character pop = stack.pop();
if (c == ')' && pop != '(') {
return false;
}else if (c == ']' && pop != '[') {
return false;
}else if (c == '}' && pop != '{') {
return false;
}
}
}
return stack.isEmpty();
}
}
}

View File

@ -0,0 +1,57 @@
package cn.whaifree.redo.redoAll;
import org.junit.Test;
import java.util.HashMap;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/8/31 18:32
* @注释
*/
public class LeetCode3 {
@Test
public void test() {
Solution solution = new Solution();
String s = "abcabcbb";
int result = solution.lengthOfLongestSubstring(s);
System.out.println(result);
}
class Solution {
public int lengthOfLongestSubstring(String s) {
HashMap<Character, Boolean> map = new HashMap<>();
int left = 0;
int right = 0;
int maxLen = 0;
while (right < s.length()) {
char item = s.charAt(right);
if (map.containsKey(item) && map.get(item)) {
// 已经存在
maxLen = Math.max(maxLen, right - left);
while (map.get(item)) {
map.put(s.charAt(left), false);
left++;
}
}
map.put(item, true);
right++;
}
int mapSize = 0;
for (Character c : map.keySet()) {
if (map.get(c)) {
mapSize++;
}
}
// 有可能在后面才能取到最大值
return Math.max(mapSize, maxLen);
}
}
}

View File

@ -0,0 +1,98 @@
package cn.whaifree.redo.redoAll;
import org.junit.Test;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/9/1 23:07
* @注释
*/
public class LeetCode309 {
class Solution {
/**
* dp[][]
*
*
*
* 1 2 3 0 2
* 0 0 1 2
* 1 0 0 0
* 2 -1-1
* 3 -1-2
*
* @param prices
* @return
*/
public int maxProfit(int[] prices) {
int n = prices.length;
if (n < 2) {
return 0;
}
int[][] dp = new int[n][3];
dp[0][0] = 0;
dp[0][1] = -prices[0];
dp[0][2] = -prices[0];
for (int i = 1; i < n; i++) {
dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][2]);
dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] - prices[i]);
dp[i][2] = dp[i - 1][1] + prices[i];
}
return 1;
}
}
@Test
public void test() {
int b = 1 << 4;
Solution solution1 = new Solution();
int i1 = solution1.hashCode();
String binaryString = Integer.toBinaryString(i1);
System.out.println(binaryString);
int[] prices = {1,0};
Solution1 solution = new Solution1();
int i = solution.maxProfit(prices);
System.out.println(i);
}
class Solution1 {
/**
* 1. 当天有股票 0
* - 前一天就有 dp[0][i-1]
* - 当天买入 dp[1][i-2] - values[i]
* 2. 当天没股票 1
* - 刚刚卖 dp[0][i-1]+value[i]
* - 前一天就没有 dp[1][i-1]
*
* dp[0][0] = -values[0] 第一天
* dp[1][0] = 0
*
* dp[0][1] = dp[0][0] dp[1][0]-values[i] 第二天有股票可能第一天就有或者刚刚买入
* dp[1][1] = dp[1][0] dp[0][1]+values[i]
* @param prices
* @return
*/
public int maxProfit(int[] prices) {
if (prices.length < 2) {
return 0;
}
int[][] dp = new int[2][prices.length];
dp[0][0] = -prices[0];
dp[1][0] = 0;
dp[0][1] = Math.max(dp[0][0], dp[1][0] - prices[1]);
dp[1][1] = Math.max(dp[1][0], dp[0][1] + prices[1]);
for (int i = 2; i < prices.length; i++) {
dp[0][i] = Math.max(dp[0][i - 1], dp[1][i - 2] - prices[i]);
dp[1][i] = Math.max(dp[0][i - 1] + prices[i], dp[1][i - 1]);
}
return dp[1][prices.length - 1];
}
}
}

View File

@ -0,0 +1,40 @@
package cn.whaifree.redo.redoAll;
import org.junit.Test;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/8/31 14:43
* @注释
*/
public class LeetCode704 {
@Test
public void test() {
Solution solution = new Solution();
int[] nums = {1};
int target = 8;
int result = solution.search(nums, target);
System.out.println(result);
}
class Solution {
public int search(int[] nums, int target) {
int left = 0;
int right = nums.length - 1;
while (left <= right) {
int mid = (left + right) >> 1;
if (nums[mid] == target) {
return mid;
} else if (nums[mid] < target) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return -1;
}
}
}

View File

@ -0,0 +1,62 @@
package cn.whaifree.redo.redoAll;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/9/1 20:59
* @注释
*/
public class LeetCode72 {
class Solution {
/**
* 对应位置字符相同取左上角的数字为操作数因为这个数已经对上了
*
* - 删除 dp[i-1][j]+1
* - 替换 dp[i-1][j-1]+1
* - 插入 dp[i][j-1]+1
*
* dp[i][j]表示把0-i变为0-j的最少操作次数
* h o r s e
* 0 1 2 3 4 5
* 0 0 1 2 3 4 5
* r 1 1 1 2 2 3 4 a b
* o 2 1 2 1 2 3 4 c d d的数量由前面acd已经计算过的最小操作得出即d这个操作只需要你的acb+1次操作必然能变成你要的样子
* s 3 1 3 2 3 2 3
*
*
* @param word1
* @param word2
* @return
*/
public int minDistance(String word1, String word2) {
int len1 = word1.length();
int len2 = word2.length();
int[][] dp = new int[len1 + 1][len2 + 1];
for (int i = 0; i <= len1; i++) {
dp[i][0] = i;
}
for (int i = 0; i <= len2; i++) {
dp[0][i] = i;
}
for (int i = 1; i <= len1; i++) {
for (int j = 1; j <= len2; j++) {
if (word1.charAt(i - 1) == word2.charAt(j - 1)) {
dp[i][j] = dp[i - 1][j - 1];
} else {
dp[i][j] = Math.min(
dp[i - 1][j - 1] + 1, // 替换 [i-1][j-1]
Math.min(
dp[i - 1][j] + 1, // 增加 [i][j-1]
dp[i][j - 1] + 1) // 删除 [i-1][j]
);
}
}
}
return dp[len1][len2];
}
}
}

View File

@ -0,0 +1,81 @@
package cn.whaifree.redo.redoAll;
import org.junit.Test;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/9/1 20:09
* @注释
*/
public class LeetCode75 {
@Test
public void test()
{
int[] nums = {2,1,0};
Solution1 solution = new Solution1();
solution.sortColors(nums);
for (int num : nums) {
System.out.println(num);
}
}
class Solution {
public void sortColors(int[] nums) {
int left = 0;
int right = nums.length - 1;
for (int i = 0; i < nums.length; i++) {
while (right >= i && nums[i] == 2) { // 万一换过来的还是2
swap(nums, right, i);
right--;
}
if (nums[i] == 0) { // 每个0只要往前插入就好了
swap(nums, left++, i);
}
}
}
public void swap(int[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}
class Solution1 {
/**
* 双指针两个指针指向0和1应该swap的地方
*
* @param nums
*/
public void sortColors(int[] nums) {
int indexZero = 0;
int indexOne = 0;
for (int i = 0; i < nums.length; i++) {
if (nums[i] == 0) {
swap(nums, indexZero, i);
// 此时有可能index0指向的是1这样交换会把1交换到后面去
// 即交换后的i指向的可能为1
// 需要把这个1给他替换到index1对应的位置
// if (indexZero < indexOne) {
// swap(nums, i, indexOne);
// }
indexOne++;
indexZero++;
} else if (nums[i] == 1) {
swap(nums, indexOne++, i);
}
}
}
public void swap(int[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}
}

View File

@ -0,0 +1,133 @@
package cn.whaifree.tech.thread;
import com.github.phantomthief.pool.KeyAffinityExecutor;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/9/1 12:53
* @注释
*/
public class AffinityThreadPoolTest {
final static Object o = new Object();
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(8);
long l = System.currentTimeMillis();
synchronized (o) {
for (int i = 0; i < 3; i++) {
int finalI = i;
executorService.submit(() -> {
System.out.println(Thread.currentThread().getName() + " A " + finalI);
});
executorService.submit(() -> {
System.out.println(Thread.currentThread().getName() + " B "+ finalI);
});
}
}
KeyAffinityExecutor executor = KeyAffinityExecutor.newSerializingExecutor(8,200, "MY-POOL");
l = System.currentTimeMillis();
synchronized (o) {
for (int i = 0; i < 3; i++) {
int finalI = i;
executor.submit("A", () -> {
System.out.println(Thread.currentThread().getName() + " A " + finalI);
return null;
});
executor.submit("B", () -> {
System.out.println(Thread.currentThread().getName() + " B "+ finalI);
return null;
});
}
}
System.out.println(System.currentTimeMillis() - l);
}
/**
* 效果相同key的任务可以顺序执行
* @param args
*/
public static void main1(String[] args) {
AffinityThreadPool affinityThreadPool = new AffinityThreadPool();
// 提交任务
affinityThreadPool.submitTask("key1", () -> System.out.println("Task 1 - Key 1"));
affinityThreadPool.submitTask("key1", () -> System.out.println("Task 2 - Key 1"));
affinityThreadPool.submitTask("key2", () -> System.out.println("Task 1 - Key 2"));
affinityThreadPool.submitTask("key2", () -> System.out.println("Task 2 - Key 2"));
// 关闭线程池
affinityThreadPool.shutdown();
}
}
class AffinityThreadPool {
private final Map<String, ExecutorService> threadPools;
private final AtomicInteger counter; // 当前线程池数量
public AffinityThreadPool() {
this.threadPools = new ConcurrentHashMap<>();
this.counter = new AtomicInteger(0);
}
/**
* 根据键获取或创建单线程执行器
* @param key
* @return 单线程执行器
*/
private synchronized ExecutorService getOrCreateThreadPool(String key) {
ExecutorService executor = threadPools.get(key);
if (executor == null) {
// 创建一个新的单线程执行器
executor = Executors.newSingleThreadExecutor();
threadPools.put(key, executor);
}
return executor;
}
/**
* 提交任务
* @param key
* @param task 任务
*/
public void submitTask(String key, Runnable task) {
ExecutorService executor = getOrCreateThreadPool(key);
executor.submit(task);
}
/**
* 关闭所有线程池
*/
public void shutdown() {
for (ExecutorService executor : threadPools.values()) {
executor.shutdown();
}
}
}