Compare commits
102 Commits
ab8c68d90f
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| dadf47f151 | |||
| ad72033f7e | |||
| f86b055ecb | |||
| 2235c45510 | |||
| d4dd16ef96 | |||
| 301a8b3911 | |||
| ba50b612d8 | |||
| f251d5601a | |||
| 21a23ee07e | |||
| a91655bac5 | |||
| c665ca3b1f | |||
| c1da2bd955 | |||
| e298c3a1a5 | |||
| 5edfe37a46 | |||
| 81c9ce2995 | |||
| 545e3df7c0 | |||
| 4160b02787 | |||
| fe1d9d913c | |||
| 166fe7fe9a | |||
| aaccb2114b | |||
| b7da6e9537 | |||
| 1b2a33d72d | |||
| bbd5275855 | |||
| b254db3bc0 | |||
| e575b8b94b | |||
| 850c0d3dc3 | |||
| 10e6dbf415 | |||
| 497732614d | |||
| f1a6584fcd | |||
| db57411ca1 | |||
| 09d2c4899b | |||
| 19d4bf9dee | |||
| 4cd72cd4f2 | |||
| 6cfb4fd37e | |||
| 4c3ee5fcf4 | |||
| 3c8752be70 | |||
| 226c572e59 | |||
| 4a6bd38732 | |||
| beb3a22fdd | |||
| 0f081ad1db | |||
| de07e89bb8 | |||
| e230636a54 | |||
| 83d334356b | |||
| f69a0267c4 | |||
| 987e56909c | |||
| 3aaabd8b6d | |||
| 1b10985030 | |||
| c72ced990f | |||
| 9107b0c4ba | |||
| 4bacec63a3 | |||
| 78d8ad252b | |||
| d51106271e | |||
| 947d81a5b5 | |||
| af2221682c | |||
| 8f2e5d0b62 | |||
| dba3de0be2 | |||
| 42da65cf47 | |||
| aa73622a34 | |||
| f601c051d4 | |||
| 9d6a001b85 | |||
| cc5cbc1ebb | |||
| e76d89f774 | |||
| ee6f67a6ab | |||
| b3dbc9f668 | |||
| 163882bb4d | |||
| 3947896a04 | |||
| d3b548c8b4 | |||
| cc013f3b86 | |||
| e106affde0 | |||
| 7aca97aa2e | |||
| 2f74ee2c8c | |||
| 0b5acb84ab | |||
| dccb21493b | |||
| 7cfdaab3d0 | |||
| bf4d8c5fb9 | |||
| 5865722a7d | |||
| 165f099240 | |||
| f581b143dc | |||
| 8d2f0d57b5 | |||
| 1fb0c52138 | |||
| 3b5b3b50a9 | |||
| f5ff83737c | |||
| 59c2bd2e3c | |||
| 367798c0dc | |||
| d194341936 | |||
|
|
3ee99909b8 | ||
| 2584e13e20 | |||
| 612feb1e9e | |||
| 6c8b22b204 | |||
| fa4748c57c | |||
|
|
16dad8f7b6 | ||
|
|
d8a328c472 | ||
|
|
b83d324c54 | ||
|
|
522969e077 | ||
|
|
19161217b7 | ||
|
|
2953e48009 | ||
|
|
69d714f19a | ||
| de91226dba | |||
| 7403cea6a7 | |||
|
|
6a59bac8b9 | ||
| 7697a84edf | |||
|
|
9f737f1a45 |
5
.gitignore
vendored
5
.gitignore
vendored
@@ -7,9 +7,10 @@
|
||||
target
|
||||
*.project
|
||||
*.classpath
|
||||
/.settings
|
||||
**/.settings
|
||||
/bin
|
||||
/useful-code.iml
|
||||
/.idea
|
||||
/resources/debug.log
|
||||
*.iml
|
||||
*.iml
|
||||
budd-common/.settings
|
||||
|
||||
2
LICENSE
2
LICENSE
@@ -1,6 +1,6 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright © 2020 xrv <xrg@live.com>
|
||||
Copyright © 2022 xrv <xrv@live.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -6,3 +6,7 @@
|
||||
[](https://github.com/ehlxr/budd/releases)
|
||||
|
||||
常用的一些 Java 代码
|
||||
|
||||
## Thanks to the following organizations for providing open source licenses
|
||||
|
||||
[<img src="https://github.com/ehlxr/budd/blob/master/jetbrains.svg" width = "200" height = "217" alt="jetbrains" align=center />](https://jb.gg/OpenSource)
|
||||
|
||||
55
budd-common/pom.xml
Normal file
55
budd-common/pom.xml
Normal file
@@ -0,0 +1,55 @@
|
||||
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>io.github.ehlxr</groupId>
|
||||
<artifactId>budd</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>budd-common</artifactId>
|
||||
<name>budd-common</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-annotations</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>okhttp</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>9</source>
|
||||
<target>9</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2020 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.algorithm;
|
||||
|
||||
/**
|
||||
* @author ehlxr
|
||||
* @since 2021-12-28 23:16.
|
||||
*/
|
||||
public class FindKthLargest {
|
||||
public static void main(String[] args) {
|
||||
int[] nums = new int[]{3, 2, 1, 5, 6, 4};
|
||||
System.out.println(findKthLargest(nums, 2));
|
||||
}
|
||||
|
||||
public static int findKthLargest2(int[] nums, int k) {
|
||||
for (int i = nums.length / 2 - 1; i >= 0; i--) {
|
||||
// 从第一个非叶子结点从下至上,从右至左调整结构
|
||||
adjustHeap(nums, i, nums.length);
|
||||
}
|
||||
|
||||
for (int j = nums.length - 1; j >= 0; j--) {
|
||||
k--;
|
||||
|
||||
if (k == 0) {
|
||||
return nums[0];
|
||||
}
|
||||
|
||||
swap(nums, 0, j);
|
||||
adjustHeap(nums, 0, j);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static void adjustHeap(int[] arr, int i, int length) {
|
||||
// 先取出当前元素 i
|
||||
int temp = arr[i];
|
||||
// 从 i 结点的左子结点开始,也就是 2i+1 处开始
|
||||
for (int k = i * 2 + 1; k < length; k = k * 2 + 1) {
|
||||
// 如果左子结点小于右子结点,k 指向右子结点
|
||||
if (k + 1 < length && arr[k] < arr[k + 1]) {
|
||||
k++;
|
||||
}
|
||||
// 如果子节点大于父节点,将子节点和父节点交换
|
||||
// if (arr[k] > arr[i]) {
|
||||
// swap(arr, k, i);
|
||||
if (arr[k] > temp) {
|
||||
// 不用进行交换
|
||||
arr[i] = arr[k];
|
||||
|
||||
i = k;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 将 temp 值放到最终的位置
|
||||
arr[i] = temp;
|
||||
}
|
||||
|
||||
|
||||
public static int findKthLargest(int[] nums, int k) {
|
||||
if (nums == null || nums.length < k) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int q = partition(nums, 0, nums.length - 1);
|
||||
while (q + 1 != k) {
|
||||
if (k < q + 1) {
|
||||
q = partition(nums, 0, q - 1);
|
||||
} else {
|
||||
q = partition(nums, q + 1, nums.length - 1);
|
||||
}
|
||||
}
|
||||
|
||||
return nums[q];
|
||||
}
|
||||
|
||||
|
||||
public static int partition(int[] a, int p, int r) {
|
||||
int pivot = a[r];
|
||||
int i = p;
|
||||
for (int j = p; j < r; j++) {
|
||||
if (a[j] >= pivot) {
|
||||
swap(a, i++, j);
|
||||
}
|
||||
}
|
||||
|
||||
swap(a, i, r);
|
||||
return i;
|
||||
}
|
||||
|
||||
private static void swap(int[] a, int i, int j) {
|
||||
if (i == j) {
|
||||
return;
|
||||
}
|
||||
int temp = a[i];
|
||||
a[i] = a[j];
|
||||
a[j] = temp;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2022 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.algorithm;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author ehlxr
|
||||
* @since 2022-04-29 11:07.
|
||||
*/
|
||||
public class MinWindow {
|
||||
public static void main(String[] args) {
|
||||
System.out.println(minWindow("cabwefgewcwaefgcf", "cae"));
|
||||
System.out.println(minWindow("bba", "ab"));
|
||||
System.out.println(minWindow("ADOBECODEBANC", "ABC"));
|
||||
System.out.println(minWindow("a", "a"));
|
||||
System.out.println(minWindow("a", "b"));
|
||||
System.out.println(minWindow("", "a"));
|
||||
System.out.println(minWindow("", ""));
|
||||
System.out.println(minWindow("a", "aa"));
|
||||
System.out.println(minWindow("aa", "a"));
|
||||
}
|
||||
|
||||
public static String minWindow(String s, String t) {
|
||||
Map<Character, Integer> windows = new HashMap<>();
|
||||
Map<Character, Integer> needs = new HashMap<>();
|
||||
for (int i = 0; i < t.length(); i++) {
|
||||
needs.put(t.charAt(i), needs.getOrDefault(t.charAt(i), 0) + 1);
|
||||
}
|
||||
|
||||
int left = 0, right = 0, valid = 0, start = -1, len = Integer.MAX_VALUE;
|
||||
while (right < s.length()) {
|
||||
char r = s.charAt(right);
|
||||
|
||||
if (needs.containsKey(r)) {
|
||||
windows.put(r, windows.getOrDefault(r, 0) + 1);
|
||||
if (windows.get(r).equals(needs.get(r))) {
|
||||
valid++;
|
||||
}
|
||||
}
|
||||
right++;
|
||||
|
||||
while (valid == needs.size()) {
|
||||
if (right - left < len) {
|
||||
len = right - left;
|
||||
start = left;
|
||||
}
|
||||
|
||||
char l = s.charAt(left);
|
||||
left++;
|
||||
|
||||
if (windows.containsKey(l)) {
|
||||
if (windows.get(l).equals(needs.get(l))) {
|
||||
valid--;
|
||||
}
|
||||
windows.put(l, windows.get(l) - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return start > -1 ? s.substring(start, start + len) : "";
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2020 xrv <xrg@live.com>
|
||||
* Copyright © 2022 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -22,45 +22,49 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.proxy;
|
||||
package io.github.ehlxr.algorithm;
|
||||
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 全排列
|
||||
*
|
||||
* @author ehlxr
|
||||
* @since 2019-06-28.
|
||||
* @since 2022-04-20 16:42.
|
||||
*/
|
||||
public class Main {
|
||||
public class Permutation {
|
||||
static List<List<Integer>> res = new ArrayList<>();
|
||||
|
||||
public static void main(String[] args) {
|
||||
Flyable proxy = (Flyable) Proxy.newProxyInstance(Flyable.class.getClassLoader(),
|
||||
new Class[]{Flyable.class}, new MyInvocationHandler(new Bird()));
|
||||
|
||||
// 动态代理会生成类似以下的 Java 代码
|
||||
/*
|
||||
package me.ehlxr.proxy;
|
||||
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class Proxy implements Flyable {
|
||||
private InvocationHandler handler;
|
||||
|
||||
public Proxy(InvocationHandler handler) {
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fly() {
|
||||
try {
|
||||
Method method = Flyable.class.getMethod("fly");
|
||||
this.handler.invoke(this, method, null);
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
int[] arr = {1, 2, 3};
|
||||
for (List<Integer> r : permute(arr)) {
|
||||
for (int i : r) {
|
||||
System.out.print(i + " ");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
proxy.fly();
|
||||
public static List<List<Integer>> permute(int[] nums) {
|
||||
List<Integer> track = new ArrayList<>();
|
||||
backtrack(nums, track);
|
||||
return res;
|
||||
}
|
||||
|
||||
public static void backtrack(int[] nums, List<Integer> track) {
|
||||
// 回溯结束条件
|
||||
if (track.size() == nums.length) {
|
||||
res.add(new ArrayList<>(track));
|
||||
return;
|
||||
}
|
||||
for (int num : nums) {
|
||||
if (track.contains(num)) {
|
||||
continue;
|
||||
}
|
||||
track.add(num);
|
||||
backtrack(nums, track);
|
||||
track.remove(track.size() - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2020 xrv <xrg@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.algorithm.binarytree.heap;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @author ehlxr
|
||||
* @since 2022-03-15 07:40.
|
||||
*/
|
||||
public class Heap {
|
||||
private static void createHeap(int[] a) {
|
||||
int n = a.length - 1; // 最后一个叶子节点下标
|
||||
buildHeap(a, n);
|
||||
}
|
||||
|
||||
private static void buildHeap(int[] a, int n) {
|
||||
// (n - 1) / 2 表示最后一个叶子节点父节点,即为最后一个非叶子节点
|
||||
for (int i = (n - 1) / 2; i >= 0; --i) {
|
||||
heapify(a, n, i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 堆化
|
||||
*
|
||||
* @param a 数组
|
||||
* @param n 最后一个元素下标
|
||||
* @param i 需要调整的父节点下标
|
||||
*/
|
||||
private static void heapify(int[] a, int n, int i) {
|
||||
while (true) {
|
||||
int max = i;
|
||||
|
||||
// 从当前节点和左右叶子节点中找出最大的
|
||||
int l = 2 * i + 1;
|
||||
if (l <= n && a[l] > a[max]) {
|
||||
max = l;
|
||||
}
|
||||
|
||||
int r = 2 * i + 2;
|
||||
if (r <= n && a[r] > a[max]) {
|
||||
max = r;
|
||||
}
|
||||
|
||||
// 当前节点最大时退出
|
||||
if (max == i) {
|
||||
break;
|
||||
}
|
||||
|
||||
swap(a, i, max);
|
||||
|
||||
// 最大节点和当前节点交换后,继续以当前节点为父节点堆化
|
||||
i = max;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 堆排序
|
||||
*/
|
||||
private static void sort(int[] a) {
|
||||
for (int i = a.length - 1; i > 0; i--) {
|
||||
buildHeap(a, i);
|
||||
// 堆顶元素和最后一个元素交换,除过最后一个元素外其它元素再次构建大顶堆
|
||||
swap(a, 0, i);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int[] arr = new int[]{1, 2, 3, 4, 5, 6};
|
||||
createHeap(arr);
|
||||
System.out.println(Arrays.toString(arr));
|
||||
|
||||
sort(arr);
|
||||
System.out.println(Arrays.toString(arr));
|
||||
|
||||
}
|
||||
|
||||
private static void swap(int[] arr, int i, int j) {
|
||||
int tmp = arr[i];
|
||||
arr[i] = arr[j];
|
||||
arr[j] = tmp;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2020 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.algorithm.dp;
|
||||
|
||||
/**
|
||||
* 在一个数组 arr 中,找出一组不相邻的数字,使得最后的和最大
|
||||
* <p>
|
||||
* 图解 https://cdn.jsdelivr.net/gh/0vo/oss/images/dp.jpg
|
||||
*
|
||||
* @author ehlxr
|
||||
* @since 2021-10-31 22:46.
|
||||
*/
|
||||
public class FindMaxSum {
|
||||
public static int recOpt(int[] arr, int i) {
|
||||
if (i == 0) {
|
||||
return arr[0];
|
||||
} else if (i == 1) {
|
||||
return Math.max(arr[0], arr[1]);
|
||||
} else {
|
||||
int a = recOpt(arr, i - 2) + arr[i];
|
||||
int b = recOpt(arr, i - 1);
|
||||
return Math.max(a, b);
|
||||
}
|
||||
}
|
||||
|
||||
public static int dpOpt(int[] arr) {
|
||||
int[] opt = new int[arr.length];
|
||||
opt[0] = arr[0];
|
||||
opt[1] = Math.max(arr[0], arr[1]);
|
||||
for (int i = 2; i < opt.length; i++) {
|
||||
int a = opt[i - 2] + arr[i];
|
||||
int b = opt[i - 1];
|
||||
opt[i] = Math.max(a, b);
|
||||
}
|
||||
return opt[arr.length - 1];
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int[] arr = {4, 1, 1, 9, 1};
|
||||
System.out.println(dpOpt(arr));
|
||||
System.out.println(recOpt(arr, arr.length - 1));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2022 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.algorithm.dp;
|
||||
|
||||
/**
|
||||
* 对于一组不同重量、不同价值、不可分割的物品,我们选择将某些物品装入背包,在满足背包最大重量限制的前提下,背包中可装入物品的总价值最大是多少呢?
|
||||
*
|
||||
* @author ehlxr
|
||||
* @since 2022-03-05 14:31.
|
||||
*/
|
||||
public class KnapSack {
|
||||
private final int[] weight = {2, 2, 4, 6, 3}; // 物品的重量
|
||||
private final int[] value = {3, 4, 8, 9, 6}; // 物品的价值
|
||||
private final int n = 5; // 物品个数
|
||||
private final int w = 9; // 背包承受的最大重量
|
||||
private int maxV = Integer.MIN_VALUE; // 结果放到 maxV 中
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println(knapsack3(new int[]{2, 2, 4, 6, 3}, new int[]{3, 4, 8, 9, 6}, 5, 9));
|
||||
// System.out.println(knapsack(new int[]{2, 2, 4, 6, 3}, new int[]{3, 4, 8, 9, 6}, 5, 9));
|
||||
}
|
||||
|
||||
/**
|
||||
* 动态规划方式
|
||||
*
|
||||
* @param weight 物品重量
|
||||
* @param value 物品的价值
|
||||
* @param n 物品个数
|
||||
* @param w 背包可承载重量
|
||||
* @return 最大价值
|
||||
*/
|
||||
// public static int knapsack(int[] weight, int[] value, int n, int w) {
|
||||
// int[][] dp = new int[][];
|
||||
// }
|
||||
|
||||
/**
|
||||
* 动态规划方式
|
||||
*
|
||||
* @param weight 物品重量
|
||||
* @param value 物品的价值
|
||||
* @param n 物品个数
|
||||
* @param w 背包可承载重量
|
||||
* @return 最大价值
|
||||
*/
|
||||
public static int knapsack3(int[] weight, int[] value, int n, int w) {
|
||||
int[][] states = new int[n][w + 1];
|
||||
for (int i = 0; i < n; ++i) { // 初始化 states,默认 -1
|
||||
for (int j = 0; j < w + 1; ++j) {
|
||||
states[i][j] = -1;
|
||||
}
|
||||
}
|
||||
states[0][0] = 0;
|
||||
if (weight[0] <= w) {
|
||||
states[0][weight[0]] = value[0];
|
||||
}
|
||||
for (int i = 1; i < n; ++i) { // 动态规划,状态转移
|
||||
for (int j = 0; j <= w; ++j) { // 不选择第 i 个物品
|
||||
if (states[i - 1][j] >= 0) {
|
||||
// 复制上一层状态
|
||||
states[i][j] = states[i - 1][j];
|
||||
}
|
||||
}
|
||||
// 下面的 j 表示重量
|
||||
for (int j = 0; j <= w - weight[i]; ++j) { // 选择第 i 个物品
|
||||
if (states[i - 1][j] >= 0) { // 表示上一层存在重量为 j 的状态
|
||||
int v = states[i - 1][j] + value[i]; // 上一层重量为 j 的价值 + i 物品的价值
|
||||
if (v > states[i][j + weight[i]]) { // states[i][j + weight[i]]:存储当前重量 j + 物品 i 的重量所在位置的价值
|
||||
states[i][j + weight[i]] = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 找出最大值
|
||||
int maxvalue = -1;
|
||||
for (int j = 0; j <= w; ++j) {
|
||||
if (states[n - 1][j] > maxvalue) {
|
||||
maxvalue = states[n - 1][j];
|
||||
}
|
||||
}
|
||||
return maxvalue;
|
||||
}
|
||||
|
||||
/**
|
||||
* 回溯方式
|
||||
*
|
||||
* @param i 第几个物品
|
||||
* @param cw 物品的重量
|
||||
* @param cv 物品的价值
|
||||
*/
|
||||
public void f(int i, int cw, int cv) { // 调用 f (0, 0, 0)
|
||||
if (cw == w || i == n) { //cw==w 表示装满了,i==n 表示物品都考察完了
|
||||
if (cv > maxV) {
|
||||
maxV = cv;
|
||||
}
|
||||
return;
|
||||
}
|
||||
f(i + 1, cw, cv); // 选择不装第 i 个物品
|
||||
if (cw + weight[i] <= w) {
|
||||
f(i + 1, cw + weight[i], cv + value[i]); // 选择装第 i 个物品
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2022 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.algorithm.dp;
|
||||
|
||||
/**
|
||||
* 假设我们有一个 n 乘以 n 的矩阵 w [n][n]。矩阵存储的都是正整数。棋子起始位置在左上角,终止位置在右下角。
|
||||
* 我们将棋子从左上角移动到右下角。每次只能向右或者向下移动一位。从左上角到右下角,会有很多不同的路径可以走。
|
||||
* 我们把每条路径经过的数字加起来看作路径的长度。那从左上角移动到右下角的最短路径长度是多少呢?
|
||||
*
|
||||
* @author ehlxr
|
||||
* @since 2022-03-05 16:46.
|
||||
*/
|
||||
public class MinDist {
|
||||
|
||||
private final int[][] matrix = {{1, 3, 5, 9}, {2, 1, 3, 4}, {5, 2, 6, 7}, {6, 8, 4, 3}};
|
||||
private final int[][] mem = new int[4][4];
|
||||
private int minDist = Integer.MAX_VALUE; // 全局变量或者成员变量
|
||||
|
||||
/**
|
||||
* 动态规划:状态转移表法
|
||||
*/
|
||||
public int minDistDP(int[][] matrix, int n) {
|
||||
int[][] states = new int[n][n];
|
||||
int sum = 0;
|
||||
for (int j = 0; j < n; ++j) { // 初始化states的第一行数据
|
||||
sum += matrix[0][j];
|
||||
states[0][j] = sum;
|
||||
}
|
||||
sum = 0;
|
||||
for (int i = 0; i < n; ++i) { // 初始化states的第一列数据
|
||||
sum += matrix[i][0];
|
||||
states[i][0] = sum;
|
||||
}
|
||||
for (int i = 1; i < n; ++i) {
|
||||
for (int j = 1; j < n; ++j) {
|
||||
states[i][j] = matrix[i][j] + Math.min(states[i][j - 1], states[i - 1][j]);
|
||||
}
|
||||
}
|
||||
return states[n - 1][n - 1];
|
||||
}
|
||||
|
||||
/**
|
||||
* 动态规划:状态转移方程法
|
||||
*/
|
||||
public int minDist(int i, int j) { // 调用minDist(n-1, n-1);
|
||||
if (i == 0 && j == 0) {
|
||||
return matrix[0][0];
|
||||
}
|
||||
// 备忘录,如果计算过,即有数字存在,则直接返回
|
||||
if (mem[i][j] > 0) {
|
||||
return mem[i][j];
|
||||
}
|
||||
int minLeft = Integer.MAX_VALUE;
|
||||
if (j - 1 >= 0) {
|
||||
minLeft = minDist(i, j - 1);
|
||||
}
|
||||
int minUp = Integer.MAX_VALUE;
|
||||
if (i - 1 >= 0) {
|
||||
minUp = minDist(i - 1, j);
|
||||
}
|
||||
|
||||
int currMinDist = matrix[i][j] + Math.min(minLeft, minUp);
|
||||
mem[i][j] = currMinDist;
|
||||
return currMinDist;
|
||||
}
|
||||
|
||||
/**
|
||||
* 回溯方式
|
||||
*/
|
||||
public void minDistBacktracing(int i, int j, int dist, int[][] w, int n) {
|
||||
// 到达了n-1, n-1这个位置了,这里看着有点奇怪哈,你自己举个例子看下
|
||||
if (i == n && j == n) {
|
||||
if (dist < minDist) {
|
||||
minDist = dist;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (i < n) { // 往下走,更新i=i+1, j=j
|
||||
minDistBacktracing(i + 1, j, dist + w[i][j], w, n);
|
||||
}
|
||||
if (j < n) { // 往右走,更新i=i, j=j+1
|
||||
minDistBacktracing(i, j + 1, dist + w[i][j], w, n);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2022 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.algorithm.linkedlist;
|
||||
|
||||
/**
|
||||
* @author ehlxr
|
||||
* @since 2022-05-01 14:18.
|
||||
*/
|
||||
public class FindKthFromEnd {
|
||||
public static void main(String[] args) {
|
||||
ListNode head = new ListNode(1);
|
||||
head.next = new ListNode(2);
|
||||
head.next.next = new ListNode(3);
|
||||
head.next.next.next = new ListNode(4);
|
||||
head.next.next.next.next = new ListNode(5);
|
||||
head.next.next.next.next.next = new ListNode(6);
|
||||
|
||||
System.out.println(head);
|
||||
|
||||
System.out.println(findKthFromEnd(head, 1));
|
||||
System.out.println(findKthFromEnd2(head, 1));
|
||||
}
|
||||
|
||||
public static ListNode findKthFromEnd(ListNode head, int k) {
|
||||
int n = 0;
|
||||
ListNode node = head;
|
||||
ListNode p = null;
|
||||
while (node != null) {
|
||||
if (p != null) {
|
||||
p = p.next;
|
||||
}
|
||||
|
||||
n++;
|
||||
if (n == k) {
|
||||
p = head;
|
||||
}
|
||||
|
||||
node = node.next;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
public static ListNode findKthFromEnd2(ListNode head, int k) {
|
||||
ListNode p = head;
|
||||
ListNode q = head;
|
||||
for (int i = 0; i < k; i++) {
|
||||
q = q.next;
|
||||
}
|
||||
while (q != null) {
|
||||
p = p.next;
|
||||
q = q.next;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2020 xrv <xrg@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.algorithm.linkedlist;
|
||||
|
||||
/**
|
||||
* @author ehlxr
|
||||
* @since 2022-04-15 08:41.
|
||||
*/
|
||||
public class Leecode21 {
|
||||
public static void main(String[] args) {
|
||||
ListNode list1 = new ListNode(1);
|
||||
ListNode list2 = new ListNode(2);
|
||||
ListNode list3 = new ListNode(4);
|
||||
list1.next = list2;
|
||||
list2.next = list3;
|
||||
ListNode list4 = new ListNode(1);
|
||||
ListNode list5 = new ListNode(3);
|
||||
ListNode list6 = new ListNode(4);
|
||||
list4.next = list5;
|
||||
list5.next = list6;
|
||||
ListNode list7 = mergeTwoLists(list1, list4);
|
||||
while (list7 != null) {
|
||||
System.out.println(list7.val);
|
||||
list7 = list7.next;
|
||||
}
|
||||
}
|
||||
|
||||
public static ListNode mergeTwoLists(ListNode list1, ListNode list2) {
|
||||
ListNode res = new ListNode();
|
||||
ListNode tmp = res;
|
||||
|
||||
while (list1 != null || list2 != null) {
|
||||
if (list1 == null) {
|
||||
tmp.next = list2;
|
||||
break;
|
||||
}
|
||||
if (list2 == null) {
|
||||
tmp.next = list1;
|
||||
break;
|
||||
}
|
||||
if (list1.val < list2.val) {
|
||||
tmp.next = list1;
|
||||
list1 = list1.next;
|
||||
} else {
|
||||
tmp.next = list2;
|
||||
list2 = list2.next;
|
||||
}
|
||||
tmp = tmp.next;
|
||||
}
|
||||
|
||||
return res.next;
|
||||
}
|
||||
|
||||
public static ListNode mergeTwoLists2(ListNode l1, ListNode l2) {
|
||||
// 虚拟头结点
|
||||
ListNode dummy = new ListNode(-1), p = dummy;
|
||||
ListNode p1 = l1, p2 = l2;
|
||||
|
||||
while (p1 != null && p2 != null) {
|
||||
// 比较 p1 和 p2 两个指针
|
||||
// 将值较小的的节点接到 p 指针
|
||||
if (p1.val > p2.val) {
|
||||
p.next = p2;
|
||||
p2 = p2.next;
|
||||
} else {
|
||||
p.next = p1;
|
||||
p1 = p1.next;
|
||||
}
|
||||
// p 指针不断前进
|
||||
p = p.next;
|
||||
}
|
||||
|
||||
if (p1 != null) {
|
||||
p.next = p1;
|
||||
}
|
||||
|
||||
if (p2 != null) {
|
||||
p.next = p2;
|
||||
}
|
||||
|
||||
return dummy.next;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2020 xrv <xrg@live.com>
|
||||
* Copyright © 2022 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -22,13 +22,11 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.leetcode;
|
||||
package io.github.ehlxr.algorithm.linkedlist;
|
||||
|
||||
/**
|
||||
* 链表结构
|
||||
*
|
||||
* @author ehlxr
|
||||
* @since 2021-02-27 21:09.
|
||||
* @since 2022-12-04 22:25.
|
||||
*/
|
||||
public class ListNode {
|
||||
int val;
|
||||
@@ -53,4 +51,4 @@ public class ListNode {
|
||||
", next=" + next +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2022 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.algorithm.linkedlist;
|
||||
|
||||
/**
|
||||
* 判断单链表是否是回文
|
||||
*
|
||||
* @author ehlxr
|
||||
* @since 2022-12-03 23:11.
|
||||
*/
|
||||
public class Palindrome {
|
||||
public static void main(String[] args) {
|
||||
ListNode head = new ListNode(1);
|
||||
head.next = new ListNode(2);
|
||||
head.next.next = new ListNode(3);
|
||||
head.next.next.next = new ListNode(2);
|
||||
head.next.next.next.next = new ListNode(1);
|
||||
System.out.println(head);
|
||||
System.out.println(isPalindrome(head));
|
||||
|
||||
head = new ListNode(1);
|
||||
head.next = new ListNode(2);
|
||||
head.next.next = new ListNode(3);
|
||||
head.next.next.next = new ListNode(3);
|
||||
head.next.next.next.next = new ListNode(2);
|
||||
head.next.next.next.next.next = new ListNode(1);
|
||||
System.out.println(head);
|
||||
System.out.println(isPalindrome(head));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* slow, fast 双指针,slow 前进一步,fast 前进两步,当 fast 到达链表尾部时,slow 处于链表中间
|
||||
* 与此同时反转链表前半部分(head 到中间节点部分)
|
||||
*/
|
||||
public static boolean isPalindrome(ListNode head) {
|
||||
if (head == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ListNode slow = head, fast = head, pre = null;
|
||||
while (fast != null && fast.next != null) {
|
||||
fast = fast.next.next;
|
||||
|
||||
ListNode tmp = slow.next;
|
||||
slow.next = pre;
|
||||
pre = slow;
|
||||
slow = tmp;
|
||||
// slow = slow.next;
|
||||
}
|
||||
if (fast != null) {
|
||||
// 节点个数为奇数
|
||||
slow = slow.next;
|
||||
}
|
||||
System.out.println("中间节点:" + slow);
|
||||
System.out.println("中位点反转:" + pre);
|
||||
|
||||
while (pre != null) {
|
||||
if (pre.val != slow.val) {
|
||||
return false;
|
||||
}
|
||||
pre = pre.next;
|
||||
slow = slow.next;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2020 xrv <xrg@live.com>
|
||||
* Copyright © 2022 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -22,42 +22,47 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.leetcode;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.PriorityQueue;
|
||||
package io.github.ehlxr.algorithm.linkedlist;
|
||||
|
||||
/**
|
||||
* @author ehlxr
|
||||
* @since 2020-10-20 17:54.
|
||||
* @since 2022-05-03 14:26.
|
||||
*/
|
||||
public class Solution5 {
|
||||
|
||||
public int findKthLargest(int[] nums, int k) {
|
||||
PriorityQueue<Integer> queue = new PriorityQueue<>();
|
||||
for (int val : nums) {
|
||||
queue.add(val);
|
||||
if (queue.size() > k) {
|
||||
queue.poll();
|
||||
}
|
||||
}
|
||||
return queue.peek();
|
||||
}
|
||||
|
||||
public class ReverseKGroup {
|
||||
public static void main(String[] args) {
|
||||
int[] arr = {4, 6, 8, 5, 9};
|
||||
// PriorityQueue<Integer> queue = new PriorityQueue<>();
|
||||
// for (int val : arr) {
|
||||
// queue.add(val);
|
||||
// }
|
||||
// System.out.println(Arrays.toString(queue.toArray()));
|
||||
//
|
||||
//
|
||||
// arr = new int[]{4, 6, 8, 5, 9};
|
||||
PriorityQueue<Integer> maxHeap = new PriorityQueue<>(arr.length, (o1, o2) -> o2 - o1);
|
||||
for (int val : arr) {
|
||||
maxHeap.add(val);
|
||||
}
|
||||
System.out.println(Arrays.toString(maxHeap.toArray()));
|
||||
ListNode head = new ListNode(1);
|
||||
head.next = new ListNode(2);
|
||||
head.next.next = new ListNode(3);
|
||||
head.next.next.next = new ListNode(4);
|
||||
head.next.next.next.next = new ListNode(5);
|
||||
System.out.println(head);
|
||||
System.out.println(reverseKGroup(head, 2));
|
||||
}
|
||||
|
||||
public static ListNode reverseKGroup(ListNode head, int k) {
|
||||
ListNode p = head;
|
||||
for (int i = 0; i < k; i++) {
|
||||
if (p == null) {
|
||||
return head;
|
||||
}
|
||||
p = p.next;
|
||||
}
|
||||
|
||||
ListNode r = reverseN(head, p);
|
||||
head.next = reverseKGroup(p, k);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
public static ListNode reverseN(ListNode head, ListNode n) {
|
||||
ListNode cur = head, pre = null;
|
||||
while (cur != n) {
|
||||
ListNode next = cur.next;
|
||||
cur.next = pre;
|
||||
pre = cur;
|
||||
cur = next;
|
||||
}
|
||||
return pre;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2022 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.algorithm.linkedlist;
|
||||
|
||||
/**
|
||||
* 反转单链表
|
||||
*
|
||||
* @author ehlxr
|
||||
* @since 2022-03-14 07:05.
|
||||
*/
|
||||
public class ReverseLinkedList {
|
||||
public static void main(String[] args) {
|
||||
ListNode ListNode5 = new ListNode(5, null);
|
||||
ListNode ListNode4 = new ListNode(4, ListNode5);
|
||||
ListNode ListNode3 = new ListNode(3, ListNode4);
|
||||
ListNode ListNode2 = new ListNode(2, ListNode3);
|
||||
ListNode head = new ListNode(1, ListNode2);
|
||||
|
||||
// ListNode reverse = reverse(root);
|
||||
// reverse.print();
|
||||
|
||||
// System.out.println(reverseToN(head, ListNode3));
|
||||
// System.out.println(reverseToN(head, 2));
|
||||
System.out.println(reverseFm2N(head, 2, 4));
|
||||
|
||||
}
|
||||
|
||||
public static ListNode reverseToN(ListNode root, ListNode n) {
|
||||
ListNode pre = null, cur = root, tmp = root;
|
||||
while (cur != n) {
|
||||
tmp = cur.next;
|
||||
|
||||
cur.next = pre;
|
||||
pre = cur;
|
||||
cur = tmp;
|
||||
}
|
||||
|
||||
return pre;
|
||||
|
||||
}
|
||||
|
||||
static ListNode next = null;
|
||||
|
||||
public static ListNode reverseToN(ListNode root, int n) {
|
||||
if (n == 1) {
|
||||
next = root.next;
|
||||
return root;
|
||||
}
|
||||
|
||||
ListNode h = reverseToN(root.next, n - 1);
|
||||
root.next.next = root;
|
||||
root.next = next;
|
||||
return h;
|
||||
}
|
||||
|
||||
public static ListNode reverseFm2N(ListNode root, int m, int n) {
|
||||
if (m == 1) {
|
||||
return reverseToN(root, n);
|
||||
}
|
||||
root.next = reverseFm2N(root.next, m - 1, n - 1);
|
||||
return root;
|
||||
}
|
||||
|
||||
public static ListNode reverse(ListNode root) {
|
||||
|
||||
ListNode pre = null;
|
||||
ListNode cur = root;
|
||||
while (cur != null) {
|
||||
ListNode tmp = cur.next;
|
||||
|
||||
cur.next = pre;
|
||||
pre = cur;
|
||||
cur = tmp;
|
||||
// tmp = cur.next;
|
||||
}
|
||||
|
||||
return pre;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2020 xrv <xrg@live.com>
|
||||
* Copyright © 2020 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -22,33 +22,45 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.test;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
package io.github.ehlxr.algorithm.match;
|
||||
|
||||
/**
|
||||
* 字符串匹配:暴力匹配
|
||||
*
|
||||
* @author ehlxr
|
||||
* @date 2016/12/22
|
||||
* @since 2022-03-12 13:36.
|
||||
*/
|
||||
//@SuppressWarnings({"AlibabaRemoveCommentedCode", "Convert2Lambda", "UnnecessaryLocalVariable"})
|
||||
public class ThreadPoolExecutorTest {
|
||||
public class BruteForce {
|
||||
public static void main(String[] args) {
|
||||
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
final int index = i;
|
||||
//try {
|
||||
// Thread.sleep(index * 1000);
|
||||
//} catch (InterruptedException e) {
|
||||
// e.printStackTrace();
|
||||
//}
|
||||
cachedThreadPool.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
//System.out.println(index);
|
||||
System.out.println("Thread: " + Thread.currentThread().getName());
|
||||
String s = "abdcfhjudfadf";
|
||||
String p = "dcf";
|
||||
|
||||
System.out.println(bf(s, p));
|
||||
}
|
||||
|
||||
public static int bf(String s, String p) {
|
||||
int m = s.length();
|
||||
int n = p.length();
|
||||
|
||||
for (int i = 0; i <= m - n; i++) {
|
||||
int j = 0;
|
||||
for (; j < n; j++) {
|
||||
// if (s.charAt(i) == p.charAt(j)) {
|
||||
// i++;
|
||||
// } else {
|
||||
// break;
|
||||
// }
|
||||
// 如果主串与模式串不匹配,则主串向右移动一个字符,模式串从头开始匹配
|
||||
if (s.charAt(i + j) != p.charAt(j)) {
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
if (j == n) {
|
||||
// return i - n;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2022 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.algorithm.match;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* 字符串匹配算法 KPM
|
||||
*
|
||||
* @author ehlxr
|
||||
* @since 2022-03-13 10:06.
|
||||
*/
|
||||
public class Kmp {
|
||||
public static void main(String[] args) {
|
||||
String s = "bacbababaabcbab";
|
||||
String p = "abab";
|
||||
|
||||
System.out.println(Arrays.toString(getNexts(p)));
|
||||
System.out.println(kmp(s, p));
|
||||
}
|
||||
|
||||
public static int kmp(String s, String p) {
|
||||
char[] scs = s.toCharArray();
|
||||
char[] pcs = p.toCharArray();
|
||||
|
||||
int m = s.length();
|
||||
int n = p.length();
|
||||
|
||||
int[] next = getNexts(p);
|
||||
|
||||
for (int i = 0; i <= m - n; i++) {
|
||||
int j = 0;
|
||||
// while (j < n) {
|
||||
// if (scs[i] == pcs[j]) {
|
||||
// i++;
|
||||
// j++;
|
||||
// } else {
|
||||
// // 当模式串与主串不匹配时,如果**不匹配字符**对应模式串下标大于 j > 0 (非首个模式串字符),
|
||||
// // 并且此字符前一个字符对应字符串部分匹配表中的值 next[j - 1] 也大于 0,
|
||||
// // j - next[j - 1] 即模式串为后移的位数,等价于 j 置为 next[j - 1]
|
||||
// if (j > 0 && next[j - 1] > 0) {
|
||||
// j = next[j - 1];
|
||||
// } else {
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// if (j == n) {
|
||||
// return i - n;
|
||||
// }
|
||||
|
||||
for (; j < n; j++) {
|
||||
if (scs[i + j] != pcs[j]) {
|
||||
// 暴力匹配算法当模式串和主串不匹配时,主串匹配下标 +1,模式串匹配下标置为 0,
|
||||
// KMP 算法优化点在于将模式串下标置为不匹配字符前一个字符对应 next 数组的值
|
||||
if (j > 0 && next[j - 1] > 0) {
|
||||
// 当模式串与主串不匹配时,如果**不匹配字符**对应模式串下标大于 j > 0 (非首个模式串字符),
|
||||
// 并且此字符前一个字符对应字符串部分匹配表中的值 next[j - 1] 也大于 0,
|
||||
// j - next[j - 1] 即模式串为后移的位数,等价于 j 置为 next[j - 1]
|
||||
j = next[j - 1];
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (j == n) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
private static int[] getNexts(String p) {
|
||||
int m = p.length();
|
||||
char[] b = p.toCharArray();
|
||||
int[] next = new int[m];
|
||||
|
||||
next[0] = 0;
|
||||
int k = 0; // 表示前后缀相匹配的最大长度
|
||||
|
||||
// 根据已知 next 数组的前 i-1 位推测第 i 位
|
||||
for (int i = 1; i < m; ++i) {
|
||||
while (k != 0 && b[k] != b[i]) {
|
||||
// k 为 b[0, i) 子串最大匹配前后缀长度
|
||||
// b[0, k) 为 b[0, i) 子串最大匹配前缀子串
|
||||
|
||||
// 若:1、b[k] != b[i],则求 b[0, i] 子串最大匹配前后缀长度问题
|
||||
// 转换成了求 b[0, k) 子串最大匹配前后缀长度问题
|
||||
// 循环直到 b[k] == b[i] (下一步处理) 或 k == 0
|
||||
k = next[k];
|
||||
}
|
||||
// 若:2、b[k] == b[i],则 b[0, i] 子串最大匹配前后缀长度为 k + 1
|
||||
if (b[k] == b[i]) {
|
||||
++k;
|
||||
}
|
||||
next[i] = k;
|
||||
}
|
||||
return next;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,207 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2022 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.algorithm.search;
|
||||
|
||||
/**
|
||||
* @author ehlxr
|
||||
* @since 2022-01-01 17:06.
|
||||
*/
|
||||
public class BinarySearch {
|
||||
public static void main(String[] args) {
|
||||
int[] a = new int[]{1, 3, 5, 6, 7, 8, 9};
|
||||
System.out.println(search(a, a.length, 3));
|
||||
System.out.println(searchRec(a, a.length, 3));
|
||||
a = new int[]{1, 2, 2, 2, 2, 5, 6, 7, 8, 9};
|
||||
System.out.println(searchFirst(a, a.length, 2));
|
||||
a = new int[]{1, 3, 4, 5, 6, 8, 8, 8, 9};
|
||||
System.out.println(searchLast(a, a.length, 8));
|
||||
a = new int[]{1, 2, 2, 3, 4, 5, 6, 7, 8, 8, 9};
|
||||
System.out.println(searchFirstGreater(a, a.length, 7));
|
||||
a = new int[]{1, 2, 3, 4, 5, 6, 8, 9};
|
||||
System.out.println(searchLastLess(a, a.length, 7));
|
||||
}
|
||||
|
||||
/**
|
||||
* 非递归二分查找
|
||||
*
|
||||
* @param a 要查找的数组
|
||||
* @param n 数组的长度
|
||||
* @param v 要查找的值
|
||||
* @return 要查找值在数组中的索引
|
||||
*/
|
||||
public static int search(int[] a, int n, int v) {
|
||||
int low = 0;
|
||||
int high = n - 1;
|
||||
while (low <= high) {
|
||||
int mid = low + ((high - low) >> 1);
|
||||
if (a[mid] == v) {
|
||||
return mid;
|
||||
} else if (a[mid] < v) {
|
||||
low = mid + 1;
|
||||
} else {
|
||||
high = mid - 1;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归二分查找
|
||||
*
|
||||
* @param a 要查找的数组
|
||||
* @param n 数组的长度
|
||||
* @param v 要查找的值
|
||||
* @return 要查找值在数组中的索引
|
||||
*/
|
||||
public static int searchRec(int[] a, int n, int v) {
|
||||
return searchRec(a, 0, n - 1, v);
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归二分查找
|
||||
*/
|
||||
public static int searchRec(int[] a, int low, int high, int v) {
|
||||
if (low > high) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int mid = low + ((high - low) >> 1);
|
||||
if (a[mid] == v) {
|
||||
return mid;
|
||||
} else if (a[mid] < v) {
|
||||
return searchRec(a, mid + 1, high, v);
|
||||
} else {
|
||||
return searchRec(a, low, mid - 1, v);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找第一个值等于给定值的元素
|
||||
*
|
||||
* @param a 要查找的数组
|
||||
* @param n 数组的长度
|
||||
* @param v 要查找的值
|
||||
* @return 要查找值在数组中的索引
|
||||
*/
|
||||
public static int searchFirst(int[] a, int n, int v) {
|
||||
int low = 0;
|
||||
int high = n - 1;
|
||||
while (low <= high) {
|
||||
int mid = low + ((high - low) >> 1);
|
||||
if (a[mid] == v) {
|
||||
if (mid == 0 || a[mid - 1] != v) {
|
||||
return mid;
|
||||
} else {
|
||||
high = mid - 1;
|
||||
}
|
||||
} else if (a[mid] < v) {
|
||||
low = mid + 1;
|
||||
} else {
|
||||
high = mid - 1;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找最后一个值等于给定值的元素
|
||||
*
|
||||
* @param a 要查找的数组
|
||||
* @param n 数组的长度
|
||||
* @param v 要查找的值
|
||||
* @return 要查找值在数组中的索引
|
||||
*/
|
||||
public static int searchLast(int[] a, int n, int v) {
|
||||
int low = 0;
|
||||
int high = n - 1;
|
||||
while (low <= high) {
|
||||
int mid = low + ((high - low) >> 1);
|
||||
if (a[mid] == v) {
|
||||
if (mid == n - 1 || a[mid + 1] != v) {
|
||||
return mid;
|
||||
} else {
|
||||
low = mid + 1;
|
||||
}
|
||||
} else if (a[mid] < v) {
|
||||
low = mid + 1;
|
||||
} else {
|
||||
high = mid - 1;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找第一个大于等于给定值的元素
|
||||
*
|
||||
* @param a 要查找的数组
|
||||
* @param n 数组的长度
|
||||
* @param v 要查找的值
|
||||
* @return 要查找值在数组中的索引
|
||||
*/
|
||||
public static int searchFirstGreater(int[] a, int n, int v) {
|
||||
int low = 0;
|
||||
int high = n - 1;
|
||||
while (low <= high) {
|
||||
int mid = low + ((high - low) >> 1);
|
||||
if (a[mid] < v) {
|
||||
low = mid + 1;
|
||||
} else {
|
||||
if (mid == 0 || a[mid - 1] < v) {
|
||||
return mid;
|
||||
} else {
|
||||
high = mid - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找最后一个小于等于给定值的元素
|
||||
*
|
||||
* @param a 要查找的数组
|
||||
* @param n 数组的长度
|
||||
* @param v 要查找的值
|
||||
* @return 要查找值在数组中的索引
|
||||
*/
|
||||
public static int searchLastLess(int[] a, int n, int v) {
|
||||
int low = 0;
|
||||
int high = n - 1;
|
||||
while (low <= high) {
|
||||
int mid = low + ((high - low) >> 1);
|
||||
if (a[mid] > v) {
|
||||
high = mid - 1;
|
||||
} else {
|
||||
if (mid == n - 1 || a[mid + 1] > v) {
|
||||
return mid;
|
||||
} else {
|
||||
low = mid + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2021 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.algorithm.sort;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @author ehlxr
|
||||
* @since 2021-12-27 19:06.
|
||||
*/
|
||||
public class MergeSort {
|
||||
public static void main(String[] args) {
|
||||
int[] arrs = new int[]{3, 2, 5, 7, 1, 9};
|
||||
System.out.println(Arrays.toString(sort(arrs)));
|
||||
System.out.println(Arrays.toString(sort2(arrs)));
|
||||
}
|
||||
|
||||
public static int[] sort(int[] arrs) {
|
||||
if (arrs.length <= 1) {
|
||||
return arrs;
|
||||
}
|
||||
int[] a1 = sort(Arrays.copyOfRange(arrs, 0, arrs.length / 2));
|
||||
int[] a2 = sort(Arrays.copyOfRange(arrs, arrs.length / 2, arrs.length));
|
||||
|
||||
return merge(a1, a2);
|
||||
}
|
||||
|
||||
public static int[] merge(int[] a1, int[] a2) {
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
int[] result = new int[a1.length + a2.length];
|
||||
int k = 0;
|
||||
while (i < a1.length || j < a2.length) {
|
||||
int temp;
|
||||
if (i >= a1.length) {
|
||||
temp = a2[j++];
|
||||
} else if (j >= a2.length) {
|
||||
temp = a1[i++];
|
||||
} else if (a1[i] <= a2[j]) {// 为了保证算法的稳定性,如果 a1、a2 有相同的元素,保证 a1 的元素在前面
|
||||
temp = a1[i++];
|
||||
} else {
|
||||
temp = a2[j++];
|
||||
}
|
||||
|
||||
result[k] = temp;
|
||||
k++;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public static int[] sort2(int[] a) {
|
||||
if (a == null || a.length <= 1) {
|
||||
return a;
|
||||
}
|
||||
|
||||
return merge2(sort2(Arrays.copyOfRange(a, 0, a.length / 2)),
|
||||
sort2(Arrays.copyOfRange(a, a.length / 2, a.length)));
|
||||
}
|
||||
|
||||
public static int[] merge2(int[] a, int[] b) {
|
||||
int[] r = new int[a.length + b.length];
|
||||
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
int m = 0;
|
||||
while (i < a.length || j < b.length) {
|
||||
if (i >= a.length) {
|
||||
r[m++] = b[j++];
|
||||
continue;
|
||||
}
|
||||
|
||||
if (j >= b.length) {
|
||||
r[m++] = a[i++];
|
||||
continue;
|
||||
}
|
||||
|
||||
if (a[i] < b[j]) {
|
||||
r[m++] = a[i++];
|
||||
} else {
|
||||
r[m++] = b[j++];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return r;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2021 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.algorithm.sort;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @author ehlxr
|
||||
* @since 2021-12-28 19:57.
|
||||
*/
|
||||
public class QuickSort {
|
||||
public static void main(String[] args) {
|
||||
int[] a = new int[]{3, 9, 5, 7, 1, 2};
|
||||
sort2(a, 0, a.length - 1);
|
||||
|
||||
System.out.println(Arrays.toString(a));
|
||||
}
|
||||
|
||||
public static void sort(int[] a, int p, int r) {
|
||||
if (p >= r) {
|
||||
return;
|
||||
}
|
||||
|
||||
int q = partition(a, p, r);
|
||||
|
||||
sort(a, p, q - 1);
|
||||
sort(a, q + 1, r);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取分区点
|
||||
* <p>
|
||||
* 图示:https://cdn.jsdelivr.net/gh/0vo/oss/images/quick_sort.jpg
|
||||
* <p>
|
||||
* 通过游标 i 把 a[p...r] 分成两部分。
|
||||
* a[p...i-1] 的元素都是小于 pivot 的,我们暂且叫它 “已处理区间”,a[i...r] 是 “未处理区间”。
|
||||
* 我们每次都从未处理的区间 a[i...r] 中取一个元素 a[j],与 pivot 对比,
|
||||
* 如果小于 pivot,则将其加入到已处理区间的尾部,也就是 a[i] 的位置
|
||||
* <p>
|
||||
* 只需要将 a[i] 与 a[j] 交换,就可以在 O(1) 时间复杂度内将 a[j] 放到下标为 i 的位置。
|
||||
*/
|
||||
public static int partition(int[] a, int p, int r) {
|
||||
int i = p;
|
||||
int pivot = a[r];
|
||||
for (int j = p; j < r; j++) {
|
||||
if (a[j] < pivot) {
|
||||
swap(a, i++, j);
|
||||
}
|
||||
}
|
||||
|
||||
swap(a, i, r);
|
||||
System.out.println("i=" + i + " " + Arrays.toString(a));
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
public static void swap(int[] a, int i, int j) {
|
||||
if (i == j) {
|
||||
return;
|
||||
}
|
||||
int temp = a[i];
|
||||
a[i] = a[j];
|
||||
a[j] = temp;
|
||||
}
|
||||
|
||||
public static void sort2(int[] a, int l, int r) {
|
||||
if (a == null || l >= r) {
|
||||
return;
|
||||
}
|
||||
|
||||
int i = l, j = r;
|
||||
int p = l; // 选择最左边的元素为 pivot
|
||||
while (l < r) {
|
||||
// 如果选择 p = l 必须先从右边找到小于 a[p] 的第一个元素
|
||||
while (l < r && a[r] >= a[p]) {
|
||||
r--;
|
||||
}
|
||||
swap(a, r, p);
|
||||
p = r;
|
||||
|
||||
// 从左边找到大于 a[p] 的第一个元素
|
||||
while (l < r && a[l] <= a[p]) {
|
||||
l++;
|
||||
}
|
||||
swap(a, l, p);
|
||||
p = l;
|
||||
System.out.println(Arrays.toString(a));
|
||||
|
||||
}
|
||||
|
||||
sort2(a, i, p - 1);
|
||||
sort2(a, p + 1, j);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2020 xrv <xrg@live.com>
|
||||
* Copyright © 2021 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -22,10 +22,7 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package io.github.ehlxr.annotation;
|
||||
package io.github.ehlxr.annotations;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
@@ -33,11 +30,12 @@ import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* @author ehlxr
|
||||
* 请求日志排除注解
|
||||
*
|
||||
* @author ehlxr
|
||||
* @since 2021-08-18 14:03.
|
||||
*/
|
||||
@Target(ElementType.PACKAGE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@interface PkgAnnotation {
|
||||
|
||||
@Target(ElementType.METHOD)
|
||||
public @interface NoRequestLog {
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2020 xrv <xrg@live.com>
|
||||
* Copyright © 2021 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -22,28 +22,26 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.common;
|
||||
|
||||
/**
|
||||
* @author ehlxr
|
||||
*/
|
||||
/**
|
||||
* @author ehlxr
|
||||
* 常量
|
||||
*
|
||||
* @author ehlxr
|
||||
* @since 2021-08-29 18:32.
|
||||
*/
|
||||
@PkgAnnotation
|
||||
package io.github.ehlxr.annotation;
|
||||
public interface Constant {
|
||||
/**
|
||||
* traceID
|
||||
*/
|
||||
String LOG_TRACE_ID = "logTraceId";
|
||||
|
||||
/**
|
||||
* 包内方法
|
||||
*/
|
||||
class MyPackageMethod {
|
||||
public void myPackageMethod() {
|
||||
System.out.println("MyPackageMethod...");
|
||||
}
|
||||
/**
|
||||
* 接口请求开始时间戳
|
||||
*/
|
||||
String REQUEST_START_TIME = "request_start_time";
|
||||
|
||||
int SUCCESS_CODE = 0;
|
||||
|
||||
String SUCCESS_MSG = "success";
|
||||
}
|
||||
|
||||
/**
|
||||
* 包内常量
|
||||
*/
|
||||
class MyPackageConst {
|
||||
static final java.lang.String PACKAGE_STRING = "myPackageConst";
|
||||
}
|
||||
@@ -1,28 +1,4 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2020 xrv <xrg@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.utils;
|
||||
package io.github.ehlxr.common;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
@@ -30,6 +6,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.base.Throwables;
|
||||
import io.github.ehlxr.enums.CodeEnum;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.text.SimpleDateFormat;
|
||||
@@ -67,7 +44,7 @@ public class Result<T> implements Serializable {
|
||||
}
|
||||
|
||||
public static <T> Result<T> success(T data, String message) {
|
||||
return new Result<>(Code.SUCCESSFUL.getCode(), data, message);
|
||||
return new Result<>(CodeEnum.SUCCESSFUL.getCode(), data, message);
|
||||
}
|
||||
|
||||
public static <T> Result<T> success(T data) {
|
||||
@@ -82,35 +59,35 @@ public class Result<T> implements Serializable {
|
||||
return new Result<>(c, d, m);
|
||||
}
|
||||
|
||||
public static <T> Result<T> of(Code c, T d, String m) {
|
||||
public static <T> Result<T> of(CodeEnum c, T d, String m) {
|
||||
return new Result<>(c.getCode(), d, m);
|
||||
}
|
||||
|
||||
public static <T> Result<T> fail(Code code, String message) {
|
||||
return of(code.getCode(), null, message);
|
||||
public static <T> Result<T> fail(CodeEnum codeEnum, String message) {
|
||||
return of(codeEnum.getCode(), null, message);
|
||||
}
|
||||
|
||||
public static <T> Result<T> fail(Code code) {
|
||||
return fail(code, code.getMessage());
|
||||
public static <T> Result<T> fail(CodeEnum codeEnum) {
|
||||
return fail(codeEnum, codeEnum.getMessage());
|
||||
}
|
||||
|
||||
public static <T> Result<T> fail(Throwable e) {
|
||||
// 格式化异常消息,防止输出异常栈信息到结果集
|
||||
e = Throwables.getRootCause(e);
|
||||
return of(Code.UNKNOWN_EXCEPTION.getCode(), null, String.format("%s: %s", e.getClass().getSimpleName(), e.getMessage()));
|
||||
return of(CodeEnum.UNKNOWN_EXCEPTION.getCode(), null, String.format("%s: %s", e.getClass().getSimpleName(), e.getMessage()));
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
// return Strings.isNullOrEmpty(m) ? c.getMessage() : m;
|
||||
if (Strings.isNullOrEmpty(message)) {
|
||||
Code code;
|
||||
CodeEnum codeEnum;
|
||||
try {
|
||||
code = Code.code(this.code);
|
||||
codeEnum = CodeEnum.code(this.code);
|
||||
} catch (Exception e) {
|
||||
return message;
|
||||
}
|
||||
|
||||
return Objects.isNull(code) ? "" : code.getMessage();
|
||||
return Objects.isNull(codeEnum) ? "" : codeEnum.getMessage();
|
||||
}
|
||||
return message;
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2021 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
||||
|
||||
/**
|
||||
* @author ehlxr
|
||||
* @since 2021-08-29 18:32.
|
||||
*/
|
||||
@Configuration
|
||||
public class RedisTemplateConfig {
|
||||
@Bean(name = "redisTemplate")
|
||||
public RedisTemplate<String, String> getRedisTemplate(RedisConnectionFactory factory) {
|
||||
return buildRedisTemplateByString(factory);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建 redisTemplate 使用 string序列化
|
||||
*/
|
||||
public RedisTemplate<String, String> buildRedisTemplateByString(RedisConnectionFactory factory) {
|
||||
RedisTemplate<String, String> redisTemplate = new RedisTemplate<>();
|
||||
redisTemplate.setConnectionFactory(factory);
|
||||
redisTemplate.setKeySerializer(new StringRedisSerializer());
|
||||
redisTemplate.setValueSerializer(new StringRedisSerializer());
|
||||
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
|
||||
redisTemplate.setHashValueSerializer(new StringRedisSerializer());
|
||||
return redisTemplate;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2020 xrv <xrg@live.com>
|
||||
* Copyright © 2021 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -22,35 +22,51 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.proxy;
|
||||
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
package io.github.ehlxr.datastructure;
|
||||
|
||||
/**
|
||||
* 链表节点数据结构
|
||||
*
|
||||
* @author ehlxr
|
||||
* @since 2019-06-28.
|
||||
* @since 2021-12-23 14:41.
|
||||
*/
|
||||
public class MyInvocationHandler implements InvocationHandler {
|
||||
private final Bird bird;
|
||||
public class Node<T> {
|
||||
private T val;
|
||||
private Node<T> next;
|
||||
|
||||
public MyInvocationHandler(Bird bird) {
|
||||
this.bird = bird;
|
||||
public Node(T val, Node<T> next) {
|
||||
this.val = val;
|
||||
this.next = next;
|
||||
}
|
||||
|
||||
public T getVal() {
|
||||
return val;
|
||||
}
|
||||
|
||||
public void setVal(T val) {
|
||||
this.val = val;
|
||||
}
|
||||
|
||||
public Node<T> getNext() {
|
||||
return next;
|
||||
}
|
||||
|
||||
public void setNext(Node<T> next) {
|
||||
this.next = next;
|
||||
}
|
||||
|
||||
public void print() {
|
||||
Node<T> n = this;
|
||||
while (n != null) {
|
||||
System.out.printf("%s -> ", n.getVal());
|
||||
n = n.getNext();
|
||||
}
|
||||
System.out.print("null");
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invoke(Object proxy, Method method, Object[] args) {
|
||||
long start = System.currentTimeMillis();
|
||||
|
||||
try {
|
||||
method.invoke(bird, args);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
long end = System.currentTimeMillis();
|
||||
System.out.println("Fly time = " + (end - start));
|
||||
return null;
|
||||
public String toString() {
|
||||
return "Node{" + val + '}';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2021 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.datastructure.linkedlist;
|
||||
|
||||
import io.github.ehlxr.datastructure.Node;
|
||||
|
||||
/**
|
||||
* 反转链表
|
||||
*
|
||||
* @author ehlxr
|
||||
* @since 2021-12-23 14:40.
|
||||
*/
|
||||
public class ReverseLinkedList<T> {
|
||||
public static void main(String[] args) {
|
||||
ReverseLinkedList<Integer> reverseLinkedList = new ReverseLinkedList<>();
|
||||
Node<Integer> n5 = new Node<>(5, null);
|
||||
Node<Integer> n4 = new Node<>(4, n5);
|
||||
Node<Integer> n3 = new Node<>(3, n4);
|
||||
Node<Integer> n2 = new Node<>(2, n3);
|
||||
Node<Integer> n1 = new Node<>(1, n2);
|
||||
Node<Integer> head = new Node<>(0, n1);
|
||||
|
||||
head.print();
|
||||
|
||||
System.out.println("-------------");
|
||||
// head = reverse(head);
|
||||
head = reverseLinkedList.reverse2(head);
|
||||
// head = reverse3(head, null);
|
||||
head.print();
|
||||
}
|
||||
|
||||
|
||||
// 循环方式
|
||||
public Node<T> reverse(Node<T> head) {
|
||||
if (head == null || head.getNext() == null) {
|
||||
return head;
|
||||
}
|
||||
Node<T> pre = null;
|
||||
|
||||
Node<T> cur = head;
|
||||
while (cur != null) {
|
||||
Node<T> next = cur.getNext();
|
||||
cur.setNext(pre);
|
||||
pre = cur;
|
||||
|
||||
cur = next;
|
||||
}
|
||||
|
||||
return pre;
|
||||
}
|
||||
|
||||
// 递归一
|
||||
public Node<T> reverse2(Node<T> head) {
|
||||
if (head == null || head.getNext() == null) {
|
||||
return head;
|
||||
}
|
||||
|
||||
Node<T> next = head.getNext();
|
||||
Node<T> node = reverse2(next);
|
||||
|
||||
head.getNext().setNext(head);
|
||||
head.setNext(null);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
// 递归二
|
||||
public Node<T> reverse3(Node<T> head, Node<T> pre) {
|
||||
if (head == null) {
|
||||
return pre;
|
||||
}
|
||||
|
||||
Node<T> next = head.getNext();
|
||||
Node<T> node = reverse3(next, head);
|
||||
|
||||
head.setNext(pre);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2020 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.datastructure.queue;
|
||||
|
||||
/**
|
||||
* 数组实现循环队列
|
||||
* <p>
|
||||
* 一般情况下只需要 tail + 1 == head 即可判定队列已满,结合特殊情况(head == 0,tail == n - 1)
|
||||
* 可使用公式 (tail + 1) % size == head 判定队列已满,head == tail 判断队列为空,
|
||||
* 但这种公式判断循环队列会浪费一个数组的存储空间。
|
||||
* <p>
|
||||
* 另也可使用一个变量 n 记录当前队列中的数量(入队 +1,出队 -1),当 head == tail 时,
|
||||
* 如果 n == size,则队列已满,如果 n == 0 则队列为空。
|
||||
*
|
||||
* @author ehlxr
|
||||
* @since 2021-12-25 21:01.
|
||||
*/
|
||||
public class CircularQueue {
|
||||
private final Integer[] data;
|
||||
private int head = 0;
|
||||
private int tail = 0;
|
||||
private final int size;
|
||||
|
||||
public CircularQueue(int size) {
|
||||
data = new Integer[size];
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
CircularQueue queue = new CircularQueue(5);
|
||||
|
||||
// 循环队列会浪费一个数组的存储空间。队列容量为 5,入队 5 个最后一个失败
|
||||
for (int i = 0; i < 5; i++) {
|
||||
System.out.println(queue.enqueue(i));
|
||||
}
|
||||
|
||||
// 出队 2 个,然后还可以入队 2 个
|
||||
for (int i = 0; i < 2; i++) {
|
||||
System.out.println(queue.dequeue());
|
||||
}
|
||||
System.out.println(queue.enqueue(7));
|
||||
System.out.println(queue.enqueue(8));
|
||||
System.out.println(queue.enqueue(9));
|
||||
|
||||
// 出队 6 个,最后一个失败
|
||||
for (int i = 0; i < 6; i++) {
|
||||
System.out.println(queue.dequeue());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 入队(从队尾添加元素)
|
||||
*/
|
||||
public boolean enqueue(Integer item) {
|
||||
// 判断队列是否已满
|
||||
if ((tail + 1) % size == head) {
|
||||
return false;
|
||||
}
|
||||
data[tail] = item;
|
||||
tail = (tail + 1) % size;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 出队(从队首取出元素)
|
||||
*/
|
||||
public Integer dequeue() {
|
||||
// 判断队列是否为空
|
||||
if (head == tail) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Integer no = data[head];
|
||||
head = (head + 1) % size;
|
||||
|
||||
return no;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2021 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.datastructure.queue;
|
||||
|
||||
/**
|
||||
* 数组实现动态扩容队列
|
||||
*
|
||||
* @author ehlxr
|
||||
* @since 2021-12-25 15:19.
|
||||
*/
|
||||
public class DynamicArrayQueue {
|
||||
private final String[] data;
|
||||
private final int size;
|
||||
private int head = 0;
|
||||
private int tail = 0;
|
||||
|
||||
public DynamicArrayQueue(int size) {
|
||||
data = new String[size];
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
DynamicArrayQueue queue = new DynamicArrayQueue(5);
|
||||
|
||||
// 队列容量为 5,入队 6 个最后一个失败
|
||||
for (int i = 0; i < 6; i++) {
|
||||
System.out.println(queue.enqueue("" + i));
|
||||
}
|
||||
|
||||
// 出队 2 个,然后还可以入队 2 个
|
||||
for (int i = 0; i < 2; i++) {
|
||||
System.out.println(queue.dequeue());
|
||||
}
|
||||
System.out.println(queue.enqueue("a"));
|
||||
System.out.println(queue.enqueue("b"));
|
||||
System.out.println(queue.enqueue("c"));
|
||||
|
||||
// 出队 6 个,最后一个失败
|
||||
for (int i = 0; i < 6; i++) {
|
||||
System.out.println(queue.dequeue());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 入队(从队尾添加元素)
|
||||
*/
|
||||
public boolean enqueue(String item) {
|
||||
// 判断队列是否已满
|
||||
if (tail == size) {
|
||||
if (head == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 如果 tail == size,而 head != 0,0 与 head 之间还有空位,向前移动 head 与 tail 之间的数据
|
||||
// for (int i = head; i < tail; i++) {
|
||||
// data[i - head] = data[i];
|
||||
// }
|
||||
if (tail - head >= 0) {
|
||||
System.arraycopy(data, head, data, 0, tail - head);
|
||||
}
|
||||
|
||||
tail -= head;
|
||||
head = 0;
|
||||
}
|
||||
|
||||
data[tail++] = item;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 出队(从队首取出元素)
|
||||
*/
|
||||
public String dequeue() {
|
||||
// 判断队列是否为空
|
||||
if (head == tail) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return data[head++];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2021 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.datastructure.queue;
|
||||
|
||||
import io.github.ehlxr.datastructure.Node;
|
||||
|
||||
/**
|
||||
* 基于链表实现的队列
|
||||
* <p>
|
||||
* 入队时间复杂度 O(n)
|
||||
*
|
||||
* @author ehlxr
|
||||
* @since 2021-12-25 16:02.
|
||||
*/
|
||||
public class LinkedListQueue<T> {
|
||||
private Node<T> head;
|
||||
|
||||
public static void main(String[] args) {
|
||||
LinkedListQueue<Integer> queue = new LinkedListQueue<>();
|
||||
for (int i = 0; i < 6; i++) {
|
||||
System.out.println(queue.enqueue(i));
|
||||
}
|
||||
|
||||
for (int i = 0; i < 6; i++) {
|
||||
queue.getData().print();
|
||||
System.out.println(queue.dequeue());
|
||||
}
|
||||
|
||||
System.out.println(queue.dequeue());
|
||||
}
|
||||
|
||||
/**
|
||||
* 入队(从队尾添加元素)
|
||||
* 时间复杂度 O(n)
|
||||
*/
|
||||
public boolean enqueue(T item) {
|
||||
Node<T> node = new Node<T>(item, null);
|
||||
if (head == null) {
|
||||
head = node;
|
||||
return true;
|
||||
}
|
||||
|
||||
// 找到队尾
|
||||
Node<T> tail = head;
|
||||
while (tail.getNext() != null) {
|
||||
tail = tail.getNext();
|
||||
}
|
||||
|
||||
tail.setNext(node);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 出队(从队首取出元素)
|
||||
*/
|
||||
public T dequeue() {
|
||||
if (head == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
T val = head.getVal();
|
||||
head = head.getNext();
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
public Node<T> getData() {
|
||||
return head;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2021 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.datastructure.queue;
|
||||
|
||||
import io.github.ehlxr.datastructure.Node;
|
||||
|
||||
/**
|
||||
* 基于链表实现的队列
|
||||
* <p>
|
||||
* 多一个变量 tail,换取入队时间复杂度为 O(1)
|
||||
*
|
||||
* @author ehlxr
|
||||
* @since 2021-12-25 16:48.
|
||||
*/
|
||||
public class LinkedListQueue2<T> {
|
||||
private Node<T> head = null;
|
||||
private Node<T> tail = null;
|
||||
|
||||
public static void main(String[] args) {
|
||||
LinkedListQueue2<Integer> queue = new LinkedListQueue2<>();
|
||||
for (int i = 0; i < 6; i++) {
|
||||
System.out.println(queue.enqueue(i));
|
||||
}
|
||||
|
||||
for (int i = 0; i < 6; i++) {
|
||||
queue.getData().print();
|
||||
System.out.println(queue.dequeue());
|
||||
}
|
||||
|
||||
System.out.println(queue.dequeue());
|
||||
}
|
||||
|
||||
/**
|
||||
* 入队(从队尾添加元素)
|
||||
* 时间复杂度 O(1)
|
||||
*/
|
||||
public boolean enqueue(T item) {
|
||||
Node<T> node = new Node<>(item, null);
|
||||
|
||||
if (tail == null) {
|
||||
head = node;
|
||||
tail = node;
|
||||
return true;
|
||||
}
|
||||
|
||||
tail.setNext(node);
|
||||
tail = node;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 出队(从队首取出元素)
|
||||
*/
|
||||
public T dequeue() {
|
||||
if (head == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
T val = head.getVal();
|
||||
head = head.getNext();
|
||||
// 如果队列为空了,需要把 tail 置空
|
||||
if (head == null) {
|
||||
tail = null;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
public Node<T> getData() {
|
||||
return head;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2020 xrv <xrg@live.com>
|
||||
* Copyright © 2020 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -22,44 +22,56 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.hashing.consistent;
|
||||
package io.github.ehlxr.datastructure.stack;
|
||||
|
||||
import java.util.SortedMap;
|
||||
import java.util.TreeMap;
|
||||
/**
|
||||
* @author ehlxr
|
||||
* @since 2021-12-25 22:10.
|
||||
*/
|
||||
public class ArrayStack {
|
||||
private final Integer[] data;
|
||||
private final int size;
|
||||
// 栈顶下标
|
||||
private int top = 0;
|
||||
|
||||
public class Cluster {
|
||||
private static final int SERVER_SIZE_MAX = 1024;
|
||||
|
||||
private final SortedMap<Integer, Server> servers = new TreeMap<>();
|
||||
private int size = 0;
|
||||
|
||||
public void put(Entry e) {
|
||||
routeServer(e.hashCode()).put(e);
|
||||
}
|
||||
|
||||
public Entry get(Entry e) {
|
||||
return routeServer(e.hashCode()).get(e);
|
||||
}
|
||||
|
||||
public Server routeServer(int hash) {
|
||||
if (servers.isEmpty())
|
||||
return null;
|
||||
|
||||
if (!servers.containsKey(hash)) {
|
||||
SortedMap<Integer, Server> tailMap = servers.tailMap(hash);
|
||||
hash = tailMap.isEmpty() ? servers.firstKey() : tailMap.firstKey();
|
||||
// hash = servers.firstKey();
|
||||
public static void main(String[] args) {
|
||||
ArrayStack stack = new ArrayStack(5);
|
||||
for (int i = 0; i < 6; i++) {
|
||||
System.out.println(stack.push(i));
|
||||
}
|
||||
return servers.get(hash);
|
||||
|
||||
for (int i = 0; i < 6; i++) {
|
||||
System.out.println(stack.pop());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public boolean addServer(Server s) {
|
||||
if (size >= SERVER_SIZE_MAX)
|
||||
public ArrayStack(int size) {
|
||||
data = new Integer[size];
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
/**
|
||||
* 入栈
|
||||
*/
|
||||
public boolean push(Integer item) {
|
||||
// 判断栈是否已满
|
||||
if (top == size) {
|
||||
return false;
|
||||
}
|
||||
data[top++] = item;
|
||||
|
||||
servers.put(s.hashCode(), s);
|
||||
|
||||
size++;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 出栈
|
||||
*/
|
||||
public Integer pop() {
|
||||
// 判断栈是否为空
|
||||
if (top == 0) {
|
||||
return null;
|
||||
}
|
||||
return data[--top];
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2020 xrv <xrg@live.com>
|
||||
* Copyright © 2020 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -22,55 +22,63 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.test;
|
||||
package io.github.ehlxr.datastructure.stack;
|
||||
|
||||
import io.github.ehlxr.datastructure.Node;
|
||||
|
||||
/**
|
||||
* Created by ehlxr on 2017/4/14.
|
||||
* @author ehlxr
|
||||
* @since 2021-12-25 22:28.
|
||||
*/
|
||||
public class TestReference {
|
||||
public class LinkedListStack<T> {
|
||||
private Node<T> head;
|
||||
|
||||
public Node<T> getData() {
|
||||
return head;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
Person person = new Person();
|
||||
LinkedListStack<Integer> stack = new LinkedListStack<>();
|
||||
for (int i = 0; i < 6; i++) {
|
||||
System.out.println(stack.push(i));
|
||||
}
|
||||
|
||||
for (int i = 0; i < 6; i++) {
|
||||
stack.getData().print();
|
||||
System.out.println(stack.pop());
|
||||
}
|
||||
|
||||
person.age = 20;
|
||||
person.name = "test20";
|
||||
System.out.println(person);
|
||||
TestReference testReference = new TestReference();
|
||||
testReference.test(person);
|
||||
System.out.println(person);
|
||||
}
|
||||
|
||||
public void test(Person person) {
|
||||
person = new Person();
|
||||
person.age = 21;
|
||||
person.name = "test21";
|
||||
/**
|
||||
* 入栈
|
||||
*/
|
||||
public boolean push(T item) {
|
||||
Node<T> node = new Node<>(item, null);
|
||||
if (head == null) {
|
||||
head = node;
|
||||
return true;
|
||||
}
|
||||
|
||||
node.setNext(head);
|
||||
head = node;
|
||||
return true;
|
||||
}
|
||||
|
||||
static class Person {
|
||||
String name;
|
||||
int age;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Person{" +
|
||||
"name='" + name + '\'' +
|
||||
", age=" + age +
|
||||
'}';
|
||||
/**
|
||||
* 出栈
|
||||
*/
|
||||
public T pop() {
|
||||
if (head == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
T val = head.getVal();
|
||||
head = head.getNext();
|
||||
return val;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
|
||||
public void setAge(int age) {
|
||||
this.age = age;
|
||||
}
|
||||
public void clear() {
|
||||
head = null;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2020 xrv <xrg@live.com>
|
||||
* Copyright © 2021 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -22,7 +22,7 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.utils;
|
||||
package io.github.ehlxr.enums;
|
||||
|
||||
/**
|
||||
* 自定义状态码
|
||||
@@ -30,7 +30,7 @@ package io.github.ehlxr.utils;
|
||||
* @author ehlxr
|
||||
* @since 2020/3/18.
|
||||
*/
|
||||
public enum Code {
|
||||
public enum CodeEnum {
|
||||
/**
|
||||
* 成功
|
||||
*/
|
||||
@@ -55,7 +55,7 @@ public enum Code {
|
||||
private final int code;
|
||||
private final String message;
|
||||
|
||||
Code(int code, String message) {
|
||||
CodeEnum(int code, String message) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
}
|
||||
@@ -76,10 +76,10 @@ public enum Code {
|
||||
'}';
|
||||
}
|
||||
|
||||
private static final Code[] CODES = Code.values();
|
||||
private static final CodeEnum[] CODE_ENUMS = CodeEnum.values();
|
||||
|
||||
public static Code code(int code) {
|
||||
for (Code c : CODES) {
|
||||
public static CodeEnum code(int code) {
|
||||
for (CodeEnum c : CODE_ENUMS) {
|
||||
if (code == c.getCode()) {
|
||||
return c;
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2020 xrv <xrg@live.com>
|
||||
* Copyright © 2021 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -22,7 +22,7 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.utils;
|
||||
package io.github.ehlxr.enums;
|
||||
|
||||
/**
|
||||
* FORM 表单提交类型
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2020 xrv <xrg@live.com>
|
||||
* Copyright © 2021 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -22,7 +22,7 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.utils;
|
||||
package io.github.ehlxr.enums;
|
||||
|
||||
/**
|
||||
* @author ehlxr
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2020 xrv <xrg@live.com>
|
||||
* Copyright © 2021 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -22,31 +22,30 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.singleton;
|
||||
|
||||
import java.util.stream.IntStream;
|
||||
package io.github.ehlxr.exception;
|
||||
|
||||
/**
|
||||
* 枚举单例模式
|
||||
*
|
||||
* @author ehlxr
|
||||
* @since 2021-02-18 10:28.
|
||||
* @since 2020-05-06.
|
||||
*/
|
||||
public enum SingleEnum {
|
||||
/**
|
||||
* 唯一实例
|
||||
*/
|
||||
INSTANCE;
|
||||
public class JsonParseException extends RuntimeException {
|
||||
private static final long serialVersionUID = -2626765995683345473L;
|
||||
|
||||
public static SingleEnum getInstance() {
|
||||
return INSTANCE;
|
||||
public JsonParseException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
public String hello(String str) {
|
||||
return "hello " + str;
|
||||
public JsonParseException(String msg, Throwable e) {
|
||||
super(msg, e);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
IntStream.range(0, 5).parallel().forEach(i -> System.out.println(Thread.currentThread().getName() + " => " + SingleEnum.getInstance()));
|
||||
public JsonParseException(Throwable e) {
|
||||
super(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Throwable fillInStackTrace() {
|
||||
// 不拷贝栈信息
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2020 xrv <xrg@live.com>
|
||||
* Copyright © 2020 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -22,28 +22,46 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.singleton;
|
||||
package io.github.ehlxr.exception;
|
||||
|
||||
import java.util.stream.IntStream;
|
||||
import io.github.ehlxr.enums.CodeEnum;
|
||||
|
||||
/**
|
||||
* @author ehlxr
|
||||
* @since 2021-02-18 11:23.
|
||||
* @since 2021-08-29 19:18.
|
||||
*/
|
||||
public class SingleTonStaticInnerClass {
|
||||
private SingleTonStaticInnerClass() {
|
||||
public class ServiceDataException extends RuntimeException {
|
||||
/**
|
||||
* 错误码
|
||||
*/
|
||||
private int code;
|
||||
/**
|
||||
* 异常信息
|
||||
*/
|
||||
private String msg;
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
private static class HandlerInstance {
|
||||
private static SingleTonStaticInnerClass instance = new SingleTonStaticInnerClass();
|
||||
|
||||
public String getMsg() {
|
||||
return msg;
|
||||
}
|
||||
|
||||
public static SingleTonStaticInnerClass getInstance() {
|
||||
return HandlerInstance.instance;
|
||||
|
||||
public ServiceDataException(Throwable throwable) {
|
||||
super(throwable);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
IntStream.range(0, 5).parallel().forEach(i -> System.out.println(Thread.currentThread().getName() + " => " + SingleTonStaticInnerClass.getInstance()));
|
||||
public ServiceDataException(CodeEnum codeEnum) {
|
||||
this.code = codeEnum.getCode();
|
||||
this.msg = codeEnum.getMessage();
|
||||
}
|
||||
|
||||
}
|
||||
public ServiceDataException(int code, String msg) {
|
||||
super(msg);
|
||||
this.code = code;
|
||||
this.msg = msg;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2021 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.function;
|
||||
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
import java.util.concurrent.RecursiveAction;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* @author ehlxr
|
||||
* @since 2021-09-06 10:48.
|
||||
*/
|
||||
public class BlockerActionConsumer<T> extends RecursiveAction {
|
||||
private static final long serialVersionUID = 4942349095463615123L;
|
||||
private final MyManagedBlockerImpl<T> blocker;
|
||||
|
||||
public BlockerActionConsumer(Consumer<T> consumer, T t) {
|
||||
this.blocker = new MyManagedBlockerImpl<>(consumer, t);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute() {
|
||||
try {
|
||||
ForkJoinPool.managedBlock(blocker);
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
static class MyManagedBlockerImpl<T> implements ForkJoinPool.ManagedBlocker {
|
||||
private final Consumer<T> consumer;
|
||||
private final T t;
|
||||
private boolean done = false;
|
||||
|
||||
public MyManagedBlockerImpl(Consumer<T> consumer, T t) {
|
||||
this.consumer = consumer;
|
||||
this.t = t;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean block() {
|
||||
consumer.accept(t);
|
||||
done = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReleasable() {
|
||||
return done;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2021 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.function;
|
||||
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
import java.util.concurrent.RecursiveTask;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* @author ehlxr
|
||||
* @since 2021-09-06 10:39.
|
||||
*/
|
||||
public class BlockerTaskFunction<T, R> extends RecursiveTask<R> {
|
||||
private static final long serialVersionUID = -4114798302790287199L;
|
||||
private final MyManagedBlockerImpl<T, R> blocker;
|
||||
|
||||
public BlockerTaskFunction(Function<T, R> function, T t) {
|
||||
this.blocker = new MyManagedBlockerImpl<>(function, t);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected R compute() {
|
||||
try {
|
||||
ForkJoinPool.managedBlock(blocker);
|
||||
setRawResult(blocker.r);
|
||||
return getRawResult();
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
static class MyManagedBlockerImpl<T, R> implements ForkJoinPool.ManagedBlocker {
|
||||
private final Function<T, R> function;
|
||||
private final T t;
|
||||
private R r;
|
||||
private boolean done = false;
|
||||
|
||||
public MyManagedBlockerImpl(Function<T, R> function, T t) {
|
||||
this.function = function;
|
||||
this.t = t;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean block() {
|
||||
r = function.apply(t);
|
||||
done = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReleasable() {
|
||||
return done;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2020 xrv <xrg@live.com>
|
||||
* Copyright © 2021 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -22,27 +22,26 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.proxy;
|
||||
package io.github.ehlxr.function;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* @author ehlxr
|
||||
* @since 2019-06-28.
|
||||
* @since 2021-09-06 10:40.
|
||||
*/
|
||||
public class Bird implements Flyable {
|
||||
@Override
|
||||
public void fly() {
|
||||
System.out.println("Bird is flying...");
|
||||
try {
|
||||
Thread.sleep(new Random().nextInt(1000));
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
public class CallableFunction<T, R> implements Callable<R> {
|
||||
private final T t;
|
||||
private final Function<T, R> function;
|
||||
|
||||
public CallableFunction(Function<T, R> function, T t) {
|
||||
this.function = function;
|
||||
this.t = t;
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public void run() {
|
||||
// System.out.println("Bird is running...");
|
||||
// }
|
||||
}
|
||||
@Override
|
||||
public R call() {
|
||||
return function.apply(t);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2021 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.function;
|
||||
|
||||
import java.util.concurrent.RecursiveTask;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* @author ehlxr
|
||||
* @since 2021-09-06 10:41.
|
||||
*/
|
||||
public class RecursiveTaskFunction<T, R> extends RecursiveTask<R> {
|
||||
private static final long serialVersionUID = 4451027118600634633L;
|
||||
private final T t;
|
||||
private final Function<T, R> function;
|
||||
|
||||
public RecursiveTaskFunction(Function<T, R> function, T t) {
|
||||
this.function = function;
|
||||
this.t = t;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected R compute() {
|
||||
return function.apply(t);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2020 xrv <xrg@live.com>
|
||||
* Copyright © 2021 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -22,21 +22,25 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.hashing.consistent;
|
||||
package io.github.ehlxr.function;
|
||||
|
||||
public class Entry {
|
||||
private final String key;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
Entry(String key) {
|
||||
this.key = key;
|
||||
/**
|
||||
* @author ehlxr
|
||||
* @since 2021-09-06 10:40.
|
||||
*/
|
||||
public class RunnableConsumer<T> implements Runnable {
|
||||
private final T t;
|
||||
private final Consumer<T> consumer;
|
||||
|
||||
public RunnableConsumer(Consumer<T> consumer, T t) {
|
||||
this.consumer = consumer;
|
||||
this.t = t;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return key;
|
||||
public void run() {
|
||||
consumer.accept(t);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return key.hashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2022 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.queue;
|
||||
|
||||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @author ehlxr
|
||||
* @since 2022-02-24 20:00.
|
||||
*/
|
||||
@Component
|
||||
public class RedisDelayQueue {
|
||||
private static final Logger log = LoggerFactory.getLogger(RedisDelayQueue.class);
|
||||
/**
|
||||
* 延迟队列名称
|
||||
*/
|
||||
private static final String DELAY_QUEUE_NAME = "budd:delayQueue";
|
||||
private static final ExecutorService POOL = new ThreadPoolExecutor(5, 200,
|
||||
0L, TimeUnit.MILLISECONDS,
|
||||
new LinkedBlockingQueue<>(1024), new ThreadFactoryBuilder()
|
||||
.setNameFormat("RedisDelayQueue-pool-%d").build(),
|
||||
new ThreadPoolExecutor.AbortPolicy());
|
||||
private final RedisTemplate<String, String> redisTemplate;
|
||||
|
||||
public RedisDelayQueue(RedisTemplate<String, String> redisTemplate) {
|
||||
this.redisTemplate = redisTemplate;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加延迟任务
|
||||
*
|
||||
* @param msg 延迟任务消息
|
||||
* @param delayTime 延迟时间(毫秒)
|
||||
*/
|
||||
public void addDelayTasks(String msg, long delayTime) {
|
||||
Boolean result = redisTemplate.opsForZSet()
|
||||
.add(DELAY_QUEUE_NAME, msg, System.currentTimeMillis() + delayTime);
|
||||
log.debug("add task {} result {} ", msg, result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 监听延迟消息
|
||||
*/
|
||||
@PostConstruct
|
||||
public void listenDelayLoop() {
|
||||
//noinspection AlibabaAvoidManuallyCreateThread
|
||||
new Thread(() -> {
|
||||
while (true) {
|
||||
// 获取一个到点的消息
|
||||
Set<String> taskSet = redisTemplate.opsForZSet()
|
||||
.rangeByScore(DELAY_QUEUE_NAME, 0, System.currentTimeMillis(), 0, 1);
|
||||
|
||||
// 如果没有,就等等
|
||||
if (taskSet == null || taskSet.isEmpty()) {
|
||||
try {
|
||||
// log.debug("there is no task will sleep 1s.");
|
||||
TimeUnit.SECONDS.sleep(1);
|
||||
} catch (InterruptedException e) {
|
||||
log.error("listen delay loop error.", e);
|
||||
}
|
||||
// 继续执行
|
||||
continue;
|
||||
}
|
||||
|
||||
for (String task : taskSet) {
|
||||
// 任务认领成功
|
||||
Long isRemove = redisTemplate.opsForZSet().remove(DELAY_QUEUE_NAME, task);
|
||||
if (isRemove != null && isRemove > 0) {
|
||||
log.info("will deal task {}", task);
|
||||
// 拿到任务 后续处理
|
||||
POOL.execute(() -> log.info("task {} deal done.", task));
|
||||
} else {
|
||||
log.warn("task {} has been handled by another instance", task);
|
||||
}
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2020 xrv <xrg@live.com>
|
||||
* Copyright © 2022 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -22,14 +22,23 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.proxy;
|
||||
package io.github.ehlxr.semaphore;
|
||||
|
||||
/**
|
||||
* @author ehlxr
|
||||
* @since 2019-06-28.
|
||||
* @since 2022-03-03 11:25.
|
||||
*/
|
||||
public interface Flyable {
|
||||
void fly();
|
||||
public interface DistributedSemaphore {
|
||||
/**
|
||||
* 尝试获取一个信号量
|
||||
*
|
||||
* @return true 获取成功,false 获取失败
|
||||
*/
|
||||
boolean tryAcquire();
|
||||
|
||||
// void run();
|
||||
/**
|
||||
* 释放自己持有的信号量
|
||||
*/
|
||||
void release();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2022 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.semaphore;
|
||||
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.data.redis.core.RedisOperations;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.core.SessionCallback;
|
||||
import org.springframework.data.redis.core.ZSetOperations;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @author ehlxr
|
||||
* @since 2022-03-03 11:25.
|
||||
*/
|
||||
public class RedisSemaphore implements DistributedSemaphore {
|
||||
private static final String SEMAPHORE_TIME_KEY = "budd:semaphore:time:";
|
||||
private static final String SEMAPHORE_OWNER_KEY = "budd:semaphore:owner:";
|
||||
private static final String SEMAPHORE_COUNTER_KEY = "budd:semaphore:counter:";
|
||||
private final RedisTemplate<String, String> redisTemplate;
|
||||
private final String timeKey;
|
||||
private final String ownerKey;
|
||||
private final String counterKey;
|
||||
// 信号量的信息
|
||||
private final SemaphoreInfo info;
|
||||
// 信号量实体
|
||||
private final DistributedSemaphore semaphore;
|
||||
// 身份证明
|
||||
private final String identification;
|
||||
|
||||
public RedisSemaphore(SemaphoreInfo info, RedisTemplate<String, String> redisTemplate,
|
||||
String identification) {
|
||||
this.info = info;
|
||||
this.redisTemplate = redisTemplate;
|
||||
this.timeKey = SEMAPHORE_TIME_KEY.concat(info.getSemaphoreName());
|
||||
this.ownerKey = SEMAPHORE_OWNER_KEY.concat(info.getSemaphoreName());
|
||||
this.counterKey = SEMAPHORE_COUNTER_KEY.concat(info.getSemaphoreName());
|
||||
this.semaphore = info.isFair() ? new FairSemaphore() : new NonfairSemaphore();
|
||||
this.identification = identification;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tryAcquire() {
|
||||
return semaphore.tryAcquire();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release() {
|
||||
semaphore.release();
|
||||
}
|
||||
|
||||
private class NonfairSemaphore implements DistributedSemaphore {
|
||||
@Override
|
||||
public boolean tryAcquire() {
|
||||
ZSetOperations<String, String> zsetOps = redisTemplate.opsForZSet();
|
||||
long timeMillis = System.currentTimeMillis();
|
||||
// 先清除过期的信号量
|
||||
zsetOps.removeRangeByScore(timeKey, 0, timeMillis - TimeUnit.SECONDS.toMillis(info.getExpire()));
|
||||
// 尝试获取信号量并比较自身的排名,如果小于许可证的数量则表示获取成功 (redis rank 指令从 0 开始计数)
|
||||
zsetOps.add(timeKey, identification, timeMillis);
|
||||
Long rank = zsetOps.rank(timeKey, identification);
|
||||
if (rank != null && rank < info.getPermits()) {
|
||||
return true;
|
||||
}
|
||||
// 获取失败,删除掉上边添加的标识
|
||||
release();
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release() {
|
||||
redisTemplate.opsForZSet().remove(timeKey, identification);
|
||||
}
|
||||
}
|
||||
|
||||
private class FairSemaphore implements DistributedSemaphore {
|
||||
@Override
|
||||
public boolean tryAcquire() {
|
||||
long timeMillis = System.currentTimeMillis();
|
||||
// 用于获取信号量的计数
|
||||
Long counter = redisTemplate.opsForValue().increment(counterKey, 1);
|
||||
if (counter == null) {
|
||||
return false;
|
||||
}
|
||||
// 用流水线把这一堆命令用一次 IO 全部发过去
|
||||
redisTemplate.executePipelined(new SessionCallback<>() {
|
||||
@Override
|
||||
public Object execute(@Nonnull RedisOperations operations) throws DataAccessException {
|
||||
ZSetOperations<String, Object> zsetOps = operations.opsForZSet();
|
||||
// 利用 timeKey 来控制是否过期,ownerKey 控制是否超配额,
|
||||
// 使用 zset 的 intersectAndStore 在获取信号量之前清理过期数据,同时清理排名集合中的数据
|
||||
// 清除过期的信号量
|
||||
zsetOps.removeRangeByScore(timeKey, 0, timeMillis - TimeUnit.SECONDS.toMillis(info.getExpire()));
|
||||
zsetOps.intersectAndStore(timeKey, ownerKey, ownerKey);
|
||||
// 尝试获取信号量
|
||||
zsetOps.add(timeKey, identification, timeMillis);
|
||||
zsetOps.add(ownerKey, identification, counter);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
// 这里根据 持有者集合 的分数来进行判断
|
||||
Long ownerRank = redisTemplate.opsForZSet().rank(ownerKey, identification);
|
||||
if (ownerRank != null && ownerRank < info.getPermits()) {
|
||||
return true;
|
||||
}
|
||||
release();
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release() {
|
||||
redisTemplate.executePipelined(new SessionCallback<>() {
|
||||
@Override
|
||||
public Object execute(@Nonnull RedisOperations operations) throws DataAccessException {
|
||||
ZSetOperations<String, Object> zetOps = operations.opsForZSet();
|
||||
zetOps.remove(timeKey, identification);
|
||||
zetOps.remove(ownerKey, identification);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2022 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.semaphore;
|
||||
|
||||
/**
|
||||
* @author ehlxr
|
||||
* @since 2022-03-03 11:24.
|
||||
*/
|
||||
public final class SemaphoreInfo {
|
||||
// 信号量的名称
|
||||
private final String semaphoreName;
|
||||
// 许可证的数量
|
||||
private final int permits;
|
||||
// 信号量最大持有时间 (过期时间) 单位 s
|
||||
private final long expire;
|
||||
// 公平 or 非公平
|
||||
private final boolean fair;
|
||||
|
||||
public SemaphoreInfo(String semaphoreName, int permits, long expire) {
|
||||
this(semaphoreName, permits, expire, false);
|
||||
}
|
||||
|
||||
public SemaphoreInfo(String semaphoreName, int permits, long expire, boolean fair) {
|
||||
this.semaphoreName = semaphoreName;
|
||||
this.permits = permits;
|
||||
this.expire = expire;
|
||||
this.fair = fair;
|
||||
}
|
||||
|
||||
public String getSemaphoreName() {
|
||||
return semaphoreName;
|
||||
}
|
||||
|
||||
public int getPermits() {
|
||||
return permits;
|
||||
}
|
||||
|
||||
public long getExpire() {
|
||||
return expire;
|
||||
}
|
||||
|
||||
public boolean isFair() {
|
||||
return fair;
|
||||
}
|
||||
}
|
||||
323
budd-common/src/main/java/io/github/ehlxr/util/DateUtil.java
Normal file
323
budd-common/src/main/java/io/github/ehlxr/util/DateUtil.java
Normal file
@@ -0,0 +1,323 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2021 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.util;
|
||||
|
||||
import org.apache.commons.lang3.tuple.ImmutablePair;
|
||||
|
||||
import java.time.*;
|
||||
import java.time.chrono.ChronoLocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.temporal.TemporalAdjusters;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
/**
|
||||
* 日期操作
|
||||
*
|
||||
* @author ehlxr
|
||||
* @since 2021-08-29 18:32.
|
||||
*/
|
||||
public class DateUtil {
|
||||
public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
|
||||
public static final String YYYY_MM_DD = "yyyy-MM-dd";
|
||||
public static final String MM_DD = "MM-dd";
|
||||
public static final String HH_MM_SS = "HH:mm:ss";
|
||||
|
||||
// private static final DateTimeFormatter DEFAULT_DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern(YYYY_MM_DD_HH_MM_SS);
|
||||
// private static final DateTimeFormatter DEFAULT_DATE_FORMATTER = DateTimeFormatter.ofPattern(YYYY_MM_DD);
|
||||
// private static final DateTimeFormatter DEFAULT_DATE_NO_YEAR_FORMATTER = DateTimeFormatter.ofPattern(MM_DD);
|
||||
// private static final DateTimeFormatter DEFAULT_TIME_FORMATTER = DateTimeFormatter.ofPattern(HH_MM_SS);
|
||||
private static final Map<String, DateTimeFormatter> PATTEN_FORMATTER_MAPPER = Collections.synchronizedMap(new WeakHashMap<>());
|
||||
|
||||
// static {
|
||||
// PATTEN_FORMATTER_MAPPER.put(YYYY_MM_DD_HH_MM_SS, DEFAULT_DATE_TIME_FORMATTER);
|
||||
// PATTEN_FORMATTER_MAPPER.put(YYYY_MM_DD, DEFAULT_DATE_FORMATTER);
|
||||
// PATTEN_FORMATTER_MAPPER.put(MM_DD, DEFAULT_DATE_NO_YEAR_FORMATTER);
|
||||
// PATTEN_FORMATTER_MAPPER.put(HH_MM_SS, DEFAULT_TIME_FORMATTER);
|
||||
// }
|
||||
|
||||
private static DateTimeFormatter cacheFormatterAndGet(String patten) {
|
||||
DateTimeFormatter dateTimeFormatter = PATTEN_FORMATTER_MAPPER.get(patten);
|
||||
if (dateTimeFormatter == null) {
|
||||
dateTimeFormatter = DateTimeFormatter.ofPattern(patten).withZone(ZoneId.of("+8"));
|
||||
PATTEN_FORMATTER_MAPPER.put(patten, dateTimeFormatter);
|
||||
}
|
||||
return dateTimeFormatter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param localDateTime date time
|
||||
* @return yyyy-MM-dd HH:mm:ss
|
||||
*/
|
||||
public static String formatLocalDateTime(LocalDateTime localDateTime) {
|
||||
return localDateTime.format(cacheFormatterAndGet(YYYY_MM_DD_HH_MM_SS));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param localDateTime time
|
||||
* @param patten yyyy-MM-dd HH:mm:ss
|
||||
* @return yyyy-MM-dd HH:mm:ss
|
||||
*/
|
||||
public static String formatLocalDateTime(LocalDateTime localDateTime, String patten) {
|
||||
DateTimeFormatter dateTimeFormatter = cacheFormatterAndGet(patten);
|
||||
return localDateTime.format(dateTimeFormatter);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param localDate date
|
||||
* @param patten only date patten
|
||||
* @return yyyy-MM-dd
|
||||
*/
|
||||
public static String formatLocalDate(LocalDate localDate, String patten) {
|
||||
DateTimeFormatter dateTimeFormatter = cacheFormatterAndGet(patten);
|
||||
return localDate.format(dateTimeFormatter);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param localDate localDate
|
||||
* @return yyyy-MM-dd
|
||||
*/
|
||||
public static String formatLocalDate(LocalDate localDate) {
|
||||
return localDate.format(cacheFormatterAndGet(YYYY_MM_DD));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param localTime localTime
|
||||
* @param patten patten
|
||||
* @return HH:mm:ss
|
||||
*/
|
||||
public static String formatLocalTime(LocalTime localTime, String patten) {
|
||||
DateTimeFormatter dateTimeFormatter = cacheFormatterAndGet(patten);
|
||||
return localTime.format(dateTimeFormatter);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param localTime localTime
|
||||
* @return HH:mm:ss
|
||||
*/
|
||||
public static String formatLocalTime(LocalTime localTime) {
|
||||
return localTime.format(cacheFormatterAndGet(HH_MM_SS));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param date date time
|
||||
* @param patten patten
|
||||
* @return yyyy-MM-dd HH:mm:ss
|
||||
*/
|
||||
public static String format(Date date, String patten) {
|
||||
Instant instant = date.toInstant();
|
||||
LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.of("+8"));
|
||||
return localDateTime.format(cacheFormatterAndGet(patten));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param date date
|
||||
* @return yyyy-MM-dd HH:mm:ss
|
||||
*/
|
||||
public static String format(Date date) {
|
||||
return format(date, YYYY_MM_DD_HH_MM_SS);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param date date
|
||||
* @return yyyy-MM-dd
|
||||
*/
|
||||
public static String formatDate(Date date) {
|
||||
return format(date, YYYY_MM_DD);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param date date
|
||||
* @return HH:mm:ss
|
||||
*/
|
||||
public static String formatTime(Date date) {
|
||||
return format(date, HH_MM_SS);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mills mills
|
||||
* @return yyyy-MM-dd HH:mm:ss
|
||||
*/
|
||||
public static String formatMills(long mills, String patten) {
|
||||
Instant instant = Instant.ofEpochMilli(mills);
|
||||
LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.of("+8"));
|
||||
return formatLocalDateTime(localDateTime, patten);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mills mills
|
||||
* @return yyyy-MM-dd HH:mm:ss
|
||||
*/
|
||||
public static String formatMills(long mills) {
|
||||
return formatMills(mills, YYYY_MM_DD_HH_MM_SS);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mills mills
|
||||
* @return yyyy-MM-dd
|
||||
*/
|
||||
public static String formatMillsDate(long mills) {
|
||||
return formatMills(mills, YYYY_MM_DD);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param date date
|
||||
* @return HH:mm:ss
|
||||
*/
|
||||
public static String formatMillsTime(long date) {
|
||||
return formatMills(date, HH_MM_SS);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param date yyyy-MM-dd HH:mm:ss
|
||||
* @return Date
|
||||
*/
|
||||
public static Date parse(String date) {
|
||||
LocalDateTime localDateTime = parseToLocalDateTime(date);
|
||||
Instant instant = localDateTime.toInstant(OffsetDateTime.now().getOffset());
|
||||
return Date.from(instant);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param date string date
|
||||
* @param patten formatter patten
|
||||
* @return LocalDateTime
|
||||
*/
|
||||
public static LocalDateTime parseToLocalDateTime(String date, String patten) {
|
||||
return LocalDateTime.parse(date, DateTimeFormatter.ofPattern(patten));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param date yyyy-MM-dd HH:mm:ss
|
||||
* @return LocalDateTime
|
||||
*/
|
||||
public static LocalDateTime parseToLocalDateTime(String date) {
|
||||
return LocalDateTime.parse(date, cacheFormatterAndGet(YYYY_MM_DD_HH_MM_SS));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param date yyyy-MM-dd HH:mm:ss
|
||||
* @return milliseconds
|
||||
*/
|
||||
public static Long parseToMillis(String date) {
|
||||
return parseToMillis(date, YYYY_MM_DD_HH_MM_SS);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param date string date
|
||||
* @param patten formatter patten
|
||||
* @return milliseconds
|
||||
*/
|
||||
public static Long parseToMillis(String date, String patten) {
|
||||
return toInstant(LocalDateTime.parse(date, cacheFormatterAndGet(patten))).toEpochMilli();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param date yyyy-MM-dd
|
||||
* @return LocalDate
|
||||
*/
|
||||
public static LocalDate parseToLocalDate(String date) {
|
||||
return LocalDate.parse(date, cacheFormatterAndGet(YYYY_MM_DD));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param date HH:mm:ss
|
||||
* @return LocalTime
|
||||
*/
|
||||
public static LocalTime parseToLocalTime(String date) {
|
||||
return LocalTime.parse(date, cacheFormatterAndGet(HH_MM_SS));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param dayStart date
|
||||
* @param dayEnd date
|
||||
*/
|
||||
public static Period betweenDays(Date dayStart, Date dayEnd) {
|
||||
LocalDateTime localDateTimeStart = LocalDateTime.ofInstant(dayStart.toInstant(), OffsetDateTime.now().getOffset());
|
||||
LocalDateTime localDateTimeEnd = LocalDateTime.ofInstant(dayEnd.toInstant(), OffsetDateTime.now().getOffset());
|
||||
return Period.between(localDateTimeStart.toLocalDate(), localDateTimeEnd.toLocalDate());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param dayStart date
|
||||
* @param dayEnd date
|
||||
*/
|
||||
public static Duration betweenTimes(Date dayStart, Date dayEnd) {
|
||||
LocalDateTime localDateTimeStart = LocalDateTime.ofInstant(dayStart.toInstant(), OffsetDateTime.now().getOffset());
|
||||
LocalDateTime localDateTimeEnd = LocalDateTime.ofInstant(dayEnd.toInstant(), OffsetDateTime.now().getOffset());
|
||||
return Duration.between(localDateTimeStart, localDateTimeEnd);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param dayStart date
|
||||
* @param dayEnd date
|
||||
*/
|
||||
public static Period betweenDays(String dayStart, String dayEnd) {
|
||||
return Period.between(parseToLocalDate(dayStart), parseToLocalDate(dayEnd));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param dayStart date
|
||||
* @param dayEnd date
|
||||
*/
|
||||
public static Duration betweenTimes(String dayStart, String dayEnd) {
|
||||
return Duration.between(parseToLocalDateTime(dayStart), parseToLocalDateTime(dayEnd));
|
||||
}
|
||||
|
||||
/**
|
||||
* 每月开始、结束毫秒时间戳
|
||||
*/
|
||||
public static ImmutablePair<Long, Long> firstAndLastMillisOfMonth() {
|
||||
LocalDate today = LocalDate.now();
|
||||
Long firstDay = toInstant(LocalDateTime.of(today.with(TemporalAdjusters.firstDayOfMonth()), LocalTime.MIN)).toEpochMilli();
|
||||
Long lastDay = toInstant(LocalDateTime.of(today.with(TemporalAdjusters.lastDayOfMonth()), LocalTime.MAX)).toEpochMilli();
|
||||
return ImmutablePair.of(firstDay, lastDay);
|
||||
}
|
||||
|
||||
public static Instant toInstant(ChronoLocalDateTime<?> d) {
|
||||
return d.toInstant(ZoneOffset.of("+8"));
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前秒级别时间戳
|
||||
*
|
||||
* @return 10 位时间戳
|
||||
*/
|
||||
public static Long currentTimeSecond() {
|
||||
return toInstant(LocalDateTime.now()).getEpochSecond();
|
||||
}
|
||||
|
||||
/**
|
||||
* 之前的多少天
|
||||
*
|
||||
* @param days 之前的天数
|
||||
* @return yyyy-MM-dd
|
||||
*/
|
||||
public static String beforeDay(long days) {
|
||||
return formatLocalDate(LocalDate.now().minusDays(days));
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2020 xrv <xrg@live.com>
|
||||
* Copyright © 2021 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -22,25 +22,62 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.utils;
|
||||
package io.github.ehlxr.util;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import io.github.ehlxr.enums.FormType;
|
||||
import io.github.ehlxr.enums.HttpContentType;
|
||||
import okhttp3.*;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.TrustManager;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
import java.io.File;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
|
||||
/**
|
||||
* @author ehlxr
|
||||
* @since 2020/4/20.
|
||||
*/
|
||||
public class HttpUtil {
|
||||
private static final OkHttpClient OK_HTTP_CLIENT = new OkHttpClient.Builder()
|
||||
private static OkHttpClient client = new OkHttpClient.Builder()
|
||||
.connectTimeout(1, TimeUnit.MINUTES)
|
||||
.readTimeout(1, TimeUnit.MINUTES)
|
||||
.build();
|
||||
|
||||
public static void trustAllClient() {
|
||||
Try.of(() -> {
|
||||
X509TrustManager x509TrustManager = new X509TrustManager() {
|
||||
@Override
|
||||
public void checkClientTrusted(X509Certificate[] chain, String authType) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkServerTrusted(X509Certificate[] chain, String authType) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public X509Certificate[] getAcceptedIssuers() {
|
||||
return new X509Certificate[]{};
|
||||
}
|
||||
};
|
||||
|
||||
SSLContext sslContext = SSLContext.getInstance("TLS");
|
||||
sslContext.init(null, new TrustManager[]{x509TrustManager}, new SecureRandom());
|
||||
|
||||
client = new OkHttpClient.Builder()
|
||||
.connectTimeout(1, TimeUnit.MINUTES)
|
||||
.readTimeout(1, TimeUnit.MINUTES)
|
||||
.sslSocketFactory(sslContext.getSocketFactory(), x509TrustManager)
|
||||
.hostnameVerifier((s, sslSession) -> true)
|
||||
.build();
|
||||
}).trap(Throwable::printStackTrace).run();
|
||||
}
|
||||
|
||||
public static String get(String url, Map<String, String> headers) {
|
||||
String resp;
|
||||
try {
|
||||
@@ -48,7 +85,7 @@ public class HttpUtil {
|
||||
.url(url)
|
||||
.headers(Headers.of(headers))
|
||||
.build();
|
||||
Response response = OK_HTTP_CLIENT.newCall(request).execute();
|
||||
Response response = client.newCall(request).execute();
|
||||
if (response.isSuccessful()) {
|
||||
resp = response.body() != null ? response.body().string() : "";
|
||||
} else {
|
||||
@@ -75,7 +112,7 @@ public class HttpUtil {
|
||||
.post(RequestBody.create(mediaType, body))
|
||||
.build();
|
||||
|
||||
Response response = OK_HTTP_CLIENT.newCall(request).execute();
|
||||
Response response = client.newCall(request).execute();
|
||||
if (response.isSuccessful()) {
|
||||
resp = response.body() != null ? response.body().string() : "";
|
||||
} else {
|
||||
@@ -117,7 +154,7 @@ public class HttpUtil {
|
||||
.post(builder.build())
|
||||
.headers(Headers.of(header))
|
||||
.build();
|
||||
Response response = OK_HTTP_CLIENT.newCall(request).execute();
|
||||
Response response = client.newCall(request).execute();
|
||||
if (response.isSuccessful()) {
|
||||
resp = response.body() != null ? response.body().string() : "";
|
||||
} else {
|
||||
@@ -136,5 +173,9 @@ public class HttpUtil {
|
||||
|
||||
return sb.substring(0, sb.length() - 1);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
HttpUtil.trustAllClient();
|
||||
}
|
||||
}
|
||||
|
||||
108
budd-common/src/main/java/io/github/ehlxr/util/IdUtil.java
Normal file
108
budd-common/src/main/java/io/github/ehlxr/util/IdUtil.java
Normal file
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2021 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.util;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* 自增 id 生成工具类
|
||||
*
|
||||
* @author ehlxr
|
||||
* @since 2021-08-29 18:32.
|
||||
*/
|
||||
@Component
|
||||
public class IdUtil {
|
||||
private final static String REDIS_ID_KEY = "com.tzld.piaoquan.incentive_";
|
||||
/**
|
||||
* 每一毫秒生成的最大数
|
||||
*/
|
||||
private static final int MAX_NUN = 99;
|
||||
private static final AtomicInteger ATOMIC_NUM = new AtomicInteger();
|
||||
private static RedisTemplate<String, String> redisTemplate;
|
||||
private static String cur_date;
|
||||
|
||||
public static long redisId() {
|
||||
// 生成 17 位的时间戳(每毫秒使用新的时间戳当key)
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS");
|
||||
String timeStamp = LocalDateTime.now(ZoneOffset.of("+8")).format(formatter);
|
||||
// 获得 redis-key
|
||||
String newKey = String.format("%s:%s", REDIS_ID_KEY, timeStamp);
|
||||
// 获取自增值(时间戳 + 自定义 key)
|
||||
Long increment = redisTemplate.opsForValue().increment(newKey, 1);
|
||||
// 设置时间戳生成的 key 的有效期为 1 秒
|
||||
redisTemplate.expire(newKey, 1, TimeUnit.SECONDS);
|
||||
// 获取订单号,时间戳 + 唯一自增 Id(2 位数,不过前方补 0)
|
||||
return Long.parseLong(String.format("%s%02d", timeStamp, increment));
|
||||
}
|
||||
|
||||
// @Autowired
|
||||
// public IdUtil(RedisTemplate<String, Object> redisTemplate) {
|
||||
// IdUtil.redisTemplate = redisTemplate;
|
||||
// }
|
||||
|
||||
/**
|
||||
* 生成 19 位数 id
|
||||
* <p>
|
||||
* 17 位日期 + 2 位自增数<br>
|
||||
* 一毫秒最多生成 MAX_NUN 个 id,同一毫秒 id 有序自增
|
||||
*/
|
||||
public static long localId() {
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS");
|
||||
String nowStr = LocalDateTime.now(ZoneOffset.of("+8")).format(formatter);
|
||||
|
||||
// 如果当前时间不是 cur_date 时间 设置 cur_date 为当前时间 重新开始计数
|
||||
if (!nowStr.equals(cur_date)) {
|
||||
cur_date = nowStr;
|
||||
|
||||
ATOMIC_NUM.set(0);
|
||||
}
|
||||
// 如果同一毫秒最大数大于 最大数 MAX_NUN 则等待 1 毫秒 重新计算
|
||||
if (ATOMIC_NUM.get() >= MAX_NUN) {
|
||||
try {
|
||||
Thread.sleep(1);
|
||||
} catch (InterruptedException ignored) {
|
||||
}
|
||||
|
||||
nowStr = LocalDateTime.now(ZoneOffset.of("+8")).format(formatter);
|
||||
ATOMIC_NUM.set(0);
|
||||
}
|
||||
|
||||
// 线程安全的原子操作,所以此方法无需同步 调用 incrementAndGet 函数来进行自增操作
|
||||
return Long.parseLong(String.format("%s%02d", nowStr, ATOMIC_NUM.incrementAndGet()));
|
||||
}
|
||||
|
||||
@Autowired
|
||||
public void setRedisTemplate(RedisTemplate<String, String> redisTemplate) {
|
||||
IdUtil.redisTemplate = redisTemplate;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2020 xrv <xrg@live.com>
|
||||
* Copyright © 2021 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -22,7 +22,7 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.utils;
|
||||
package io.github.ehlxr.util;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
@@ -30,6 +30,7 @@ import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.*;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import io.github.ehlxr.exception.JsonParseException;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
@@ -75,7 +76,7 @@ public class JsonUtils {
|
||||
try {
|
||||
return OBJECT_MAPPER.readTree(obj2String(obj));
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new RuntimeException(e);
|
||||
throw new JsonParseException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,7 +94,7 @@ public class JsonUtils {
|
||||
try {
|
||||
return obj instanceof String ? (String) obj : OBJECT_MAPPER.writeValueAsString(obj);
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new RuntimeException(e);
|
||||
throw new JsonParseException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,7 +112,7 @@ public class JsonUtils {
|
||||
try {
|
||||
return obj instanceof String ? (String) obj : OBJECT_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new RuntimeException(e);
|
||||
throw new JsonParseException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,7 +131,7 @@ public class JsonUtils {
|
||||
try {
|
||||
return clazz.equals(String.class) ? (T) str : OBJECT_MAPPER.readValue(str, clazz);
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new RuntimeException(e);
|
||||
throw new JsonParseException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,7 +150,7 @@ public class JsonUtils {
|
||||
try {
|
||||
return typeReference.getType().equals(String.class) ? (T) str : OBJECT_MAPPER.readValue(str, typeReference);
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new RuntimeException(e);
|
||||
throw new JsonParseException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,7 +168,7 @@ public class JsonUtils {
|
||||
try {
|
||||
return OBJECT_MAPPER.readValue(str, javaType);
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new RuntimeException(e);
|
||||
throw new JsonParseException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -246,4 +247,3 @@ public class JsonUtils {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2021 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.util;
|
||||
|
||||
import java.util.BitSet;
|
||||
|
||||
/**
|
||||
* @author ehlxr
|
||||
* @since 2021-12-16 09:36.
|
||||
*/
|
||||
public class MyBloomFilter {
|
||||
/**
|
||||
* 一个长度为10 亿的比特位
|
||||
*/
|
||||
private static final int DEFAULT_SIZE = 256 << 22;
|
||||
|
||||
/**
|
||||
* 为了降低错误率,使用加法hash算法,所以定义一个8个元素的质数数组
|
||||
*/
|
||||
private static final int[] SEEDS = {3, 5, 7, 11, 13, 31, 37, 61};
|
||||
|
||||
/**
|
||||
* 相当于构建 8 个不同的hash算法
|
||||
*/
|
||||
private static final HashFunction[] HASH_FUNCS = new HashFunction[SEEDS.length];
|
||||
|
||||
/**
|
||||
* 初始化布隆过滤器的 bitmap
|
||||
*/
|
||||
private static final BitSet BIT_SET = new BitSet(DEFAULT_SIZE);
|
||||
|
||||
/**
|
||||
* 添加数据
|
||||
*
|
||||
* @param value 需要加入的值
|
||||
*/
|
||||
public static void add(String value) {
|
||||
if (value != null) {
|
||||
for (HashFunction f : HASH_FUNCS) {
|
||||
//计算 hash 值并修改 bitmap 中相应位置为 true
|
||||
BIT_SET.set(f.hash(value), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断相应元素是否存在
|
||||
*
|
||||
* @param value 需要判断的元素
|
||||
* @return 结果
|
||||
*/
|
||||
public static boolean contains(String value) {
|
||||
if (value == null) {
|
||||
return false;
|
||||
}
|
||||
boolean ret = true;
|
||||
for (HashFunction f : HASH_FUNCS) {
|
||||
ret = BIT_SET.get(f.hash(value));
|
||||
//一个 hash 函数返回 false 则跳出循环
|
||||
if (!ret) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* 模拟用户是不是会员,或用户在不在线。。。
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
for (int i = 0; i < SEEDS.length; i++) {
|
||||
HASH_FUNCS[i] = new HashFunction(DEFAULT_SIZE, SEEDS[i]);
|
||||
}
|
||||
|
||||
// 添加1亿数据
|
||||
for (int i = 0; i < 1_0000_0000; i++) {
|
||||
add(String.valueOf(i));
|
||||
}
|
||||
String id = "123456789";
|
||||
add(id);
|
||||
|
||||
System.out.println(contains(id)); // true
|
||||
System.out.println("" + contains("234567890")); //false
|
||||
}
|
||||
}
|
||||
|
||||
class HashFunction {
|
||||
private final int size;
|
||||
private final int seed;
|
||||
|
||||
public HashFunction(int size, int seed) {
|
||||
this.size = size;
|
||||
this.seed = seed;
|
||||
}
|
||||
|
||||
public int hash(String value) {
|
||||
int result = 0;
|
||||
int len = value.length();
|
||||
for (int i = 0; i < len; i++) {
|
||||
result = seed * result + value.charAt(i);
|
||||
}
|
||||
int r = (size - 1) & result;
|
||||
return (size - 1) & result;
|
||||
}
|
||||
}
|
||||
312
budd-common/src/main/java/io/github/ehlxr/util/RedisUtil.java
Normal file
312
budd-common/src/main/java/io/github/ehlxr/util/RedisUtil.java
Normal file
@@ -0,0 +1,312 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2021 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.util;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.redis.core.ListOperations;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.core.script.DefaultRedisScript;
|
||||
import org.springframework.data.redis.core.script.RedisScript;
|
||||
import org.springframework.scripting.support.StaticScriptSource;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* redis 操作
|
||||
*
|
||||
* @author ehlxr
|
||||
* @since 2021-08-29 18:32.
|
||||
*/
|
||||
@Component
|
||||
public class RedisUtil {
|
||||
private static final Logger log = LoggerFactory.getLogger(RedisUtil.class);
|
||||
|
||||
/**
|
||||
* 解锁 lua 脚本
|
||||
*/
|
||||
private static final String UNLOCK = "if (redis.call('hexists', KEYS[1], ARGV[1]) == 0) then " +
|
||||
"return nil; " +
|
||||
"end; " +
|
||||
"local counter = redis.call('hincrby', KEYS[1], ARGV[1], -1); " +
|
||||
"if (counter > 0) then " +
|
||||
"return 0; " +
|
||||
"else " +
|
||||
"redis.call('del', KEYS[1]); " +
|
||||
"return 1; " +
|
||||
"end; " +
|
||||
"return nil;";
|
||||
/**
|
||||
* 锁前缀
|
||||
*/
|
||||
private static final String LOCK_PREFIX = "LOCK_";
|
||||
/**
|
||||
* 默认重试次数
|
||||
*/
|
||||
private static final Integer DEFAULT_RETRIES = 1;
|
||||
/**
|
||||
* 默认 10毫秒
|
||||
*/
|
||||
private static final Long DEFAULT_INTERVAL = 10L;
|
||||
/**
|
||||
* 加锁 lua 脚本
|
||||
*/
|
||||
private static final String LOCK = "if (redis.call('exists', KEYS[1]) == 0) then " +
|
||||
"redis.call('hset', KEYS[1], ARGV[2], 1); " +
|
||||
"redis.call('pexpire', KEYS[1], ARGV[1]); " +
|
||||
"return 1; " +
|
||||
"end; " +
|
||||
"if (redis.call('hexists', KEYS[1], ARGV[2]) == 1) then " +
|
||||
"redis.call('hincrby', KEYS[1], ARGV[2], 1); " +
|
||||
"redis.call('pexpire', KEYS[1], ARGV[1]); " +
|
||||
"return 1; " +
|
||||
"end; " +
|
||||
"return 0;";
|
||||
private static RedisTemplate<String, String> redisTemplate;
|
||||
|
||||
/**
|
||||
* 释放分布式锁时使用的 lua 脚本,保证原子性
|
||||
* <p>
|
||||
* if (redis.call('get', KEYS[1]) == ARGV[1])
|
||||
* then
|
||||
* return redis.call('del', KEYS[1])
|
||||
* else
|
||||
* return 0
|
||||
* end
|
||||
*/
|
||||
private static final String RELEASE_LOCK_LUA = "if (redis.call('get', KEYS[1]) == ARGV[1]) then return redis.call('del', KEYS[1]) else return 0 end";
|
||||
|
||||
/**
|
||||
* 滑动窗口限流使用的 lua 脚本,保证原子性
|
||||
* <p>
|
||||
* local key = KEYS[1];
|
||||
* local index = tonumber(ARGV[1]);
|
||||
* local time_window = tonumber(ARGV[2]);
|
||||
* local now_time = tonumber(ARGV[3]);
|
||||
* local far_time = redis.call('lindex', key, index);
|
||||
* if (not far_time)
|
||||
* then
|
||||
* redis.call('lpush', key, now_time);
|
||||
* redis.call('pexpire', key, time_window+1000);
|
||||
* return 1;
|
||||
* end
|
||||
* if (now_time - far_time > time_window)
|
||||
* then
|
||||
* redis.call('rpop', key);
|
||||
* redis.call('lpush', key, now_time);
|
||||
* redis.call('pexpire', key, time_window+1000);
|
||||
* return 1;
|
||||
* else
|
||||
* return 0;
|
||||
* end
|
||||
*/
|
||||
private static final String SLIDE_WINDOW_LUA = "local key = KEYS[1];\n" + "local index = tonumber(ARGV[1]);\n" + "local time_window = tonumber(ARGV[2]);\n" + "local now_time = tonumber(ARGV[3]);\n" + "local far_time = redis.call('lindex', key, index);\n" + "if (not far_time)\n" + "then\n" + " redis.call('lpush', key, now_time);\n" + " redis.call('pexpire', key, time_window+1000);\n" + " return 1;\n" + "end\n" + "\n" + "if (now_time - far_time > time_window)\n" + "then\n" + " redis.call('rpop', key);\n" + " redis.call('lpush', key, now_time);\n" + " redis.call('pexpire', key, time_window+1000);\n" + " return 1;\n" + "else\n" + " return 0;\n" + "end";
|
||||
|
||||
/**
|
||||
* 获取分布式锁
|
||||
*
|
||||
* @param key key
|
||||
* @param value value,需要保证全局唯一,用来删除分布式锁时判断身份使用
|
||||
* @param expireTime 锁过期时间,毫秒,防止业务崩溃未删除锁,导致死锁
|
||||
* @return 是否获取成功锁
|
||||
*/
|
||||
public static boolean getDistributedLock(String key, String value, long expireTime) {
|
||||
boolean result = false;
|
||||
try {
|
||||
Boolean set = redisTemplate.opsForValue().setIfAbsent(key, value, expireTime, TimeUnit.MILLISECONDS);
|
||||
result = set == null || set;
|
||||
log.info("getLock redis key: {}, value: {}, expireTime: {}, result: {}", key, value, expireTime, result);
|
||||
} catch (Exception e) {
|
||||
log.error("getLock redis key: {}, value: {}, expireTime: {}", key, value, expireTime, e);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 释放分布式锁
|
||||
*
|
||||
* @param key key
|
||||
* @param value value,需要和获取锁时传入的一致
|
||||
* @return 是否释放成功锁
|
||||
*/
|
||||
public static boolean releaseDistributedLock(String key, String value) {
|
||||
Long execute = null;
|
||||
try {
|
||||
RedisScript<Long> redisScript = new DefaultRedisScript<>(RELEASE_LOCK_LUA, Long.class);
|
||||
execute = redisTemplate.execute(redisScript, Collections.singletonList(key), value);
|
||||
log.debug("releaseLock redis key: {}, value: {}, result: {}", key, value, execute);
|
||||
} catch (Exception e) {
|
||||
log.error("releaseLock redis key: {}, value: {}", key, value, e);
|
||||
}
|
||||
return Long.valueOf(1L).equals(execute);
|
||||
}
|
||||
|
||||
/**
|
||||
* 分布式限流队列,在时间窗口内(包含该时间点),判断是否达到限流的阀值
|
||||
* 本接口实现的方法通过加锁避免并发问题,性能不高。只是为了说明限流逻辑如何实现
|
||||
*
|
||||
* @param key key
|
||||
* @param count 限流阀值
|
||||
* @param timeWindow 限流时间窗口
|
||||
* @return 是否允许通过(通过即不进行限流)
|
||||
*/
|
||||
public static synchronized boolean slideWindow(String key, int count, long timeWindow) {
|
||||
try {
|
||||
long nowTime = System.currentTimeMillis();
|
||||
ListOperations<String, String> list = redisTemplate.opsForList();
|
||||
String farTime = list.index(key, count - 1);
|
||||
if (farTime == null) {
|
||||
list.leftPush(key, String.valueOf(nowTime));
|
||||
redisTemplate.expire(key, timeWindow + 1000L, TimeUnit.MILLISECONDS);
|
||||
return true;
|
||||
}
|
||||
if (nowTime - Long.parseLong(farTime) > timeWindow) {
|
||||
list.rightPop(key);
|
||||
list.leftPush(key, String.valueOf(nowTime));
|
||||
redisTemplate.expire(key, timeWindow + 1000L, TimeUnit.MILLISECONDS);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} catch (Exception e) {
|
||||
log.error("", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 分布式限流队列,在时间窗口内(包含该时间点),判断是否达到限流的阀值
|
||||
* 本接口实现的方法通过 Lua 脚本避免并发问题,性能较高。
|
||||
*
|
||||
* @param key key
|
||||
* @param count 限流阀值
|
||||
* @param timeWindow 限流时间窗口
|
||||
* @return 是否允许通过(通过即不进行限流)
|
||||
*/
|
||||
public static boolean slideWindowLua(String key, int count, long timeWindow) {
|
||||
if (count <= 0 || timeWindow <= 0) {
|
||||
return false;
|
||||
}
|
||||
Long execute = null;
|
||||
try {
|
||||
RedisScript<Long> redisScript = new DefaultRedisScript<>(SLIDE_WINDOW_LUA, Long.class);
|
||||
execute = redisTemplate.execute(redisScript, Collections.singletonList(key), String.valueOf(count - 1), String.valueOf(timeWindow), String.valueOf(System.currentTimeMillis()));
|
||||
log.debug("slideWindowLua redis key: {}, count: {}, timeWindow: {}, result: {}", key, count, timeWindow, execute);
|
||||
} catch (Exception e) {
|
||||
log.error("slideWindowLua redis key: {}, count: {}, timeWindow: {}", key, count, timeWindow, e);
|
||||
}
|
||||
return Long.valueOf(1L).equals(execute);
|
||||
}
|
||||
|
||||
/**
|
||||
* 加锁 不可重入
|
||||
*
|
||||
* @param timeout 毫秒
|
||||
*/
|
||||
public static Boolean lock(String key, long timeout) {
|
||||
return redisTemplate.opsForValue().setIfAbsent(LOCK_PREFIX + key, "1", timeout, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解锁 不可重入
|
||||
*/
|
||||
public static Boolean unlock(String key) {
|
||||
return redisTemplate.delete(LOCK_PREFIX + key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 加锁
|
||||
*
|
||||
* @param reentrantId 重入Id
|
||||
* 超时时间 毫秒ms
|
||||
*/
|
||||
public static Boolean lock(String key, String reentrantId, long timeout) {
|
||||
return lock(key, reentrantId, timeout, DEFAULT_RETRIES);
|
||||
}
|
||||
|
||||
/**
|
||||
* 加锁
|
||||
*
|
||||
* @param reentrantId 重入Id
|
||||
* 超时时间 毫秒ms
|
||||
* @param retries 重试次数
|
||||
*/
|
||||
public static Boolean lock(String key, String reentrantId, long timeout, int retries) {
|
||||
return lock(key, reentrantId, timeout, retries, DEFAULT_INTERVAL);
|
||||
}
|
||||
|
||||
/**
|
||||
* 加锁
|
||||
*
|
||||
* @param reentrantId 重入Id
|
||||
* 超时时间 毫秒ms
|
||||
* @param retries 重试次数
|
||||
* @param interval 每次重试间隔时间 毫秒
|
||||
*/
|
||||
public static Boolean lock(String key, String reentrantId, long timeout, int retries, long interval) {
|
||||
String lockKey = LOCK_PREFIX + key;
|
||||
DefaultRedisScript<Long> script = new DefaultRedisScript<>();
|
||||
script.setResultType(Long.class);
|
||||
script.setScriptSource(new StaticScriptSource(LOCK));
|
||||
for (int i = 0; i < retries; i++) {
|
||||
Object result = redisTemplate.execute(script, Collections.singletonList(lockKey), String.valueOf(timeout), reentrantId);
|
||||
if (Objects.nonNull(result) && Objects.equals(1L, Long.valueOf(result.toString()))) {
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
TimeUnit.MILLISECONDS.sleep(interval);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解锁
|
||||
*
|
||||
* @param reentrantId 重入ID
|
||||
*/
|
||||
public static Boolean unlock(String key, String reentrantId) {
|
||||
String lockKey = LOCK_PREFIX + key;
|
||||
DefaultRedisScript<Long> script = new DefaultRedisScript<>();
|
||||
script.setResultType(Long.class);
|
||||
script.setScriptSource(new StaticScriptSource(UNLOCK));
|
||||
Object result = redisTemplate.execute(script, Collections.singletonList(lockKey), reentrantId);
|
||||
if (Objects.isNull(result)) {
|
||||
return null;
|
||||
}
|
||||
return Objects.equals(1L, Long.valueOf(result.toString()));
|
||||
}
|
||||
|
||||
@Autowired
|
||||
public void setRedisTemplate(RedisTemplate<String, String> redisTemplate) {
|
||||
RedisUtil.redisTemplate = redisTemplate;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2020 xrv <xrg@live.com>
|
||||
* Copyright © 2020 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -22,9 +22,11 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.utils;
|
||||
package io.github.ehlxr.util;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import io.github.ehlxr.common.Constant;
|
||||
import org.slf4j.MDC;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
@@ -48,11 +50,11 @@ public class SendAlarmUtil {
|
||||
/**
|
||||
* 异步发送预警信息
|
||||
*
|
||||
* @param msg 预警信息
|
||||
* @param action {@link BiConsumer} 完成后回调函数式接口
|
||||
* @param message 预警信息
|
||||
* @param action {@link BiConsumer} 完成后回调函数式接口
|
||||
*/
|
||||
public static void send(String msg, BiConsumer<? super String, ? super Throwable> action) {
|
||||
// String msg = String.format("%s\ntraceid: %s", msg, MDC.get(Constants.LOG_TRACE_ID));
|
||||
public static void send(String message, BiConsumer<? super String, ? super Throwable> action) {
|
||||
String msg = String.format("%s\ntraceid: %s", message, MDC.get(Constant.LOG_TRACE_ID));
|
||||
|
||||
CompletableFuture.supplyAsync(() -> {
|
||||
Objects.requireNonNull(dingtalkUrl, "SendAlarmUtil not init.");
|
||||
@@ -79,10 +81,10 @@ public class SendAlarmUtil {
|
||||
.trap(System.out::println)
|
||||
.run();
|
||||
|
||||
send("dsfsdf",
|
||||
send("hello",
|
||||
(t, u) -> System.out.println("send exception message to dingtalk result " + t + ". " + u));
|
||||
|
||||
System.out.println("000000");
|
||||
System.out.println("do other something....");
|
||||
|
||||
Thread.sleep(2000);
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2020 xrv <xrg@live.com>
|
||||
* Copyright © 2020 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -22,7 +22,7 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.utils;
|
||||
package io.github.ehlxr.util;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
@@ -84,6 +84,163 @@ public interface Try {
|
||||
return new TryRunnable(runnable);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"ConstantConditions", "Convert2MethodRef"})
|
||||
static void main(String[] args) {
|
||||
System.out.println("------------有返回值,无入参----------------");
|
||||
// 有返回值,无入参
|
||||
String param = "hello";
|
||||
Long result = Try.of(() -> Long.valueOf(param)).get(0L);
|
||||
System.out.println("Long.valueOf 1: " + result);
|
||||
|
||||
result = Try.of(() -> Long.valueOf(param)).get();
|
||||
System.out.println("Long.valueOf 2: " + result);
|
||||
|
||||
System.out.println("------------有返回值,有入参----------------");
|
||||
// 有返回值,有入参
|
||||
result = Try.<Map<String, String>, Long>of(s -> Long.valueOf(s.get("k1")))
|
||||
.apply(ImmutableMap.of("k1", param))
|
||||
.trap(e -> System.out.println("Long.valueOf exception: " + e.getMessage()))
|
||||
.andFinally(() -> System.out.println("This message will ignore."))
|
||||
.andFinally(s -> {
|
||||
Map<String, Object> returnMap = JsonUtils.string2Obj(JsonUtils.obj2String(s), new TypeReference<Map<String, Object>>() {
|
||||
});
|
||||
System.out.println("Long.valueOf finally run code." + s);
|
||||
// 演示抛异常
|
||||
String k2 = returnMap.get("k2").toString();
|
||||
System.out.println(k2);
|
||||
})
|
||||
.finallyTrap(e -> System.out.println("Long.valueOf finally exception: " + e.getMessage()))
|
||||
.get();
|
||||
System.out.println("Long.valueOf 3: " + result);
|
||||
|
||||
ArrayList<String> list = null;
|
||||
|
||||
System.out.println("-----------无返回值,无入参-----------------");
|
||||
// 无返回值,无入参
|
||||
Try.of(() -> Thread.sleep(-1L))
|
||||
.andFinally(() -> list.clear())
|
||||
// .andFinally(list::clear) //https://stackoverflow.com/questions/37413106/java-lang-nullpointerexception-is-thrown-using-a-method-reference-but-not-a-lamb
|
||||
.run();
|
||||
|
||||
System.out.println("--------------无返回值,有入参--------------");
|
||||
// 无返回值,有入参
|
||||
Try.<String>of(v -> list.add(0, v))
|
||||
.andFinally(s -> System.out.println(s))
|
||||
.accept("hello");
|
||||
}
|
||||
|
||||
class TryRunnable extends Tryable<TryRunnable> {
|
||||
private final ThrowableRunnable runnable;
|
||||
|
||||
protected TryRunnable(ThrowableRunnable runnable) {
|
||||
Objects.requireNonNull(runnable, "No runnable present");
|
||||
this.runnable = runnable;
|
||||
|
||||
super.c = this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算结果
|
||||
*/
|
||||
public void run() {
|
||||
try {
|
||||
runnable.run();
|
||||
} catch (final Throwable e) {
|
||||
Optional.ofNullable(throwConsumer).ifPresent(tc -> tc.accept(e));
|
||||
} finally {
|
||||
doFinally();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class TrySupplier<R> extends Tryable<TrySupplier<R>> {
|
||||
private final ThrowableSupplier<? extends R> supplier;
|
||||
|
||||
protected TrySupplier(ThrowableSupplier<? extends R> supplier) {
|
||||
Objects.requireNonNull(supplier, "No supplier present");
|
||||
this.supplier = supplier;
|
||||
|
||||
super.c = this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 如果有异常返回默认值,否则返回计算结果
|
||||
*
|
||||
* @param r 指定默认值
|
||||
* @return 实际值或默认值
|
||||
*/
|
||||
public R get(R r) {
|
||||
try {
|
||||
return supplier.get();
|
||||
} catch (final Throwable e) {
|
||||
Optional.ofNullable(throwConsumer).ifPresent(tc -> tc.accept(e));
|
||||
return r;
|
||||
} finally {
|
||||
doFinally();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 如果有异常返回 null,否则返回计算结果
|
||||
*
|
||||
* @return 实际值或 null
|
||||
*/
|
||||
public R get() {
|
||||
try {
|
||||
return supplier.get();
|
||||
} catch (final Throwable e) {
|
||||
Optional.ofNullable(throwConsumer).ifPresent(tc -> tc.accept(e));
|
||||
return null;
|
||||
} finally {
|
||||
doFinally();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
interface ThrowableConsumer<P> {
|
||||
/**
|
||||
* Performs this operation on the given argument.
|
||||
*
|
||||
* @param p the input argument
|
||||
* @throws Throwable throwable
|
||||
*/
|
||||
void accept(P p) throws Throwable;
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
interface ThrowableSupplier<R> {
|
||||
/**
|
||||
* Gets a result.
|
||||
*
|
||||
* @return a result
|
||||
* @throws Throwable throwable
|
||||
*/
|
||||
R get() throws Throwable;
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
interface ThrowableRunnable {
|
||||
/**
|
||||
* Performs this operation
|
||||
*
|
||||
* @throws Throwable throwable
|
||||
*/
|
||||
void run() throws Throwable;
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
interface ThrowableFunction<P, R> {
|
||||
/**
|
||||
* Applies this function to the given argument.
|
||||
*
|
||||
* @param p the function argument
|
||||
* @return the function result
|
||||
* @throws Throwable throwable
|
||||
*/
|
||||
R apply(P p) throws Throwable;
|
||||
}
|
||||
|
||||
abstract class Tryable<C> {
|
||||
Consumer<? super Throwable> throwConsumer;
|
||||
ThrowableRunnable finallyRunnable;
|
||||
@@ -175,74 +332,6 @@ public interface Try {
|
||||
}
|
||||
}
|
||||
|
||||
class TryRunnable extends Tryable<TryRunnable> {
|
||||
private final ThrowableRunnable runnable;
|
||||
|
||||
protected TryRunnable(ThrowableRunnable runnable) {
|
||||
Objects.requireNonNull(runnable, "No runnable present");
|
||||
this.runnable = runnable;
|
||||
|
||||
super.c = this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算结果
|
||||
*/
|
||||
public void run() {
|
||||
try {
|
||||
runnable.run();
|
||||
} catch (final Throwable e) {
|
||||
Optional.ofNullable(throwConsumer).ifPresent(tc -> tc.accept(e));
|
||||
} finally {
|
||||
doFinally();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class TrySupplier<R> extends Tryable<TrySupplier<R>> {
|
||||
private final ThrowableSupplier<? extends R> supplier;
|
||||
|
||||
protected TrySupplier(ThrowableSupplier<? extends R> supplier) {
|
||||
Objects.requireNonNull(supplier, "No supplier present");
|
||||
this.supplier = supplier;
|
||||
|
||||
super.c = this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 如果有异常返回默认值,否则返回计算结果
|
||||
*
|
||||
* @param r 指定默认值
|
||||
* @return 实际值或默认值
|
||||
*/
|
||||
public R get(R r) {
|
||||
try {
|
||||
return supplier.get();
|
||||
} catch (final Throwable e) {
|
||||
Optional.ofNullable(throwConsumer).ifPresent(tc -> tc.accept(e));
|
||||
return r;
|
||||
} finally {
|
||||
doFinally();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 如果有异常返回 null,否则返回计算结果
|
||||
*
|
||||
* @return 实际值或 null
|
||||
*/
|
||||
public R get() {
|
||||
try {
|
||||
return supplier.get();
|
||||
} catch (final Throwable e) {
|
||||
Optional.ofNullable(throwConsumer).ifPresent(tc -> tc.accept(e));
|
||||
return null;
|
||||
} finally {
|
||||
doFinally();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class TryConsumer<P> extends Tryable<TryConsumer<P>> {
|
||||
private final ThrowableConsumer<? super P> consumer;
|
||||
|
||||
@@ -335,93 +424,4 @@ public interface Try {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
interface ThrowableConsumer<P> {
|
||||
/**
|
||||
* Performs this operation on the given argument.
|
||||
*
|
||||
* @param p the input argument
|
||||
* @throws Throwable throwable
|
||||
*/
|
||||
void accept(P p) throws Throwable;
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
interface ThrowableSupplier<R> {
|
||||
/**
|
||||
* Gets a result.
|
||||
*
|
||||
* @return a result
|
||||
* @throws Throwable throwable
|
||||
*/
|
||||
R get() throws Throwable;
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
interface ThrowableRunnable {
|
||||
/**
|
||||
* Performs this operation
|
||||
*
|
||||
* @throws Throwable throwable
|
||||
*/
|
||||
void run() throws Throwable;
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
interface ThrowableFunction<P, R> {
|
||||
/**
|
||||
* Applies this function to the given argument.
|
||||
*
|
||||
* @param p the function argument
|
||||
* @return the function result
|
||||
* @throws Throwable throwable
|
||||
*/
|
||||
R apply(P p) throws Throwable;
|
||||
}
|
||||
|
||||
@SuppressWarnings({"ConstantConditions", "Convert2MethodRef"})
|
||||
static void main(String[] args) {
|
||||
System.out.println("------------有返回值,无入参----------------");
|
||||
// 有返回值,无入参
|
||||
String param = "hello";
|
||||
Long result = Try.of(() -> Long.valueOf(param)).get(0L);
|
||||
System.out.println("Long.valueOf 1: " + result);
|
||||
|
||||
result = Try.of(() -> Long.valueOf(param)).get();
|
||||
System.out.println("Long.valueOf 2: " + result);
|
||||
|
||||
System.out.println("------------有返回值,有入参----------------");
|
||||
// 有返回值,有入参
|
||||
result = Try.<Map<String, String>, Long>of(s -> Long.valueOf(s.get("k1")))
|
||||
.apply(ImmutableMap.of("k1", param))
|
||||
.trap(e -> System.out.println("Long.valueOf exception: " + e.getMessage()))
|
||||
.andFinally(() -> System.out.println("This message will ignore."))
|
||||
.andFinally(s -> {
|
||||
Map<String, Object> returnMap = JsonUtils.string2Obj(JsonUtils.obj2String(s), new TypeReference<Map<String, Object>>() {
|
||||
});
|
||||
System.out.println("Long.valueOf finally run code." + s);
|
||||
// 演示抛异常
|
||||
String k2 = returnMap.get("k2").toString();
|
||||
System.out.println(k2);
|
||||
})
|
||||
.finallyTrap(e -> System.out.println("Long.valueOf finally exception: " + e.getMessage()))
|
||||
.get();
|
||||
System.out.println("Long.valueOf 3: " + result);
|
||||
|
||||
ArrayList<String> list = null;
|
||||
|
||||
System.out.println("-----------无返回值,无入参-----------------");
|
||||
// 无返回值,无入参
|
||||
Try.of(() -> Thread.sleep(-1L))
|
||||
.andFinally(() -> list.clear())
|
||||
// .andFinally(list::clear) //https://stackoverflow.com/questions/37413106/java-lang-nullpointerexception-is-thrown-using-a-method-reference-but-not-a-lamb
|
||||
.run();
|
||||
|
||||
System.out.println("--------------无返回值,有入参--------------");
|
||||
// 无返回值,有入参
|
||||
Try.<String>of(v -> list.add(0, v))
|
||||
.andFinally(s -> System.out.println(s))
|
||||
.accept("hello");
|
||||
}
|
||||
}
|
||||
18
budd-demo/pom.xml
Normal file
18
budd-demo/pom.xml
Normal file
@@ -0,0 +1,18 @@
|
||||
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>io.github.ehlxr</groupId>
|
||||
<artifactId>budd</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>budd-demo</artifactId>
|
||||
<name>budd-demo</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.github.ehlxr</groupId>
|
||||
<artifactId>budd-common</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
123
budd-demo/src/main/java/io/github/ehlxr/File.java
Normal file
123
budd-demo/src/main/java/io/github/ehlxr/File.java
Normal file
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2023 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import io.github.ehlxr.util.JsonUtils;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author ehlxr
|
||||
* @since 2023-03-15 16:08.
|
||||
*/
|
||||
public class File {
|
||||
public static void main(String[] args) {
|
||||
|
||||
String str0 = "{\"mode\":2,\"isIOSAutoPlay\":true,\"isAndroidAutoPlay\":true,\"isShowDefaultPic\":true,\"isShowWeChatCircleShareButton\":true,\"isForceUpdate\":true,\"isGzhFullScreen\":true,\"isGzhAutoPlay\":true,\"isSharePageFullScreen\":true,\"isSharePageAutoPlay\":true,\"distDir\":\"dist_1_3_4\",\"distNewDir\":\"dist_1_3_4\",\"videoShareFriendPath\":\"pages/user-videos\",\"videoShareMomentPath\":\"pages/user-videos\",\"userShareFriendPath\":\"pages/mine/mine-info\",\"userShareMomentPath\":\"pages/mine/mine-info\",\"addMaskGuide\":false,\"addMaskDayInterval\":2,\"addMaskMaxCount\":3,\"addMaskDuration\":10,\"addBubbleGuide\":true,\"addBubbleDayInterval\":2,\"addBubbleMaxCount\":3,\"addBubbleDuration\":10,\"shortShareFriendPath\":\"pages/shortvideo/shortvideo\",\"shortShareMomentPath\":\"pages/shortvideo/shortvideo\",\"barrageUiShow\":true,\"barrageSwitchOpen\":true,\"sortType\":2,\"barrageInputStates\":0,\"videoBarrageSwitch\":true,\"isOpenUnUploadReason\":false,\"isOpenUploadReason\":false,\"homeTabUserInfoPanel\":true,\"isShowDialogOnUpdate\":false,\"fundebug\":false,\"barrageSection\":30,\"isUploadPageLoadData\":1,\"showPayTipsMaxCount\":2,\"openFollowRemind\":true,\"dayFollowRemind\":1,\"totalFollowRemind\":3,\"sharePageRoute\":1,\"shouldFixWxRenderBug\":1,\"defaultSearchText\":\"搜索你想看的\",\"isShowDetailPageGuide\":false,\"gzhOtherVideoCount\":4,\"otherVideoCount\":10,\"shareVideoDialogCount\":2,\"videoShare2PageNotFoundPercent\":0,\"categoryRouterPercent\":100,\"fixed707Upload\":1,\"albumAvailable\":1,\"csVideoShareH5Title\":\"\",\"activityMoney\":2.88,\"privacyAgreementUrl\":\"https://rescdn.piaoquantv.com/agreement/videoagreement.html\",\"serviceAgreementUrl\":\"https://rescdn.piaoquantv.com/agreement/videoservice.html\",\"h5Domain\":\"https://vlogh5.piaoquantv.com/\",\"sendVideoIgnoreAuthorizeMobile\":1,\"sendVideoPostAuthorizeMobile\":1,\"noGrantLoginEnable\":1}";
|
||||
String str2 = "{\"mode\":2,\"isIOSAutoPlay\":true,\"isAndroidAutoPlay\":true,\"isShowDefaultPic\":true,\"isShowWeChatCircleShareButton\":true,\"isForceUpdate\":true,\"isGzhFullScreen\":true,\"isGzhAutoPlay\":true,\"isSharePageFullScreen\":true,\"isSharePageAutoPlay\":true,\"distDir\":\"dist_1_3_4\",\"distNewDir\":\"dist_1_3_4\",\"videoShareFriendPath\":\"pages/user-videos\",\"videoShareMomentPath\":\"pages/user-videos\",\"userShareFriendPath\":\"pages/mine/mine-info\",\"userShareMomentPath\":\"pages/mine/mine-info\",\"addMaskGuide\":false,\"addMaskDayInterval\":2,\"addMaskMaxCount\":3,\"addMaskDuration\":10,\"addBubbleGuide\":true,\"addBubbleDayInterval\":2,\"addBubbleMaxCount\":3,\"addBubbleDuration\":10,\"shortShareFriendPath\":\"pages/shortvideo/shortvideo\",\"shortShareMomentPath\":\"pages/shortvideo/shortvideo\",\"barrageUiShow\":true,\"barrageSwitchOpen\":true,\"sortType\":2,\"barrageInputStates\":0,\"videoBarrageSwitch\":true,\"isOpenUnUploadReason\":false,\"isOpenUploadReason\":false,\"homeTabUserInfoPanel\":true,\"isShowDialogOnUpdate\":false,\"fundebug\":false,\"barrageSection\":30,\"isUploadPageLoadData\":1,\"showPayTipsMaxCount\":2,\"openFollowRemind\":true,\"dayFollowRemind\":1,\"totalFollowRemind\":3,\"sharePageRoute\":1,\"shouldFixWxRenderBug\":1,\"defaultSearchText\":\"搜索你想看的\",\"isShowDetailPageGuide\":false,\"gzhOtherVideoCount\":4,\"otherVideoCount\":10,\"shareVideoDialogCount\":2,\"videoShare2PageNotFoundPercent\":0,\"categoryRouterPercent\":100,\"fixed707Upload\":1,\"albumAvailable\":1,\"csVideoShareH5Title\":\"\",\"activityMoney\":2.88,\"privacyAgreementUrl\":\"https://weapppiccdn.yishihui.com/resources/agreements/videoagreement.html\",\"serviceAgreementUrl\":\"https://weapppiccdn.yishihui.com/resources/agreements/videoservice.html\"}";
|
||||
String str3 = "{\"mode\":2,\"isIOSAutoPlay\":true,\"isAndroidAutoPlay\":true,\"isShowDefaultPic\":true,\"isShowWeChatCircleShareButton\":true,\"isForceUpdate\":true,\"isGzhFullScreen\":true,\"isGzhAutoPlay\":true,\"isSharePageFullScreen\":true,\"isSharePageAutoPlay\":true,\"distDir\":\"dist_1_3_4\",\"distNewDir\":\"dist_1_3_4\",\"videoShareFriendPath\":\"pages/user-videos\",\"videoShareMomentPath\":\"pages/user-videos\",\"userShareFriendPath\":\"pages/mine/mine-info\",\"userShareMomentPath\":\"pages/mine/mine-info\",\"addMaskGuide\":false,\"addMaskDayInterval\":2,\"addMaskMaxCount\":3,\"addMaskDuration\":10,\"addBubbleGuide\":true,\"addBubbleDayInterval\":2,\"addBubbleMaxCount\":3,\"addBubbleDuration\":10,\"shortShareFriendPath\":\"pages/shortvideo/shortvideo\",\"shortShareMomentPath\":\"pages/shortvideo/shortvideo\",\"barrageUiShow\":true,\"barrageSwitchOpen\":true,\"sortType\":2,\"barrageInputStates\":0,\"videoBarrageSwitch\":true,\"isOpenUnUploadReason\":false,\"isOpenUploadReason\":false,\"homeTabUserInfoPanel\":true,\"isShowDialogOnUpdate\":false,\"fundebug\":false,\"barrageSection\":30,\"isUploadPageLoadData\":1,\"showPayTipsMaxCount\":2,\"openFollowRemind\":true,\"dayFollowRemind\":1,\"totalFollowRemind\":3,\"sharePageRoute\":1,\"shouldFixWxRenderBug\":1,\"defaultSearchText\":\"搜索你想看的\",\"isShowDetailPageGuide\":false,\"gzhOtherVideoCount\":4,\"otherVideoCount\":10,\"shareVideoDialogCount\":2,\"videoShare2PageNotFoundPercent\":0,\"categoryRouterPercent\":100,\"fixed707Upload\":1,\"albumAvailable\":1,\"csVideoShareH5Title\":\"\",\"activityMoney\":2.88,\"privacyAgreementUrl\":\"https://weapppiccdn.yishihui.com/resources/agreements/videoagreement.html\",\"serviceAgreementUrl\":\"https://weapppiccdn.yishihui.com/resources/agreements/videoservice.html\"}";
|
||||
String str4 = "{\"mode\":2,\"isIOSAutoPlay\":true,\"isAndroidAutoPlay\":true,\"isShowDefaultPic\":true,\"isShowWeChatCircleShareButton\":true,\"isForceUpdate\":true,\"isGzhFullScreen\":true,\"isGzhAutoPlay\":true,\"isSharePageFullScreen\":true,\"isSharePageAutoPlay\":true,\"distDir\":\"dist_1_3_4\",\"distNewDir\":\"dist_1_3_4\",\"videoShareFriendPath\":\"pages/user-videos\",\"videoShareMomentPath\":\"pages/user-videos\",\"userShareFriendPath\":\"pages/mine/mine-info\",\"userShareMomentPath\":\"pages/mine/mine-info\",\"shortShareFriendPath\":\"pages/shortvideo/shortvideo\",\"shortShareMomentPath\":\"pages/shortvideo/shortvideo\",\"addMaskGuide\":false,\"addMaskDayInterval\":2,\"addMaskMaxCount\":3,\"addMaskDuration\":10,\"addBubbleGuide\":true,\"addBubbleDayInterval\":2,\"addBubbleMaxCount\":3,\"addBubbleDuration\":10,\"barrageUiShow\":true,\"barrageSwitchOpen\":true,\"sortType\":2,\"barrageInputStates\":0,\"videoBarrageSwitch\":true,\"isOpenUnUploadReason\":false,\"isOpenUploadReason\":false,\"homeTabUserInfoPanel\":true,\"isShowDialogOnUpdate\":false,\"fundebug\":false,\"barrageSection\":30,\"isUploadPageLoadData\":1,\"showPayTipsMaxCount\":2,\"openFollowRemind\":true,\"dayFollowRemind\":1,\"totalFollowRemind\":3,\"sharePageRoute\":1,\"shouldFixWxRenderBug\":1,\"defaultSearchText\":\"搜索你想看的\",\"isShowDetailPageGuide\":false,\"gzhOtherVideoCount\":4,\"otherVideoCount\":10,\"shareVideoDialogCount\":2,\"videoShare2PageNotFoundPercent\":0,\"categoryRouterPercent\":100,\"fixed707Upload\":1,\"albumAvailable\":1,\"csVideoShareH5Title\":\"\",\"activityMoney\":2.88,\"privacyAgreementUrl\":\"https://rescdn.piaoquantv.com/agreement/videoagreement.html\",\"serviceAgreementUrl\":\"https://rescdn.piaoquantv.com/agreement/videoservice.html\",\"h5Domain\":\"https://vlogh5.piaoquantv.com/\",\"sendVideoIgnoreAuthorizeMobile\":1,\"sendVideoPostAuthorizeMobile\":1,\"noGrantLoginEnable\":1}";
|
||||
String str5 = "{\"mode\":2,\"isIOSAutoPlay\":true,\"isAndroidAutoPlay\":true,\"isShowDefaultPic\":true,\"isShowWeChatCircleShareButton\":true,\"isForceUpdate\":true,\"isGzhFullScreen\":true,\"isGzhAutoPlay\":true,\"isSharePageFullScreen\":true,\"isSharePageAutoPlay\":true,\"distDir\":\"dist_1_3_4\",\"distNewDir\":\"dist_1_3_4\",\"videoShareFriendPath\":\"pages/user-videos\",\"videoShareMomentPath\":\"pages/user-videos\",\"userShareFriendPath\":\"pages/mine/mine-info\",\"userShareMomentPath\":\"pages/mine/mine-info\",\"shortShareFriendPath\":\"pages/shortvideo/shortvideo\",\"shortShareMomentPath\":\"pages/shortvideo/shortvideo\",\"addMaskGuide\":false,\"addMaskDayInterval\":2,\"addMaskMaxCount\":3,\"addMaskDuration\":10,\"addBubbleGuide\":true,\"addBubbleDayInterval\":2,\"addBubbleMaxCount\":3,\"addBubbleDuration\":10,\"barrageUiShow\":true,\"barrageSwitchOpen\":true,\"sortType\":2,\"barrageInputStates\":0,\"videoBarrageSwitch\":true,\"isOpenUnUploadReason\":false,\"isOpenUploadReason\":false,\"homeTabUserInfoPanel\":true,\"isShowDialogOnUpdate\":false,\"fundebug\":false,\"barrageSection\":30,\"isUploadPageLoadData\":1,\"showPayTipsMaxCount\":2,\"openFollowRemind\":true,\"dayFollowRemind\":1,\"totalFollowRemind\":3,\"sharePageRoute\":1,\"shouldFixWxRenderBug\":1,\"defaultSearchText\":\"搜索你想看的\",\"isShowDetailPageGuide\":false,\"gzhOtherVideoCount\":4,\"otherVideoCount\":10,\"shareVideoDialogCount\":2,\"videoShare2PageNotFoundPercent\":0,\"categoryRouterPercent\":100,\"fixed707Upload\":1,\"albumAvailable\":1,\"privacyAgreementUrl\":\"https://rescdn.piaoquantv.com/agreement/videoagreement.html\",\"serviceAgreementUrl\":\"https://rescdn.piaoquantv.com/agreement/videoservice.html\",\"h5Domain\":\"https://vlogh5.piaoquantv.com/\",\"sendVideoIgnoreAuthorizeMobile\":1,\"sendVideoPostAuthorizeMobile\":1,\"noGrantLoginEnable\":1}";
|
||||
String str6 = "{\"mode\":2,\"isIOSAutoPlay\":true,\"isAndroidAutoPlay\":true,\"isShowDefaultPic\":true,\"isShowWeChatCircleShareButton\":true,\"isForceUpdate\":true,\"isGzhFullScreen\":true,\"isGzhAutoPlay\":true,\"isSharePageFullScreen\":true,\"isSharePageAutoPlay\":true,\"distDir\":\"dist_1_3_4\",\"distNewDir\":\"dist_1_3_4\",\"videoShareFriendPath\":\"pages/user-videos\",\"videoShareMomentPath\":\"pages/user-videos\",\"userShareFriendPath\":\"pages/mine/mine-info\",\"userShareMomentPath\":\"pages/mine/mine-info\",\"addMaskGuide\":false,\"addMaskDayInterval\":2,\"addMaskMaxCount\":3,\"addMaskDuration\":10,\"addBubbleGuide\":true,\"addBubbleDayInterval\":2,\"addBubbleMaxCount\":3,\"addBubbleDuration\":10,\"shortShareFriendPath\":\"pages/shortvideo/shortvideo\",\"shortShareMomentPath\":\"pages/shortvideo/shortvideo\",\"barrageUiShow\":true,\"barrageSwitchOpen\":true,\"sortType\":2,\"barrageInputStates\":0,\"videoBarrageSwitch\":true,\"isOpenUnUploadReason\":false,\"isOpenUploadReason\":false,\"homeTabUserInfoPanel\":true,\"isShowDialogOnUpdate\":false,\"fundebug\":false,\"barrageSection\":30,\"isUploadPageLoadData\":1,\"showPayTipsMaxCount\":2,\"openFollowRemind\":true,\"dayFollowRemind\":1,\"totalFollowRemind\":3,\"sharePageRoute\":1,\"shouldFixWxRenderBug\":1,\"defaultSearchText\":\"搜索你想看的\",\"isShowDetailPageGuide\":false,\"gzhOtherVideoCount\":4,\"otherVideoCount\":10,\"shareVideoDialogCount\":2,\"videoShare2PageNotFoundPercent\":0,\"categoryRouterPercent\":100,\"fixed707Upload\":1,\"albumAvailable\":1,\"csVideoShareH5Title\":\"\",\"activityMoney\":2.88,\"privacyAgreementUrl\":\"https://rescdn.piaoquantv.com/agreement/videoagreement.html\",\"serviceAgreementUrl\":\"https://rescdn.piaoquantv.com/agreement/videoservice.html\",\"h5Domain\":\"https://vlogh5.piaoquantv.com/\",\"sendVideoIgnoreAuthorizeMobile\":1,\"sendVideoPostAuthorizeMobile\":1,\"noGrantLoginEnable\":1}";
|
||||
String str7 = "{\"mode\":2,\"isIOSAutoPlay\":true,\"isAndroidAutoPlay\":true,\"isShowDefaultPic\":true,\"isShowWeChatCircleShareButton\":true,\"isForceUpdate\":true,\"isGzhFullScreen\":true,\"isGzhAutoPlay\":true,\"isSharePageFullScreen\":true,\"isSharePageAutoPlay\":true,\"distDir\":\"dist_1_3_4\",\"distNewDir\":\"dist_1_3_4\",\"videoShareFriendPath\":\"pages/user-videos\",\"videoShareMomentPath\":\"pages/user-videos\",\"userShareFriendPath\":\"pages/mine/mine-info\",\"userShareMomentPath\":\"pages/mine/mine-info\",\"addMaskGuide\":false,\"addMaskDayInterval\":2,\"addMaskMaxCount\":3,\"addMaskDuration\":10,\"addBubbleGuide\":true,\"addBubbleDayInterval\":2,\"addBubbleMaxCount\":3,\"addBubbleDuration\":10,\"shortShareFriendPath\":\"pages/shortvideo/shortvideo\",\"shortShareMomentPath\":\"pages/shortvideo/shortvideo\",\"barrageUiShow\":true,\"barrageSwitchOpen\":true,\"sortType\":2,\"barrageInputStates\":0,\"videoBarrageSwitch\":true,\"isOpenUnUploadReason\":false,\"isOpenUploadReason\":false,\"homeTabUserInfoPanel\":true,\"isShowDialogOnUpdate\":false,\"fundebug\":false,\"barrageSection\":30,\"isUploadPageLoadData\":1,\"showPayTipsMaxCount\":2,\"openFollowRemind\":true,\"dayFollowRemind\":1,\"totalFollowRemind\":3,\"sharePageRoute\":1,\"shouldFixWxRenderBug\":1,\"defaultSearchText\":\"搜索你想看的\",\"isShowDetailPageGuide\":false,\"gzhOtherVideoCount\":4,\"otherVideoCount\":10,\"shareVideoDialogCount\":2,\"videoShare2PageNotFoundPercent\":0,\"categoryRouterPercent\":100,\"fixed707Upload\":1,\"albumAvailable\":1,\"csVideoShareH5Title\":\"\",\"activityMoney\":2.88,\"privacyAgreementUrl\":\"https://weapppiccdn.yishihui.com/resources/agreements/videoagreement.html\",\"serviceAgreementUrl\":\"https://weapppiccdn.yishihui.com/resources/agreements/videoservice.html\"}";
|
||||
String str10 = "{\"mode\":2,\"isIOSAutoPlay\":true,\"isAndroidAutoPlay\":true,\"isShowDefaultPic\":true,\"isShowWeChatCircleShareButton\":true,\"isForceUpdate\":true,\"isGzhFullScreen\":true,\"isGzhAutoPlay\":true,\"isSharePageFullScreen\":true,\"isSharePageAutoPlay\":true,\"distDir\":\"dist_1_3_4\",\"distNewDir\":\"dist\",\"videoShareFriendPath\":\"pages/user-videos\",\"videoShareMomentPath\":\"pages/user-videos\",\"userShareFriendPath\":\"pages/mine/mine-info\",\"userShareMomentPath\":\"pages/mine/mine-info\",\"shortShareFriendPath\": \"pages/shortvideo/shortvideo\",\"shortShareMomentPath\":\"pages/shortvideo/shortvideo\",\"addMaskGuide\":true,\"addMaskDayInterval\":2,\"addMaskMaxCount\":3,\"addMaskDuration\":10,\"addBubbleGuide\":true,\"addBubbleDayInterval\":2,\"addBubbleMaxCount\":-1,\"addBubbleDuration\":5,\"barrageUiShow\": true,\"barrageSwitchOpen\": true}";
|
||||
String str17 = "{\"mode\":2,\"isIOSAutoPlay\":true,\"isAndroidAutoPlay\":true,\"isShowDefaultPic\":true,\"isShowWeChatCircleShareButton\":true,\"isForceUpdate\":true,\"isGzhFullScreen\":true,\"isGzhAutoPlay\":true,\"isSharePageFullScreen\":true,\"isSharePageAutoPlay\":true,\"distDir\":\"dist_1_3_4\",\"distNewDir\":\"dist_1_3_4\",\"videoShareFriendPath\":\"pages/user-videos\",\"videoShareMomentPath\":\"pages/user-videos\",\"userShareFriendPath\":\"pages/mine/mine-info\",\"userShareMomentPath\":\"pages/mine/mine-info\",\"addMaskGuide\":false,\"addMaskDayInterval\":2,\"addMaskMaxCount\":3,\"addMaskDuration\":10,\"addBubbleGuide\":true,\"addBubbleDayInterval\":2,\"addBubbleMaxCount\":3,\"addBubbleDuration\":10,\"shortShareFriendPath\":\"pages/shortvideo/shortvideo\",\"shortShareMomentPath\":\"pages/shortvideo/shortvideo\",\"barrageUiShow\":true,\"barrageSwitchOpen\":true,\"sortType\":2,\"barrageInputStates\":0,\"videoBarrageSwitch\":true,\"isOpenUnUploadReason\":false,\"isOpenUploadReason\":false,\"homeTabUserInfoPanel\":true,\"isShowDialogOnUpdate\":false,\"fundebug\":false,\"barrageSection\":30,\"isUploadPageLoadData\":1,\"showPayTipsMaxCount\":2,\"openFollowRemind\":true,\"dayFollowRemind\":1,\"totalFollowRemind\":3,\"sharePageRoute\":1,\"shouldFixWxRenderBug\":1,\"defaultSearchText\":\"搜索你想看的\",\"isShowDetailPageGuide\":false,\"gzhOtherVideoCount\":4,\"otherVideoCount\":10,\"shareVideoDialogCount\":2,\"videoShare2PageNotFoundPercent\":0,\"categoryRouterPercent\":100,\"fixed707Upload\":1,\"albumAvailable\":1,\"csVideoShareH5Title\":\"\",\"activityMoney\":2.88,\"privacyAgreementUrl\":\"https://weapppiccdn.yishihui.com/resources/agreements/videoagreement.html\",\"serviceAgreementUrl\":\"https://weapppiccdn.yishihui.com/resources/agreements/videoservice.html\",\"h5Domain\":\"https://vlogh5.piaoquantv.com/\"}";
|
||||
String str18 = "{\"mode\":2,\"isIOSAutoPlay\":true,\"isAndroidAutoPlay\":true,\"isShowDefaultPic\":true,\"isShowWeChatCircleShareButton\":true,\"isForceUpdate\":true,\"isGzhFullScreen\":true,\"isGzhAutoPlay\":true,\"isSharePageFullScreen\":true,\"isSharePageAutoPlay\":true,\"distDir\":\"dist_1_3_4\",\"distNewDir\":\"dist_1_3_4\",\"videoShareFriendPath\":\"pages/user-videos\",\"videoShareMomentPath\":\"pages/user-videos\",\"userShareFriendPath\":\"pages/mine/mine-info\",\"userShareMomentPath\":\"pages/mine/mine-info\",\"addMaskGuide\":false,\"addMaskDayInterval\":2,\"addMaskMaxCount\":3,\"addMaskDuration\":10,\"addBubbleGuide\":true,\"addBubbleDayInterval\":2,\"addBubbleMaxCount\":3,\"addBubbleDuration\":10,\"shortShareFriendPath\":\"pages/shortvideo/shortvideo\",\"shortShareMomentPath\":\"pages/shortvideo/shortvideo\",\"barrageUiShow\":true,\"barrageSwitchOpen\":true,\"sortType\":2,\"barrageInputStates\":0,\"videoBarrageSwitch\":true,\"isOpenUnUploadReason\":false,\"isOpenUploadReason\":false,\"homeTabUserInfoPanel\":true,\"isShowDialogOnUpdate\":false,\"fundebug\":false,\"barrageSection\":30,\"isUploadPageLoadData\":1,\"showPayTipsMaxCount\":2,\"openFollowRemind\":true,\"dayFollowRemind\":1,\"totalFollowRemind\":3,\"sharePageRoute\":1,\"shouldFixWxRenderBug\":1,\"defaultSearchText\":\"搜索你想看的\",\"isShowDetailPageGuide\":false,\"gzhOtherVideoCount\":4,\"otherVideoCount\":10,\"shareVideoDialogCount\":2,\"videoShare2PageNotFoundPercent\":0,\"categoryRouterPercent\":100,\"fixed707Upload\":1,\"albumAvailable\":1,\"csVideoShareH5Title\":\"\",\"activityMoney\":2.88,\"privacyAgreementUrl\":\"https://weapppiccdn.yishihui.com/resources/agreements/videoagreement.html\",\"serviceAgreementUrl\":\"https://weapppiccdn.yishihui.com/resources/agreements/videoservice.html\",\"h5Domain\":\"https://vlogh5.piaoquantv.com/\"}";
|
||||
String str19 = "{\"mode\":2,\"isIOSAutoPlay\":true,\"isAndroidAutoPlay\":true,\"isShowDefaultPic\":true,\"isShowWeChatCircleShareButton\":true,\"isForceUpdate\":true,\"isGzhFullScreen\":true,\"isGzhAutoPlay\":true,\"isSharePageFullScreen\":true,\"isSharePageAutoPlay\":true,\"distDir\":\"dist_1_3_4\",\"distNewDir\":\"dist_1_3_4\",\"videoShareFriendPath\":\"pages/user-videos\",\"videoShareMomentPath\":\"pages/user-videos\",\"userShareFriendPath\":\"pages/mine/mine-info\",\"userShareMomentPath\":\"pages/mine/mine-info\",\"addMaskGuide\":false,\"addMaskDayInterval\":2,\"addMaskMaxCount\":3,\"addMaskDuration\":10,\"addBubbleGuide\":true,\"addBubbleDayInterval\":2,\"addBubbleMaxCount\":3,\"addBubbleDuration\":10,\"shortShareFriendPath\":\"pages/shortvideo/shortvideo\",\"shortShareMomentPath\":\"pages/shortvideo/shortvideo\",\"barrageUiShow\":true,\"barrageSwitchOpen\":true,\"sortType\":2,\"barrageInputStates\":0,\"videoBarrageSwitch\":true,\"isOpenUnUploadReason\":false,\"isOpenUploadReason\":false,\"homeTabUserInfoPanel\":true,\"isShowDialogOnUpdate\":false,\"fundebug\":false,\"barrageSection\":30,\"isUploadPageLoadData\":1,\"showPayTipsMaxCount\":2,\"openFollowRemind\":true,\"dayFollowRemind\":1,\"totalFollowRemind\":3,\"sharePageRoute\":1,\"shouldFixWxRenderBug\":1,\"defaultSearchText\":\"搜索你想看的\",\"isShowDetailPageGuide\":false,\"gzhOtherVideoCount\":4,\"otherVideoCount\":10,\"shareVideoDialogCount\":2,\"videoShare2PageNotFoundPercent\":0,\"categoryRouterPercent\":100,\"fixed707Upload\":1,\"albumAvailable\":1,\"csVideoShareH5Title\":\"\",\"activityMoney\":2.88,\"privacyAgreementUrl\":\"https://rescdn.piaoquantv.com/agreement/videoagreement.html\",\"serviceAgreementUrl\":\"https://rescdn.piaoquantv.com/agreement/videoservice.html\",\"h5Domain\":\"https://vlogh5.piaoquantv.com/\",\"sendVideoIgnoreAuthorizeMobile\":1,\"sendVideoPostAuthorizeMobile\":1,\"noGrantLoginEnable\":1}";
|
||||
String str21 = "{\"mode\":2,\"isIOSAutoPlay\":true,\"isAndroidAutoPlay\":true,\"isShowDefaultPic\":true,\"isShowWeChatCircleShareButton\":true,\"isForceUpdate\":true,\"isGzhFullScreen\":true,\"isGzhAutoPlay\":true,\"isSharePageFullScreen\":true,\"isSharePageAutoPlay\":true,\"distDir\":\"dist_1_3_4\",\"distNewDir\":\"dist_1_3_4\",\"videoShareFriendPath\":\"pages/user-videos\",\"videoShareMomentPath\":\"pages/user-videos\",\"userShareFriendPath\":\"pages/mine/mine-info\",\"userShareMomentPath\":\"pages/mine/mine-info\",\"addMaskGuide\":false,\"addMaskDayInterval\":2,\"addMaskMaxCount\":3,\"addMaskDuration\":10,\"addBubbleGuide\":true,\"addBubbleDayInterval\":2,\"addBubbleMaxCount\":3,\"addBubbleDuration\":10,\"shortShareFriendPath\":\"pages/shortvideo/shortvideo\",\"shortShareMomentPath\":\"pages/shortvideo/shortvideo\",\"barrageUiShow\":true,\"barrageSwitchOpen\":true,\"sortType\":2,\"barrageInputStates\":0,\"videoBarrageSwitch\":true,\"isOpenUnUploadReason\":false,\"isOpenUploadReason\":false,\"homeTabUserInfoPanel\":true,\"isShowDialogOnUpdate\":false,\"fundebug\":false,\"barrageSection\":30,\"isUploadPageLoadData\":1,\"showPayTipsMaxCount\":2,\"openFollowRemind\":true,\"dayFollowRemind\":1,\"totalFollowRemind\":3,\"sharePageRoute\":1,\"shouldFixWxRenderBug\":1,\"defaultSearchText\":\"搜索你想看的\",\"isShowDetailPageGuide\":false,\"gzhOtherVideoCount\":4,\"otherVideoCount\":10,\"shareVideoDialogCount\":2,\"videoShare2PageNotFoundPercent\":0,\"categoryRouterPercent\":100,\"fixed707Upload\":1,\"albumAvailable\":1,\"csVideoShareH5Title\":\"\",\"activityMoney\":2.88,\"privacyAgreementUrl\":\"https://rescdn.piaoquantv.com/agreement/videoagreement.html\",\"serviceAgreementUrl\":\"https://rescdn.piaoquantv.com/agreement/videoservice.html\",\"h5Domain\":\"https://vlogh5.piaoquantv.com/\",\"sendVideoIgnoreAuthorizeMobile\":1,\"sendVideoPostAuthorizeMobile\":1,\"noGrantLoginEnable\":1}";
|
||||
String str22 = "{\"mode\":2,\"isIOSAutoPlay\":true,\"isAndroidAutoPlay\":true,\"isShowDefaultPic\":true,\"isShowWeChatCircleShareButton\":true,\"isForceUpdate\":true,\"isGzhFullScreen\":true,\"isGzhAutoPlay\":true,\"isSharePageFullScreen\":true,\"isSharePageAutoPlay\":true,\"distDir\":\"dist_1_3_4\",\"distNewDir\":\"dist_1_3_4\",\"videoShareFriendPath\":\"pages/user-videos\",\"videoShareMomentPath\":\"pages/user-videos\",\"userShareFriendPath\":\"pages/mine/mine-info\",\"userShareMomentPath\":\"pages/mine/mine-info\",\"addMaskGuide\":false,\"addMaskDayInterval\":2,\"addMaskMaxCount\":3,\"addMaskDuration\":10,\"addBubbleGuide\":true,\"addBubbleDayInterval\":2,\"addBubbleMaxCount\":3,\"addBubbleDuration\":10,\"shortShareFriendPath\":\"pages/shortvideo/shortvideo\",\"shortShareMomentPath\":\"pages/shortvideo/shortvideo\",\"barrageUiShow\":true,\"barrageSwitchOpen\":true,\"sortType\":2,\"barrageInputStates\":0,\"videoBarrageSwitch\":true,\"isOpenUnUploadReason\":false,\"isOpenUploadReason\":false,\"homeTabUserInfoPanel\":true,\"isShowDialogOnUpdate\":false,\"fundebug\":false,\"barrageSection\":30,\"isUploadPageLoadData\":1,\"showPayTipsMaxCount\":2,\"openFollowRemind\":true,\"dayFollowRemind\":1,\"totalFollowRemind\":3,\"sharePageRoute\":1,\"shouldFixWxRenderBug\":1,\"defaultSearchText\":\"搜索你想看的\",\"isShowDetailPageGuide\":false,\"gzhOtherVideoCount\":4,\"otherVideoCount\":10,\"shareVideoDialogCount\":2,\"videoShare2PageNotFoundPercent\":0,\"categoryRouterPercent\":100,\"fixed707Upload\":1,\"albumAvailable\":1,\"csVideoShareH5Title\":\"\",\"activityMoney\":2.88,\"privacyAgreementUrl\":\"https://rescdn.piaoquantv.com/agreement/videoagreement.html\",\"serviceAgreementUrl\":\"https://rescdn.piaoquantv.com/agreement/videoservice.html\",\"h5Domain\":\"https://vlogh5.piaoquantv.com/\",\"sendVideoIgnoreAuthorizeMobile\":1,\"sendVideoPostAuthorizeMobile\":1,\"noGrantLoginEnable\":1}";
|
||||
|
||||
// String str0 = "{\"mode\":0,\"isIOSAutoPlay\":false,\"isAndroidAutoPlay\":false,\"isShowDefaultPic\":false,\"isShowWeChatCircleShareButton\":false,\"isForceUpdate\":true,\"isGzhFullScreen\":false,\"isGzhAutoPlay\":false,\"isSharePageFullScreen\":false,\"isSharePageAutoPlay\":false,\"distDir\":\"dist_1_3_4\",\"distNewDir\":\"dist_1_3_4\",\"videoShareFriendPath\":\"pages/user-videos\",\"videoShareMomentPath\":\"pages/user-videos\",\"userShareFriendPath\":\"pages/mine/mine-info\",\"userShareMomentPath\":\"pages/mine/mine-info\",\"addMaskGuide\":false,\"addMaskDayInterval\":2,\"addMaskMaxCount\":3,\"addMaskDuration\":10,\"addBubbleGuide\":true,\"addBubbleDayInterval\":2,\"addBubbleMaxCount\":3,\"addBubbleDuration\":10,\"shortShareFriendPath\":\"pages/shortvideo/shortvideo\",\"shortShareMomentPath\":\"pages/shortvideo/shortvideo\",\"barrageUiShow\":true,\"barrageSwitchOpen\":true,\"sortType\":2,\"barrageInputStates\":0,\"videoBarrageSwitch\":true,\"isOpenUnUploadReason\":false,\"isOpenUploadReason\":false,\"homeTabUserInfoPanel\":false,\"isShowDialogOnUpdate\":false,\"fundebug\":false,\"barrageSection\":30,\"isUploadPageLoadData\":0,\"showPayTipsMaxCount\":2,\"openFollowRemind\":true,\"dayFollowRemind\":1,\"totalFollowRemind\":3,\"sharePageRoute\":0,\"shouldFixWxRenderBug\":1,\"defaultSearchText\":\"搜索你想看的\",\"isShowDetailPageGuide\":false,\"gzhOtherVideoCount\":4,\"otherVideoCount\":10,\"shareVideoDialogCount\":2,\"videoShare2PageNotFoundPercent\":0,\"categoryRouterPercent\":100,\"fixed707Upload\":1,\"albumAvailable\":1,\"csVideoShareH5Title\":\"\",\"activityMoney\":2.88,\"privacyAgreementUrl\":\"https://weapppiccdn.yishihui.com/resources/agreements/videoagreement.html\",\"serviceAgreementUrl\":\"https://weapppiccdn.yishihui.com/resources/agreements/videoservice.html\",\"h5Domain\":\"https://vlogh5.piaoquantv.com/\",\"sendVideoIgnoreAuthorizeMobile\":1,\"sendVideoPostAuthorizeMobile\":1,\"noGrantLoginEnable\":1}";
|
||||
// String str2 = "{\"mode\":0,\"isIOSAutoPlay\":false,\"isAndroidAutoPlay\":false,\"isShowDefaultPic\":false,\"isShowWeChatCircleShareButton\":false,\"isForceUpdate\":true,\"isGzhFullScreen\":false,\"isGzhAutoPlay\":false,\"isSharePageFullScreen\":false,\"isSharePageAutoPlay\":false,\"distDir\":\"dist_1_3_4\",\"distNewDir\":\"dist_1_3_4\",\"videoShareFriendPath\":\"pages/user-videos\",\"videoShareMomentPath\":\"pages/user-videos\",\"userShareFriendPath\":\"pages/mine/mine-info\",\"userShareMomentPath\":\"pages/mine/mine-info\",\"addMaskGuide\":false,\"addMaskDayInterval\":2,\"addMaskMaxCount\":3,\"addMaskDuration\":10,\"addBubbleGuide\":true,\"addBubbleDayInterval\":2,\"addBubbleMaxCount\":3,\"addBubbleDuration\":10,\"shortShareFriendPath\":\"pages/shortvideo/shortvideo\",\"shortShareMomentPath\":\"pages/shortvideo/shortvideo\",\"barrageUiShow\":true,\"barrageSwitchOpen\":true,\"sortType\":2,\"barrageInputStates\":0,\"videoBarrageSwitch\":true,\"isOpenUnUploadReason\":false,\"isOpenUploadReason\":false,\"homeTabUserInfoPanel\":false,\"isShowDialogOnUpdate\":false,\"fundebug\":false,\"barrageSection\":30,\"isUploadPageLoadData\":0,\"showPayTipsMaxCount\":2,\"openFollowRemind\":true,\"dayFollowRemind\":1,\"totalFollowRemind\":3,\"sharePageRoute\":0,\"shouldFixWxRenderBug\":1,\"defaultSearchText\":\"搜索你想看的\",\"isShowDetailPageGuide\":false,\"gzhOtherVideoCount\":4,\"otherVideoCount\":10,\"shareVideoDialogCount\":2,\"videoShare2PageNotFoundPercent\":0,\"categoryRouterPercent\":100,\"fixed707Upload\":1,\"albumAvailable\":1,\"csVideoShareH5Title\":\"\",\"activityMoney\":2.88,\"privacyAgreementUrl\":\"https://weapppiccdn.yishihui.com/resources/agreements/videoagreement.html\",\"serviceAgreementUrl\":\"https://weapppiccdn.yishihui.com/resources/agreements/videoservice.html\"}";
|
||||
// String str3 = "{\"mode\":0,\"isIOSAutoPlay\":false,\"isAndroidAutoPlay\":false,\"isShowDefaultPic\":false,\"isShowWeChatCircleShareButton\":false,\"isForceUpdate\":true,\"isGzhFullScreen\":false,\"isGzhAutoPlay\":false,\"isSharePageFullScreen\":false,\"isSharePageAutoPlay\":false,\"distDir\":\"dist_1_3_4\",\"distNewDir\":\"dist_1_3_4\",\"videoShareFriendPath\":\"pages/user-videos\",\"videoShareMomentPath\":\"pages/user-videos\",\"userShareFriendPath\":\"pages/mine/mine-info\",\"userShareMomentPath\":\"pages/mine/mine-info\",\"addMaskGuide\":false,\"addMaskDayInterval\":2,\"addMaskMaxCount\":3,\"addMaskDuration\":10,\"addBubbleGuide\":true,\"addBubbleDayInterval\":2,\"addBubbleMaxCount\":3,\"addBubbleDuration\":10,\"shortShareFriendPath\":\"pages/shortvideo/shortvideo\",\"shortShareMomentPath\":\"pages/shortvideo/shortvideo\",\"barrageUiShow\":true,\"barrageSwitchOpen\":true,\"sortType\":2,\"barrageInputStates\":0,\"videoBarrageSwitch\":true,\"isOpenUnUploadReason\":false,\"isOpenUploadReason\":false,\"homeTabUserInfoPanel\":false,\"isShowDialogOnUpdate\":false,\"fundebug\":false,\"barrageSection\":30,\"isUploadPageLoadData\":0,\"showPayTipsMaxCount\":2,\"openFollowRemind\":true,\"dayFollowRemind\":1,\"totalFollowRemind\":3,\"sharePageRoute\":0,\"shouldFixWxRenderBug\":1,\"defaultSearchText\":\"搜索你想看的\",\"isShowDetailPageGuide\":false,\"gzhOtherVideoCount\":4,\"otherVideoCount\":10,\"shareVideoDialogCount\":2,\"videoShare2PageNotFoundPercent\":0,\"categoryRouterPercent\":100,\"fixed707Upload\":1,\"albumAvailable\":1,\"csVideoShareH5Title\":\"\",\"activityMoney\":2.88,\"privacyAgreementUrl\":\"https://weapppiccdn.yishihui.com/resources/agreements/videoagreement.html\",\"serviceAgreementUrl\":\"https://weapppiccdn.yishihui.com/resources/agreements/videoservice.html\"}";
|
||||
// String str4 = "{\"mode\":0,\"isIOSAutoPlay\":false,\"isAndroidAutoPlay\":false,\"isShowDefaultPic\":false,\"isShowWeChatCircleShareButton\":false,\"isForceUpdate\":true,\"isGzhFullScreen\":false,\"isGzhAutoPlay\":false,\"isSharePageFullScreen\":true,\"isSharePageAutoPlay\":false,\"distDir\":\"dist_1_3_4\",\"distNewDir\":\"dist_1_3_4\",\"videoShareFriendPath\":\"pages/user-videos\",\"videoShareMomentPath\":\"pages/user-videos\",\"userShareFriendPath\":\"pages/mine/mine-info\",\"userShareMomentPath\":\"pages/mine/mine-info\",\"shortShareFriendPath\":\"pages/shortvideo/shortvideo\",\"shortShareMomentPath\":\"pages/shortvideo/shortvideo\",\"addMaskGuide\":false,\"addMaskDayInterval\":2,\"addMaskMaxCount\":3,\"addMaskDuration\":10,\"addBubbleGuide\":true,\"addBubbleDayInterval\":2,\"addBubbleMaxCount\":3,\"addBubbleDuration\":10,\"barrageUiShow\":true,\"barrageSwitchOpen\":true,\"sortType\":2,\"barrageInputStates\":0,\"videoBarrageSwitch\":true,\"isOpenUnUploadReason\":false,\"isOpenUploadReason\":false,\"homeTabUserInfoPanel\":false,\"isShowDialogOnUpdate\":false,\"fundebug\":false,\"barrageSection\":30,\"isUploadPageLoadData\":0,\"showPayTipsMaxCount\":2,\"openFollowRemind\":true,\"dayFollowRemind\":1,\"totalFollowRemind\":3,\"sharePageRoute\":1,\"shouldFixWxRenderBug\":1,\"defaultSearchText\":\"搜索你想看的\",\"isShowDetailPageGuide\":false,\"gzhOtherVideoCount\":4,\"otherVideoCount\":10,\"shareVideoDialogCount\":2,\"videoShare2PageNotFoundPercent\":0,\"categoryRouterPercent\":100,\"fixed707Upload\":1,\"albumAvailable\":1,\"csVideoShareH5Title\":\"\",\"activityMoney\":2.88,\"privacyAgreementUrl\":\"https://rescdn.piaoquantv.com/agreement/videoagreement.html\",\"serviceAgreementUrl\":\"https://rescdn.piaoquantv.com/agreement/videoservice.html\",\"h5Domain\":\"https://vlogh5.piaoquantv.com/\",\"sendVideoIgnoreAuthorizeMobile\":1,\"sendVideoPostAuthorizeMobile\":1,\"noGrantLoginEnable\":1}";
|
||||
// String str5 = "{\"mode\":0,\"isIOSAutoPlay\":false,\"isAndroidAutoPlay\":false,\"isShowDefaultPic\":false,\"isShowWeChatCircleShareButton\":false,\"isForceUpdate\":true,\"isGzhFullScreen\":false,\"isGzhAutoPlay\":false,\"isSharePageFullScreen\":false,\"isSharePageAutoPlay\":false,\"distDir\":\"dist_1_3_4\",\"distNewDir\":\"dist_1_3_4\",\"videoShareFriendPath\":\"pages/user-videos\",\"videoShareMomentPath\":\"pages/user-videos\",\"userShareFriendPath\":\"pages/mine/mine-info\",\"userShareMomentPath\":\"pages/mine/mine-info\",\"shortShareFriendPath\":\"pages/shortvideo/shortvideo\",\"shortShareMomentPath\":\"pages/shortvideo/shortvideo\",\"addMaskGuide\":false,\"addMaskDayInterval\":2,\"addMaskMaxCount\":3,\"addMaskDuration\":10,\"addBubbleGuide\":true,\"addBubbleDayInterval\":2,\"addBubbleMaxCount\":3,\"addBubbleDuration\":10,\"barrageUiShow\":true,\"barrageSwitchOpen\":true,\"sortType\":2,\"barrageInputStates\":0,\"videoBarrageSwitch\":true,\"isOpenUnUploadReason\":false,\"isOpenUploadReason\":false,\"homeTabUserInfoPanel\":false,\"isShowDialogOnUpdate\":false,\"fundebug\":false,\"barrageSection\":30,\"isUploadPageLoadData\":0,\"showPayTipsMaxCount\":2,\"openFollowRemind\":true,\"dayFollowRemind\":1,\"totalFollowRemind\":3,\"sharePageRoute\":1,\"shouldFixWxRenderBug\":1,\"defaultSearchText\":\"搜索你想看的\",\"isShowDetailPageGuide\":false,\"gzhOtherVideoCount\":4,\"otherVideoCount\":10,\"shareVideoDialogCount\":2,\"videoShare2PageNotFoundPercent\":0,\"categoryRouterPercent\":100,\"fixed707Upload\":1,\"albumAvailable\":1,\"privacyAgreementUrl\":\"https://rescdn.piaoquantv.com/agreement/videoagreement.html\",\"serviceAgreementUrl\":\"https://rescdn.piaoquantv.com/agreement/videoservice.html\",\"h5Domain\":\"https://vlogh5.piaoquantv.com/\",\"sendVideoIgnoreAuthorizeMobile\":1,\"sendVideoPostAuthorizeMobile\":1,\"noGrantLoginEnable\":1}";
|
||||
// String str6 = "{\"mode\":0,\"isIOSAutoPlay\":false,\"isAndroidAutoPlay\":false,\"isShowDefaultPic\":false,\"isShowWeChatCircleShareButton\":false,\"isForceUpdate\":true,\"isGzhFullScreen\":false,\"isGzhAutoPlay\":false,\"isSharePageFullScreen\":false,\"isSharePageAutoPlay\":false,\"distDir\":\"dist_1_3_4\",\"distNewDir\":\"dist_1_3_4\",\"videoShareFriendPath\":\"pages/user-videos\",\"videoShareMomentPath\":\"pages/user-videos\",\"userShareFriendPath\":\"pages/mine/mine-info\",\"userShareMomentPath\":\"pages/mine/mine-info\",\"addMaskGuide\":false,\"addMaskDayInterval\":2,\"addMaskMaxCount\":3,\"addMaskDuration\":10,\"addBubbleGuide\":true,\"addBubbleDayInterval\":2,\"addBubbleMaxCount\":3,\"addBubbleDuration\":10,\"shortShareFriendPath\":\"pages/shortvideo/shortvideo\",\"shortShareMomentPath\":\"pages/shortvideo/shortvideo\",\"barrageUiShow\":true,\"barrageSwitchOpen\":true,\"sortType\":2,\"barrageInputStates\":0,\"videoBarrageSwitch\":true,\"isOpenUnUploadReason\":false,\"isOpenUploadReason\":false,\"homeTabUserInfoPanel\":false,\"isShowDialogOnUpdate\":false,\"fundebug\":false,\"barrageSection\":30,\"isUploadPageLoadData\":0,\"showPayTipsMaxCount\":2,\"openFollowRemind\":true,\"dayFollowRemind\":1,\"totalFollowRemind\":3,\"sharePageRoute\":0,\"shouldFixWxRenderBug\":1,\"defaultSearchText\":\"搜索你想看的\",\"isShowDetailPageGuide\":false,\"gzhOtherVideoCount\":4,\"otherVideoCount\":10,\"shareVideoDialogCount\":2,\"videoShare2PageNotFoundPercent\":0,\"categoryRouterPercent\":100,\"fixed707Upload\":1,\"albumAvailable\":1,\"csVideoShareH5Title\":\"\",\"activityMoney\":2.88,\"privacyAgreementUrl\":\"https://rescdn.piaoquantv.com/agreement/videoagreement.html\",\"serviceAgreementUrl\":\"https://rescdn.piaoquantv.com/agreement/videoservice.html\",\"h5Domain\":\"https://vlogh5.piaoquantv.com/\",\"sendVideoIgnoreAuthorizeMobile\":1,\"sendVideoPostAuthorizeMobile\":1,\"noGrantLoginEnable\":1}";
|
||||
// String str7 = "{\"mode\":0,\"isIOSAutoPlay\":false,\"isAndroidAutoPlay\":false,\"isShowDefaultPic\":false,\"isShowWeChatCircleShareButton\":false,\"isForceUpdate\":true,\"isGzhFullScreen\":false,\"isGzhAutoPlay\":false,\"isSharePageFullScreen\":false,\"isSharePageAutoPlay\":false,\"distDir\":\"dist_1_3_4\",\"distNewDir\":\"dist_1_3_4\",\"videoShareFriendPath\":\"pages/user-videos\",\"videoShareMomentPath\":\"pages/user-videos\",\"userShareFriendPath\":\"pages/mine/mine-info\",\"userShareMomentPath\":\"pages/mine/mine-info\",\"addMaskGuide\":false,\"addMaskDayInterval\":2,\"addMaskMaxCount\":3,\"addMaskDuration\":10,\"addBubbleGuide\":true,\"addBubbleDayInterval\":2,\"addBubbleMaxCount\":3,\"addBubbleDuration\":10,\"shortShareFriendPath\":\"pages/shortvideo/shortvideo\",\"shortShareMomentPath\":\"pages/shortvideo/shortvideo\",\"barrageUiShow\":true,\"barrageSwitchOpen\":true,\"sortType\":2,\"barrageInputStates\":0,\"videoBarrageSwitch\":true,\"isOpenUnUploadReason\":false,\"isOpenUploadReason\":false,\"homeTabUserInfoPanel\":false,\"isShowDialogOnUpdate\":false,\"fundebug\":false,\"barrageSection\":30,\"isUploadPageLoadData\":0,\"showPayTipsMaxCount\":2,\"openFollowRemind\":true,\"dayFollowRemind\":1,\"totalFollowRemind\":3,\"sharePageRoute\":0,\"shouldFixWxRenderBug\":1,\"defaultSearchText\":\"搜索你想看的\",\"isShowDetailPageGuide\":false,\"gzhOtherVideoCount\":4,\"otherVideoCount\":10,\"shareVideoDialogCount\":2,\"videoShare2PageNotFoundPercent\":0,\"categoryRouterPercent\":100,\"fixed707Upload\":1,\"albumAvailable\":1,\"csVideoShareH5Title\":\"\",\"activityMoney\":2.88,\"privacyAgreementUrl\":\"https://weapppiccdn.yishihui.com/resources/agreements/videoagreement.html\",\"serviceAgreementUrl\":\"https://weapppiccdn.yishihui.com/resources/agreements/videoservice.html\"}";
|
||||
// String str10 = "{\"mode\":0,\"isIOSAutoPlay\":false,\"isAndroidAutoPlay\":false,\"isShowDefaultPic\":false,\"isShowWeChatCircleShareButton\":false,\"isForceUpdate\":true,\"isGzhFullScreen\":false,\"isGzhAutoPlay\":false,\"isSharePageFullScreen\":false,\"isSharePageAutoPlay\":false,\"distDir\":\"dist_1_3_4\",\"distNewDir\":\"dist\",\"videoShareFriendPath\":\"pages/user-videos\",\"videoShareMomentPath\":\"pages/user-videos\",\"userShareFriendPath\":\"pages/mine/mine-info\",\"userShareMomentPath\":\"pages/mine/mine-info\",\"shortShareFriendPath\": \"pages/shortvideo/shortvideo\",\"shortShareMomentPath\":\"pages/shortvideo/shortvideo\",\"addMaskGuide\":true,\"addMaskDayInterval\":2,\"addMaskMaxCount\":3,\"addMaskDuration\":10,\"addBubbleGuide\":true,\"addBubbleDayInterval\":2,\"addBubbleMaxCount\":-1,\"addBubbleDuration\":5,\"barrageUiShow\": true,\"barrageSwitchOpen\": true}";
|
||||
// String str17 = "{\"mode\":0,\"isIOSAutoPlay\":true,\"isAndroidAutoPlay\":true,\"isShowDefaultPic\":true,\"isShowWeChatCircleShareButton\":true,\"isForceUpdate\":true,\"isGzhFullScreen\":true,\"isGzhAutoPlay\":true,\"isSharePageFullScreen\":true,\"isSharePageAutoPlay\":true,\"distDir\":\"dist_1_3_4\",\"distNewDir\":\"dist_1_3_4\",\"videoShareFriendPath\":\"pages/user-videos\",\"videoShareMomentPath\":\"pages/user-videos\",\"userShareFriendPath\":\"pages/mine/mine-info\",\"userShareMomentPath\":\"pages/mine/mine-info\",\"addMaskGuide\":false,\"addMaskDayInterval\":2,\"addMaskMaxCount\":3,\"addMaskDuration\":10,\"addBubbleGuide\":true,\"addBubbleDayInterval\":2,\"addBubbleMaxCount\":3,\"addBubbleDuration\":10,\"shortShareFriendPath\":\"pages/shortvideo/shortvideo\",\"shortShareMomentPath\":\"pages/shortvideo/shortvideo\",\"barrageUiShow\":true,\"barrageSwitchOpen\":true,\"sortType\":2,\"barrageInputStates\":0,\"videoBarrageSwitch\":true,\"isOpenUnUploadReason\":false,\"isOpenUploadReason\":false,\"homeTabUserInfoPanel\":true,\"isShowDialogOnUpdate\":false,\"fundebug\":false,\"barrageSection\":30,\"isUploadPageLoadData\":1,\"showPayTipsMaxCount\":2,\"openFollowRemind\":true,\"dayFollowRemind\":1,\"totalFollowRemind\":3,\"sharePageRoute\":1,\"shouldFixWxRenderBug\":1,\"defaultSearchText\":\"搜索你想看的\",\"isShowDetailPageGuide\":false,\"gzhOtherVideoCount\":4,\"otherVideoCount\":10,\"shareVideoDialogCount\":2,\"videoShare2PageNotFoundPercent\":0,\"categoryRouterPercent\":100,\"fixed707Upload\":1,\"albumAvailable\":1,\"csVideoShareH5Title\":\"\",\"activityMoney\":2.88,\"privacyAgreementUrl\":\"https://weapppiccdn.yishihui.com/resources/agreements/videoagreement.html\",\"serviceAgreementUrl\":\"https://weapppiccdn.yishihui.com/resources/agreements/videoservice.html\",\"h5Domain\":\"https://vlogh5.piaoquantv.com/\"}";
|
||||
// String str18 = "{\"mode\":0,\"isIOSAutoPlay\":true,\"isAndroidAutoPlay\":true,\"isShowDefaultPic\":true,\"isShowWeChatCircleShareButton\":true,\"isForceUpdate\":true,\"isGzhFullScreen\":true,\"isGzhAutoPlay\":true,\"isSharePageFullScreen\":true,\"isSharePageAutoPlay\":true,\"distDir\":\"dist_1_3_4\",\"distNewDir\":\"dist_1_3_4\",\"videoShareFriendPath\":\"pages/user-videos\",\"videoShareMomentPath\":\"pages/user-videos\",\"userShareFriendPath\":\"pages/mine/mine-info\",\"userShareMomentPath\":\"pages/mine/mine-info\",\"addMaskGuide\":false,\"addMaskDayInterval\":2,\"addMaskMaxCount\":3,\"addMaskDuration\":10,\"addBubbleGuide\":true,\"addBubbleDayInterval\":2,\"addBubbleMaxCount\":3,\"addBubbleDuration\":10,\"shortShareFriendPath\":\"pages/shortvideo/shortvideo\",\"shortShareMomentPath\":\"pages/shortvideo/shortvideo\",\"barrageUiShow\":true,\"barrageSwitchOpen\":true,\"sortType\":2,\"barrageInputStates\":0,\"videoBarrageSwitch\":true,\"isOpenUnUploadReason\":false,\"isOpenUploadReason\":false,\"homeTabUserInfoPanel\":true,\"isShowDialogOnUpdate\":false,\"fundebug\":false,\"barrageSection\":30,\"isUploadPageLoadData\":1,\"showPayTipsMaxCount\":2,\"openFollowRemind\":true,\"dayFollowRemind\":1,\"totalFollowRemind\":3,\"sharePageRoute\":1,\"shouldFixWxRenderBug\":1,\"defaultSearchText\":\"搜索你想看的\",\"isShowDetailPageGuide\":false,\"gzhOtherVideoCount\":4,\"otherVideoCount\":10,\"shareVideoDialogCount\":2,\"videoShare2PageNotFoundPercent\":0,\"categoryRouterPercent\":100,\"fixed707Upload\":1,\"albumAvailable\":1,\"csVideoShareH5Title\":\"\",\"activityMoney\":2.88,\"privacyAgreementUrl\":\"https://weapppiccdn.yishihui.com/resources/agreements/videoagreement.html\",\"serviceAgreementUrl\":\"https://weapppiccdn.yishihui.com/resources/agreements/videoservice.html\",\"h5Domain\":\"https://vlogh5.piaoquantv.com/\"}";
|
||||
// String str19 = "{\"mode\":0,\"isIOSAutoPlay\":true,\"isAndroidAutoPlay\":true,\"isShowDefaultPic\":true,\"isShowWeChatCircleShareButton\":true,\"isForceUpdate\":true,\"isGzhFullScreen\":true,\"isGzhAutoPlay\":true,\"isSharePageFullScreen\":true,\"isSharePageAutoPlay\":true,\"distDir\":\"dist_1_3_4\",\"distNewDir\":\"dist_1_3_4\",\"videoShareFriendPath\":\"pages/user-videos\",\"videoShareMomentPath\":\"pages/user-videos\",\"userShareFriendPath\":\"pages/mine/mine-info\",\"userShareMomentPath\":\"pages/mine/mine-info\",\"addMaskGuide\":false,\"addMaskDayInterval\":2,\"addMaskMaxCount\":3,\"addMaskDuration\":10,\"addBubbleGuide\":true,\"addBubbleDayInterval\":2,\"addBubbleMaxCount\":3,\"addBubbleDuration\":10,\"shortShareFriendPath\":\"pages/shortvideo/shortvideo\",\"shortShareMomentPath\":\"pages/shortvideo/shortvideo\",\"barrageUiShow\":true,\"barrageSwitchOpen\":true,\"sortType\":2,\"barrageInputStates\":0,\"videoBarrageSwitch\":true,\"isOpenUnUploadReason\":false,\"isOpenUploadReason\":false,\"homeTabUserInfoPanel\":true,\"isShowDialogOnUpdate\":false,\"fundebug\":false,\"barrageSection\":30,\"isUploadPageLoadData\":1,\"showPayTipsMaxCount\":2,\"openFollowRemind\":true,\"dayFollowRemind\":1,\"totalFollowRemind\":3,\"sharePageRoute\":1,\"shouldFixWxRenderBug\":1,\"defaultSearchText\":\"搜索你想看的\",\"isShowDetailPageGuide\":false,\"gzhOtherVideoCount\":4,\"otherVideoCount\":10,\"shareVideoDialogCount\":2,\"videoShare2PageNotFoundPercent\":0,\"categoryRouterPercent\":100,\"fixed707Upload\":1,\"albumAvailable\":1,\"csVideoShareH5Title\":\"\",\"activityMoney\":2.88,\"privacyAgreementUrl\":\"https://rescdn.piaoquantv.com/agreement/videoagreement.html\",\"serviceAgreementUrl\":\"https://rescdn.piaoquantv.com/agreement/videoservice.html\",\"h5Domain\":\"https://vlogh5.piaoquantv.com/\",\"sendVideoIgnoreAuthorizeMobile\":1,\"sendVideoPostAuthorizeMobile\":1,\"noGrantLoginEnable\":1}";
|
||||
// String str21 = "{\"mode\":0,\"isIOSAutoPlay\":false,\"isAndroidAutoPlay\":false,\"isShowDefaultPic\":false,\"isShowWeChatCircleShareButton\":false,\"isForceUpdate\":true,\"isGzhFullScreen\":false,\"isGzhAutoPlay\":false,\"isSharePageFullScreen\":false,\"isSharePageAutoPlay\":false,\"distDir\":\"dist_1_3_4\",\"distNewDir\":\"dist_1_3_4\",\"videoShareFriendPath\":\"pages/user-videos\",\"videoShareMomentPath\":\"pages/user-videos\",\"userShareFriendPath\":\"pages/mine/mine-info\",\"userShareMomentPath\":\"pages/mine/mine-info\",\"addMaskGuide\":false,\"addMaskDayInterval\":2,\"addMaskMaxCount\":3,\"addMaskDuration\":10,\"addBubbleGuide\":true,\"addBubbleDayInterval\":2,\"addBubbleMaxCount\":3,\"addBubbleDuration\":10,\"shortShareFriendPath\":\"pages/shortvideo/shortvideo\",\"shortShareMomentPath\":\"pages/shortvideo/shortvideo\",\"barrageUiShow\":true,\"barrageSwitchOpen\":true,\"sortType\":2,\"barrageInputStates\":0,\"videoBarrageSwitch\":true,\"isOpenUnUploadReason\":false,\"isOpenUploadReason\":false,\"homeTabUserInfoPanel\":false,\"isShowDialogOnUpdate\":false,\"fundebug\":false,\"barrageSection\":30,\"isUploadPageLoadData\":0,\"showPayTipsMaxCount\":2,\"openFollowRemind\":true,\"dayFollowRemind\":1,\"totalFollowRemind\":3,\"sharePageRoute\":0,\"shouldFixWxRenderBug\":1,\"defaultSearchText\":\"搜索你想看的\",\"isShowDetailPageGuide\":false,\"gzhOtherVideoCount\":4,\"otherVideoCount\":10,\"shareVideoDialogCount\":2,\"videoShare2PageNotFoundPercent\":0,\"categoryRouterPercent\":100,\"fixed707Upload\":1,\"albumAvailable\":1,\"csVideoShareH5Title\":\"\",\"activityMoney\":2.88,\"privacyAgreementUrl\":\"https://weapppiccdn.yishihui.com/resources/agreements/videoagreement.html\",\"serviceAgreementUrl\":\"https://weapppiccdn.yishihui.com/resources/agreements/videoservice.html\",\"h5Domain\":\"https://vlogh5.piaoquantv.com/\",\"sendVideoIgnoreAuthorizeMobile\":1,\"sendVideoPostAuthorizeMobile\":1,\"noGrantLoginEnable\":1}";
|
||||
// String str22 = "{\"mode\":0,\"isIOSAutoPlay\":false,\"isAndroidAutoPlay\":false,\"isShowDefaultPic\":false,\"isShowWeChatCircleShareButton\":false,\"isForceUpdate\":true,\"isGzhFullScreen\":false,\"isGzhAutoPlay\":false,\"isSharePageFullScreen\":false,\"isSharePageAutoPlay\":false,\"distDir\":\"dist_1_3_4\",\"distNewDir\":\"dist_1_3_4\",\"videoShareFriendPath\":\"pages/user-videos\",\"videoShareMomentPath\":\"pages/user-videos\",\"userShareFriendPath\":\"pages/mine/mine-info\",\"userShareMomentPath\":\"pages/mine/mine-info\",\"addMaskGuide\":false,\"addMaskDayInterval\":2,\"addMaskMaxCount\":3,\"addMaskDuration\":10,\"addBubbleGuide\":true,\"addBubbleDayInterval\":2,\"addBubbleMaxCount\":3,\"addBubbleDuration\":10,\"shortShareFriendPath\":\"pages/shortvideo/shortvideo\",\"shortShareMomentPath\":\"pages/shortvideo/shortvideo\",\"barrageUiShow\":true,\"barrageSwitchOpen\":true,\"sortType\":2,\"barrageInputStates\":0,\"videoBarrageSwitch\":true,\"isOpenUnUploadReason\":false,\"isOpenUploadReason\":false,\"homeTabUserInfoPanel\":false,\"isShowDialogOnUpdate\":false,\"fundebug\":false,\"barrageSection\":30,\"isUploadPageLoadData\":0,\"showPayTipsMaxCount\":2,\"openFollowRemind\":true,\"dayFollowRemind\":1,\"totalFollowRemind\":3,\"sharePageRoute\":0,\"shouldFixWxRenderBug\":1,\"defaultSearchText\":\"搜索你想看的\",\"isShowDetailPageGuide\":false,\"gzhOtherVideoCount\":4,\"otherVideoCount\":10,\"shareVideoDialogCount\":2,\"videoShare2PageNotFoundPercent\":0,\"categoryRouterPercent\":100,\"fixed707Upload\":1,\"albumAvailable\":1,\"csVideoShareH5Title\":\"\",\"activityMoney\":2.88,\"privacyAgreementUrl\":\"https://weapppiccdn.yishihui.com/resources/agreements/videoagreement.html\",\"serviceAgreementUrl\":\"https://weapppiccdn.yishihui.com/resources/agreements/videoservice.html\",\"h5Domain\":\"https://vlogh5.piaoquantv.com/\",\"sendVideoIgnoreAuthorizeMobile\":1,\"sendVideoPostAuthorizeMobile\":1,\"noGrantLoginEnable\":1}";
|
||||
|
||||
Map<String, String> j0 = JsonUtils.string2Obj(str0, new TypeReference<>() {
|
||||
});
|
||||
Map<String, String> j2 = JsonUtils.string2Obj(str2, new TypeReference<>() {
|
||||
});
|
||||
Map<String, String> j3 = JsonUtils.string2Obj(str3, new TypeReference<>() {
|
||||
});
|
||||
Map<String, String> j4 = JsonUtils.string2Obj(str4, new TypeReference<>() {
|
||||
});
|
||||
Map<String, String> j5 = JsonUtils.string2Obj(str5, new TypeReference<>() {
|
||||
});
|
||||
Map<String, String> j6 = JsonUtils.string2Obj(str6, new TypeReference<>() {
|
||||
});
|
||||
Map<String, String> j7 = JsonUtils.string2Obj(str7, new TypeReference<>() {
|
||||
});
|
||||
Map<String, String> j10 = JsonUtils.string2Obj(str10, new TypeReference<>() {
|
||||
});
|
||||
Map<String, String> j17 = JsonUtils.string2Obj(str17, new TypeReference<>() {
|
||||
});
|
||||
Map<String, String> j18 = JsonUtils.string2Obj(str18, new TypeReference<>() {
|
||||
});
|
||||
Map<String, String> j19 = JsonUtils.string2Obj(str19, new TypeReference<>() {
|
||||
});
|
||||
Map<String, String> j21 = JsonUtils.string2Obj(str21, new TypeReference<>() {
|
||||
});
|
||||
Map<String, String> j22 = JsonUtils.string2Obj(str22, new TypeReference<>() {
|
||||
});
|
||||
|
||||
|
||||
for (String key : j0.keySet()) {
|
||||
System.out.println(key + "|" + j0.get(key) + "|" + j2.remove(key)
|
||||
+ "|" + j3.remove(key)
|
||||
+ "|" + j4.remove(key)
|
||||
+ "|" + j5.remove(key)
|
||||
+ "|" + j6.remove(key)
|
||||
+ "|" + j7.remove(key)
|
||||
+ "|" + j10.remove(key)
|
||||
+ "|" + j17.remove(key)
|
||||
+ "|" + j18.remove(key)
|
||||
+ "|" + j19.remove(key)
|
||||
+ "|" + j21.remove(key)
|
||||
+ "|" + j22.remove(key));
|
||||
}
|
||||
|
||||
System.out.println("j2: " + j2);
|
||||
System.out.println("j3: " + j3);
|
||||
System.out.println("j4: " + j4);
|
||||
System.out.println("j5: " + j5);
|
||||
System.out.println("j6: " + j6);
|
||||
System.out.println("j7: " + j7);
|
||||
System.out.println("j10: " + j10);
|
||||
System.out.println("j17: " + j17);
|
||||
System.out.println("j18: " + j18);
|
||||
System.out.println("j19: " + j19);
|
||||
System.out.println("j21: " + j21);
|
||||
System.out.println("j22: " + j22);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2020 xrv <xrg@live.com>
|
||||
* Copyright © 2022 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -22,16 +22,29 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.test;
|
||||
package io.github.ehlxr;
|
||||
|
||||
import io.github.ehlxr.redis.JedisUtil;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* Created by ehlxr on 2016/6/14.
|
||||
* @author ehlxr
|
||||
* @since 2022-01-17 06:31.
|
||||
*/
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
JedisUtil.set("test_20160614", "20160614");
|
||||
System.out.println(JedisUtil.getStr("test_20160614"));
|
||||
int[][] ns = {
|
||||
{1, 2, 3, 4},
|
||||
{5, 6, 7, 8},
|
||||
{9, 10, 11, 12}
|
||||
};
|
||||
System.out.println(ns.length); // 3
|
||||
System.out.println(ns[0].length); // 4
|
||||
System.out.println(ns[2][2]); // 11
|
||||
|
||||
|
||||
List<String> collect = Stream.of("111", "wwwdddd", "dddddd", "12").filter(x -> x.length() > 3).collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
260
budd-demo/src/main/java/io/github/ehlxr/ManagedBlockerTest.java
Normal file
260
budd-demo/src/main/java/io/github/ehlxr/ManagedBlockerTest.java
Normal file
@@ -0,0 +1,260 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2021 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr;
|
||||
|
||||
import com.google.common.base.Stopwatch;
|
||||
|
||||
import java.time.LocalTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* @author ehlxr
|
||||
* @since 2021-09-02 15:52.
|
||||
*/
|
||||
public class ManagedBlockerTest {
|
||||
static String threadDateTimeInfo() {
|
||||
return DateTimeFormatter.ISO_TIME.format(LocalTime.now()) + Thread.currentThread().getName();
|
||||
}
|
||||
|
||||
static void test1() {
|
||||
List<RecursiveTask<String>> tasks = Stream.generate(() -> new RecursiveTask<String>() {
|
||||
private static final long serialVersionUID = 1303648247573881735L;
|
||||
|
||||
@Override
|
||||
protected String compute() {
|
||||
System.out.println(threadDateTimeInfo() + ":simulate io task blocking for 2 seconds···");
|
||||
try {
|
||||
//线程休眠2秒模拟IO调用阻塞
|
||||
TimeUnit.SECONDS.sleep(2);
|
||||
} catch (InterruptedException e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
return threadDateTimeInfo() + ": io blocking task returns successfully";
|
||||
}
|
||||
}).limit(28).collect(Collectors.toList());
|
||||
|
||||
tasks.forEach(ForkJoinTask::fork);
|
||||
tasks.forEach(e -> {
|
||||
try {
|
||||
System.out.println(e.get());
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
Stopwatch started = Stopwatch.createStarted();
|
||||
test4();
|
||||
System.out.println(started);
|
||||
}
|
||||
|
||||
static void test2() {
|
||||
List<IoBlockerTask<String>> tasks = Stream.generate(() -> new IoBlockerTask<>(() -> {
|
||||
System.out.println(threadDateTimeInfo() + ":simulate io task blocking for 2 seconds···");
|
||||
try {
|
||||
TimeUnit.SECONDS.sleep(2);
|
||||
} catch (InterruptedException e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
return threadDateTimeInfo() + ": io blocking task returns successfully";
|
||||
})).limit(28).collect(Collectors.toList());
|
||||
|
||||
tasks.forEach(ForkJoinTask::fork);
|
||||
tasks.forEach(e -> {
|
||||
try {
|
||||
System.out.println(e.get());
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
static void test3() {
|
||||
List<IoBlockerAction> actions = Stream.generate(() -> new IoBlockerAction(() -> {
|
||||
System.out.println(threadDateTimeInfo() + ":simulate io action blocking for 2 seconds···");
|
||||
try {
|
||||
TimeUnit.SECONDS.sleep(2);
|
||||
} catch (InterruptedException e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
System.out.println(threadDateTimeInfo() + ": io blocking action successfully");
|
||||
})).limit(56).collect(Collectors.toList());
|
||||
|
||||
//如果不使用 ManagedBlocker 耗时估算: 56/7(8 cpu - 1) = 8 * 2 =16s,实际 约等于 2s
|
||||
|
||||
actions.forEach(ForkJoinTask::fork);
|
||||
actions.forEach(ForkJoinTask::join);
|
||||
}
|
||||
|
||||
static void test4() {
|
||||
List<IoBlockerAction2<Integer>> actions = Stream.generate(() -> new IoBlockerAction2<>((x) -> {
|
||||
System.out.println(threadDateTimeInfo() + ":simulate io action blocking for 2 seconds···" + x);
|
||||
try {
|
||||
TimeUnit.SECONDS.sleep(2);
|
||||
} catch (InterruptedException e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
System.out.println(threadDateTimeInfo() + ": io blocking action successfully " + x);
|
||||
}, 1)).limit(56).collect(Collectors.toList());
|
||||
|
||||
//如果不使用 ManagedBlocker 耗时估算: 56/7(8 cpu - 1) = 8 * 2 =16s,实际 约等于 2s
|
||||
|
||||
actions.forEach(x -> {
|
||||
x.fork();
|
||||
System.out.println("fork {}"+ x);
|
||||
});
|
||||
actions.forEach(x -> {
|
||||
x.join();
|
||||
System.out.println("join {}"+ x);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class IoBlockerAction2<T> extends RecursiveAction {
|
||||
private static final long serialVersionUID = -4114798302790287199L;
|
||||
private final MyManagedBlockerImpl<T> blocker;
|
||||
|
||||
public IoBlockerAction2(Consumer<T> consumer, T t) {
|
||||
this.blocker = new MyManagedBlockerImpl<>(consumer, t);
|
||||
}
|
||||
|
||||
static class MyManagedBlockerImpl<T> implements ForkJoinPool.ManagedBlocker {
|
||||
private final Consumer<T> consumer;
|
||||
private final T t;
|
||||
|
||||
public MyManagedBlockerImpl(Consumer<T> consumer, T t) {
|
||||
this.consumer = consumer;
|
||||
this.t = t;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean block() {
|
||||
consumer.accept(t);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReleasable() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute() {
|
||||
try {
|
||||
ForkJoinPool.managedBlock(blocker);
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class IoBlockerAction extends RecursiveAction {
|
||||
private static final long serialVersionUID = -4114798302790287199L;
|
||||
private final MyManagedBlockerImpl blocker;
|
||||
|
||||
public IoBlockerAction(Runnable runnable) {
|
||||
this.blocker = new MyManagedBlockerImpl(runnable);
|
||||
}
|
||||
|
||||
static class MyManagedBlockerImpl implements ForkJoinPool.ManagedBlocker {
|
||||
private final Runnable runnable;
|
||||
|
||||
public MyManagedBlockerImpl(Runnable runnable) {
|
||||
this.runnable = runnable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean block() {
|
||||
runnable.run();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReleasable() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute() {
|
||||
try {
|
||||
ForkJoinPool.managedBlock(blocker);
|
||||
// setRawResult(blocker.result);
|
||||
// return getRawResult();
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class IoBlockerTask<T> extends RecursiveTask<T> {
|
||||
private static final long serialVersionUID = -4114798302790287199L;
|
||||
private final MyManagedBlockerImpl<T> blocker;
|
||||
|
||||
public IoBlockerTask(Supplier<T> supplier) {
|
||||
this.blocker = new MyManagedBlockerImpl<>(supplier);
|
||||
}
|
||||
|
||||
static class MyManagedBlockerImpl<T> implements ForkJoinPool.ManagedBlocker {
|
||||
private final Supplier<T> supplier;
|
||||
private T result;
|
||||
|
||||
public MyManagedBlockerImpl(Supplier<T> supplier) {
|
||||
this.supplier = supplier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean block() {
|
||||
result = supplier.get();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReleasable() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected T compute() {
|
||||
try {
|
||||
ForkJoinPool.managedBlock(blocker);
|
||||
setRawResult(blocker.result);
|
||||
return getRawResult();
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
64
budd-server/pom.xml
Normal file
64
budd-server/pom.xml
Normal file
@@ -0,0 +1,64 @@
|
||||
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>io.github.ehlxr</groupId>
|
||||
<artifactId>budd</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>budd-server</artifactId>
|
||||
<name>budd-server</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.spring4all</groupId>
|
||||
<artifactId>swagger-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-aop</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.github.ehlxr</groupId>
|
||||
<artifactId>budd-demo</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<version>${spring-boot.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2020 xrv <xrg@live.com>
|
||||
* Copyright © 2020 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -22,26 +22,20 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.lock;
|
||||
package io.github.ehlxr;
|
||||
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.web.servlet.ServletComponentScan;
|
||||
|
||||
/**
|
||||
* @author ehlxr
|
||||
* @since 2021-02-15 18:11.
|
||||
* @since 2021-08-29 18:32.
|
||||
*/
|
||||
public class Locker {
|
||||
|
||||
|
||||
@SpringBootApplication
|
||||
@ServletComponentScan("io.github.ehlxr.filter")
|
||||
public class BuddServerApplication {
|
||||
public static void main(String[] args) {
|
||||
ReentrantLock lock = new ReentrantLock();
|
||||
|
||||
lock.lock(); // block until condition holds
|
||||
try {
|
||||
// ... method body
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
SpringApplication.run(BuddServerApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
141
budd-server/src/main/java/io/github/ehlxr/aop/LogRequestAop.java
Normal file
141
budd-server/src/main/java/io/github/ehlxr/aop/LogRequestAop.java
Normal file
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2021 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.aop;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import io.github.ehlxr.common.Constant;
|
||||
import io.github.ehlxr.util.JsonUtils;
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
import org.aspectj.lang.annotation.*;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.slf4j.MDC;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 请求日志记录
|
||||
*
|
||||
* @author ehlxr
|
||||
* @since 2021-08-17 22:03.
|
||||
*/
|
||||
@Aspect
|
||||
@Component
|
||||
public class LogRequestAop {
|
||||
private static final Logger log = LoggerFactory.getLogger(LogRequestAop.class);
|
||||
|
||||
// private final AliyunLogManager aliyunLogManager;
|
||||
// /**
|
||||
// * aliyun log 配置
|
||||
// */
|
||||
// @Value("${aliyun.log.project:}")
|
||||
// private String projcet;
|
||||
// @Value("${aliyun.log.logstore.request:}")
|
||||
// private String logStore;
|
||||
// @Value("${aliyun.log.topic:}")
|
||||
// private String topic;
|
||||
|
||||
// @Autowired
|
||||
// public LogRequestAop(AliyunLogManager aliyunLogManager) {
|
||||
// this.aliyunLogManager = aliyunLogManager;
|
||||
// }
|
||||
|
||||
/**
|
||||
* 切入点
|
||||
*/
|
||||
@Pointcut("execution(public * io.github.ehlxr.*Controller.*(..)) && !@annotation(io.github.ehlxr.annotations.NoRequestLog)")
|
||||
// @Pointcut("@within(org.springframework.web.bind.annotation.RestController) && !@annotation(com.tzld.piaoquan.incentive.annotations.NoRequestLog)")
|
||||
public void requestLog() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 前置操作
|
||||
*/
|
||||
@Before("requestLog()")
|
||||
public void beforeLog() {
|
||||
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
||||
HttpServletRequest request = Objects.requireNonNull(attributes).getRequest();
|
||||
|
||||
request.setAttribute(Constant.REQUEST_START_TIME, System.currentTimeMillis());
|
||||
}
|
||||
|
||||
/**
|
||||
* 后置操作
|
||||
*/
|
||||
@AfterReturning(pointcut = "requestLog()", returning = "returnValue")
|
||||
public void afterReturning(JoinPoint point, Object returnValue) {
|
||||
logRecord(point, JsonUtils.obj2String(returnValue));
|
||||
}
|
||||
|
||||
@AfterThrowing(pointcut = "requestLog()", throwing = "ex")
|
||||
public void afterThrowing(JoinPoint point, Exception ex) {
|
||||
logRecord(point, ex.getMessage());
|
||||
}
|
||||
|
||||
private void logRecord(JoinPoint point, String message) {
|
||||
try {
|
||||
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
||||
HttpServletRequest request = Objects.requireNonNull(attributes).getRequest();
|
||||
|
||||
Long startTime = (Long) request.getAttribute(Constant.REQUEST_START_TIME);
|
||||
if (Objects.isNull(startTime)) {
|
||||
return;
|
||||
}
|
||||
|
||||
String query = request.getQueryString();
|
||||
String uri = request.getRequestURI();
|
||||
|
||||
Map<String, Object> logMap = new HashMap<>(8);
|
||||
logMap.put("url", Strings.isNullOrEmpty(query) ? uri : uri + "?" + query);
|
||||
logMap.put("method", request.getMethod());
|
||||
logMap.put("header", getHeaders(request));
|
||||
logMap.put("elapsedTime", String.valueOf(System.currentTimeMillis() - startTime));
|
||||
logMap.put("clientIp", request.getRemoteAddr());
|
||||
logMap.put("requestBody", JsonUtils.obj2String(point.getArgs()));
|
||||
logMap.put(Constant.LOG_TRACE_ID, Strings.nullToEmpty(MDC.get(Constant.LOG_TRACE_ID)));
|
||||
logMap.put("responseBody", message);
|
||||
|
||||
// aliyunLogManager.sendLog(projcet, logStore, topic, logMap);
|
||||
} catch (Exception e) {
|
||||
log.error("log report request error", e);
|
||||
}
|
||||
}
|
||||
|
||||
private String getHeaders(HttpServletRequest request) {
|
||||
return Collections.list(request.getHeaderNames())
|
||||
.stream()
|
||||
.collect(Collectors.toMap(
|
||||
name -> name,
|
||||
request::getHeader)).toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package io.github.ehlxr.config;
|
||||
|
||||
|
||||
import io.github.ehlxr.util.SendAlarmUtil;
|
||||
import io.github.ehlxr.util.Try;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.ApplicationArguments;
|
||||
import org.springframework.boot.ApplicationRunner;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 项目初始化
|
||||
*
|
||||
* @author ehlxr
|
||||
* @since 2020/4/22.
|
||||
*/
|
||||
@Component
|
||||
public class Initialization implements ApplicationRunner {
|
||||
private static final Logger log = LoggerFactory.getLogger(Initialization.class);
|
||||
|
||||
@Value("${aliyun.oss.endpoint:}")
|
||||
private String endpoint;
|
||||
@Value("${aliyun.oss.accesskey.id:}")
|
||||
private String accessKeyId;
|
||||
@Value("${aliyun.oss.accesskey.secret:}")
|
||||
private String accessKeySecret;
|
||||
@Value("${aliyun.oss.bucket:}")
|
||||
private String bucket;
|
||||
@Value("${aliyun.oss.key-path:}")
|
||||
private String keyPath;
|
||||
@Value("${aliyun.oss.url-lifetime:0}")
|
||||
private Long urlLifetime;
|
||||
|
||||
@Value("${lk.jmeter.cmd:}")
|
||||
private String jmeterCmd;
|
||||
@Value("${location:}")
|
||||
private String location;
|
||||
|
||||
@Value("${lk.dingtalk-url:}")
|
||||
private String dingtalkUrl;
|
||||
|
||||
|
||||
@Override
|
||||
public void run(ApplicationArguments args) {
|
||||
// 初始化阿里云 OSS 配置信息
|
||||
// AliyunOssConfig config = AliyunOssConfig.newBuilder()
|
||||
// .endpoint(endpoint)
|
||||
// .accessKeyId(accessKeyId)
|
||||
// .accessKeySecret(accessKeySecret)
|
||||
// .bucketName(bucket)
|
||||
// .keyPath(keyPath)
|
||||
// .urlLifetime(urlLifetime)
|
||||
// .build();
|
||||
// log.info("aliyun oss config {}", config);
|
||||
// FileUploadUtil.init(config);
|
||||
//
|
||||
// if (!"develop".equals(location) && !"PRO2".equals(location)) {
|
||||
// try {
|
||||
// ExecShell.execShellCommand(jmeterCmd);
|
||||
// } catch (Exception e) {
|
||||
// log.error("exec jmeter cmd error {}", e.getMessage());
|
||||
// }
|
||||
// }
|
||||
|
||||
// 预警信息发送初始化
|
||||
Try.of(() -> SendAlarmUtil.init(dingtalkUrl))
|
||||
.trap(e -> log.warn("int SendAlarmUtil error: {}", e.getMessage()))
|
||||
.run();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2022 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.config;
|
||||
|
||||
// import com.ctrip.framework.apollo.model.ConfigChangeEvent;
|
||||
// import com.ctrip.framework.apollo.spring.annotation.ApolloConfigChangeListener;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.logging.LoggingSystem;
|
||||
// import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 结合 apollo 配置中心动态刷新(logging.level.)日志级别
|
||||
*
|
||||
* @author ehlxr
|
||||
* @since 2022-01-06 17:43.
|
||||
*/
|
||||
// @Component
|
||||
public class LoggerLevelRefresher {
|
||||
private static final Logger logger = LoggerFactory.getLogger(LoggerLevelRefresher.class);
|
||||
private static final String LOGGER_TAG = "logging.level.";
|
||||
private final LoggingSystem loggingSystem;
|
||||
|
||||
@Autowired
|
||||
public LoggerLevelRefresher(LoggingSystem loggingSystem) {
|
||||
this.loggingSystem = loggingSystem;
|
||||
}
|
||||
|
||||
// @ApolloConfigChangeListener(interestedKeyPrefixes = LOGGER_TAG)
|
||||
// private void onChange(ConfigChangeEvent changeEvent) {
|
||||
// for (String key : changeEvent.changedKeys()) {
|
||||
// String strLevel = changeEvent.getChange(key).getNewValue();
|
||||
// loggingSystem.setLogLevel(key.replaceAll(LOGGER_TAG, ""),
|
||||
// LogLevel.valueOf(strLevel.toUpperCase()));
|
||||
//
|
||||
// logger.info("logging changed: {}, oldValue: {}, newValue: {}",
|
||||
// key, changeEvent.getChange(key).getOldValue(), strLevel);
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2020 xrv <xrg@live.com>
|
||||
* Copyright © 2020 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -22,25 +22,34 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.extension;
|
||||
package io.github.ehlxr.controller;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* 把一个接口标识成扩展点。
|
||||
* <p>
|
||||
* 没有此注释的接口 {@link ExtensionLoader} 会拒绝接管
|
||||
*
|
||||
* @author ehlxr
|
||||
* @see ExtensionLoader
|
||||
* @since 2021-08-29 18:45.
|
||||
*/
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.TYPE})
|
||||
public @interface SPI {
|
||||
@RestController
|
||||
@Api(tags = "测试辅助接口")
|
||||
public class IndexController {
|
||||
private static final Logger log = LoggerFactory.getLogger(IndexController.class);
|
||||
|
||||
/**
|
||||
* the default extension name.
|
||||
* 健康检测
|
||||
*/
|
||||
String value() default "";
|
||||
@ApiOperation(value = "健康检测", notes = "健康检测")
|
||||
@GetMapping("/healthcheck")
|
||||
public String healthcheck() {
|
||||
log.debug("env {}", System.getProperty("env"));
|
||||
|
||||
return "ok";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2021 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.controller.redis;
|
||||
|
||||
import io.github.ehlxr.util.RedisUtil;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @author ehlxr
|
||||
* @since 2021-08-30 10:08.
|
||||
*/
|
||||
@RestController
|
||||
@Api(tags = "Redis 测试接口")
|
||||
@RequestMapping("/redis")
|
||||
public class RedisController {
|
||||
private static final Logger log = LoggerFactory.getLogger(RedisController.class);
|
||||
|
||||
|
||||
/**
|
||||
* Redis 锁测试
|
||||
*/
|
||||
@ApiOperation(value = "Redis 锁", notes = "Redis 锁测试")
|
||||
@GetMapping("/lock/test")
|
||||
public void lockTest() {
|
||||
Runnable runnable = () -> {
|
||||
String uuid = UUID.randomUUID().toString();
|
||||
log.info("{} retry lock...", Thread.currentThread().getName());
|
||||
boolean lock = RedisUtil.getDistributedLock("lock", uuid, 30_000);
|
||||
if (lock) {
|
||||
log.info("{} get lock!", Thread.currentThread().getName());
|
||||
|
||||
try {
|
||||
TimeUnit.SECONDS.sleep(1);
|
||||
// ...
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
Boolean locak = RedisUtil.releaseDistributedLock("lock", uuid);
|
||||
log.info("{} release lock {}", Thread.currentThread().getName(), locak);
|
||||
}
|
||||
}
|
||||
};
|
||||
new Thread(runnable, "t1").start();
|
||||
new Thread(runnable, "t2").start();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package io.github.ehlxr.filter;
|
||||
|
||||
import io.github.ehlxr.common.Constant;
|
||||
import io.github.ehlxr.util.IdUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.slf4j.MDC;
|
||||
import org.springframework.core.annotation.Order;
|
||||
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.annotation.WebFilter;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* auth filter
|
||||
*
|
||||
* @author supeng
|
||||
* @date 2020/08/31
|
||||
*/
|
||||
@Order(value = 1)
|
||||
@WebFilter(filterName = "customFilter", urlPatterns = {"/api/*"})
|
||||
public class CustomFilter implements Filter {
|
||||
private static final Logger log = LoggerFactory.getLogger(CustomFilter.class);
|
||||
|
||||
@Override
|
||||
public void init(FilterConfig filterConfig) {
|
||||
log.info("customFilter init");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
|
||||
throws IOException, ServletException {
|
||||
MDC.put(Constant.LOG_TRACE_ID, String.valueOf(IdUtil.localId()));
|
||||
filterChain.doFilter(servletRequest, servletResponse);
|
||||
MDC.remove(Constant.LOG_TRACE_ID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
log.info("customFilter destroy");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package io.github.ehlxr.handler;
|
||||
|
||||
import io.github.ehlxr.common.Constant;
|
||||
import io.github.ehlxr.common.Result;
|
||||
import io.github.ehlxr.enums.CodeEnum;
|
||||
import io.github.ehlxr.exception.ServiceDataException;
|
||||
import org.assertj.core.util.Strings;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.slf4j.MDC;
|
||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.multipart.MultipartException;
|
||||
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* @author ehlxr
|
||||
* @since 2020/4/20.
|
||||
*/
|
||||
@ControllerAdvice
|
||||
public class GlobalExceptionHandler {
|
||||
private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);
|
||||
|
||||
@ExceptionHandler(Exception.class)
|
||||
@ResponseBody
|
||||
public Result<?> defaultExceptionHandler(HttpServletRequest request, Exception e) {
|
||||
log.error("request: {}, exception: ", request.getRequestURI(), e);
|
||||
|
||||
// SendAlarmUtil.send(String.format("未知异常 request: %s, exception: %s", request.getRequestURI(), ExceptionUtils.getStackTrace(e)),
|
||||
// (t, u) -> log.info("send exception message to dingtalk result {} ", t, u));
|
||||
|
||||
String msg = CodeEnum.UNKNOWN_EXCEPTION.getMessage();
|
||||
String traceId = MDC.get(Constant.LOG_TRACE_ID);
|
||||
if (!Strings.isNullOrEmpty(traceId)) {
|
||||
msg = String.format("%s(%s)", msg, traceId);
|
||||
}
|
||||
|
||||
return Result.of(CodeEnum.UNKNOWN_EXCEPTION.getCode(), null, msg);
|
||||
}
|
||||
|
||||
@ExceptionHandler(ServiceDataException.class)
|
||||
@ResponseBody
|
||||
public Result<?> serviceDataExceptionHandler(HttpServletRequest request, ServiceDataException e) {
|
||||
log.error("request: {} service exception: ", request.getRequestURI(), e);
|
||||
|
||||
// SendAlarmUtil.send(String.format("业务异常 request: %s, service exception: %s", request.getRequestURI(), ExceptionUtils.getStackTrace(e)),
|
||||
// (t, u) -> log.info("send service exception message to dingtalk result {} ", t, u));
|
||||
|
||||
String msg = e.getMessage();
|
||||
String traceId = MDC.get(Constant.LOG_TRACE_ID);
|
||||
if (!Strings.isNullOrEmpty(traceId)) {
|
||||
msg = String.format("%s(%s)", msg, traceId);
|
||||
}
|
||||
|
||||
return Result.of(e.getCode(), null, msg);
|
||||
}
|
||||
|
||||
@ExceptionHandler(MultipartException.class)
|
||||
public String handleError(MultipartException e, RedirectAttributes redirectAttributes) {
|
||||
redirectAttributes.addFlashAttribute("message", e.getCause().getMessage());
|
||||
return "redirect:/uploadStatus";
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2020 xrv <xrg@live.com>
|
||||
* Copyright © 2020 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -22,34 +22,31 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr;
|
||||
package io.github.ehlxr.interceptor;
|
||||
|
||||
import io.github.ehlxr.common.Constant;
|
||||
import io.github.ehlxr.util.IdUtil;
|
||||
import org.slf4j.MDC;
|
||||
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* 日志 traceid Interceptor
|
||||
*
|
||||
* @author ehlxr
|
||||
* @date 2018/8/21
|
||||
* @since 2020-12-23 11:23.
|
||||
*/
|
||||
public class ReferenceCountingGC {
|
||||
public Object instance = null;
|
||||
private static final int _1MB = 1024 * 1024;
|
||||
/**
|
||||
* 这个成员属性的唯一意义就是占点内存,以便在能在 GC 日志中看清楚是否有回收过
|
||||
*/
|
||||
private final byte[] bigSize = new byte[2 * _1MB];
|
||||
|
||||
public static void testGC() {
|
||||
ReferenceCountingGC objA = new ReferenceCountingGC();
|
||||
ReferenceCountingGC objB = new ReferenceCountingGC();
|
||||
objA.instance = objB;
|
||||
objB.instance = objA;
|
||||
|
||||
objA = null;
|
||||
objB = null;
|
||||
|
||||
// 假设在这行发生 GC,objA 和 objB 是否能被回收?
|
||||
System.gc();
|
||||
public class TraceInterceptor extends HandlerInterceptorAdapter {
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
|
||||
MDC.put(Constant.LOG_TRACE_ID, String.valueOf(IdUtil.localId()));
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
testGC();
|
||||
@Override
|
||||
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
|
||||
MDC.remove(Constant.LOG_TRACE_ID);
|
||||
}
|
||||
}
|
||||
17
budd-server/src/main/resources/application-dev.yml
Normal file
17
budd-server/src/main/resources/application-dev.yml
Normal file
@@ -0,0 +1,17 @@
|
||||
server:
|
||||
port: 8081
|
||||
|
||||
springfox:
|
||||
documentation:
|
||||
enabled: true
|
||||
swagger:
|
||||
base-package: io.github.ehlxr
|
||||
base-path: /**
|
||||
contact:
|
||||
email: xrv@live.com
|
||||
name: rtg
|
||||
url: https://ehlxr.me
|
||||
description: swagger of budd server
|
||||
exclude-path: /error, /ops/**
|
||||
title: budd swagger
|
||||
version: 0.0.1-SNAPSHOT
|
||||
18
budd-server/src/main/resources/application.yml
Normal file
18
budd-server/src/main/resources/application.yml
Normal file
@@ -0,0 +1,18 @@
|
||||
spring:
|
||||
profiles:
|
||||
active: dev
|
||||
application:
|
||||
name: budd
|
||||
|
||||
server:
|
||||
tomcat:
|
||||
uri-encoding: UTF-8
|
||||
accept-count: 1000
|
||||
connection-timeout: 30000
|
||||
servlet:
|
||||
context-path: /budd
|
||||
session:
|
||||
timeout: 60
|
||||
logging:
|
||||
file:
|
||||
path: /Users/ehlxr/logs/${spring.application.name}
|
||||
264
budd-server/src/main/resources/logback-spring.xml
Normal file
264
budd-server/src/main/resources/logback-spring.xml
Normal file
@@ -0,0 +1,264 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- 日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果设置为WARN,则低于WARN的信息都不会输出 -->
|
||||
<!-- scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true -->
|
||||
<!-- scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。 -->
|
||||
<!-- debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 -->
|
||||
<configuration scan="true" scanPeriod="10 seconds">
|
||||
<!--<include resource="org/springframework/boot/logging/logback/base.xml"/>-->
|
||||
|
||||
<contextName>logback</contextName>
|
||||
<!-- name的值是变量的名称,value的值时变量定义的值。通过定义的值会被插入到logger上下文中。定义变量后,可以使“${}”来使用变量。 -->
|
||||
<!-- <property name="LOG_PATH" value="${logging.file.path}" />-->
|
||||
|
||||
<springProperty name="LOG_PATH" source="logging.file.path"/>
|
||||
<!--<springProperty name="ALIYUN_LOG_ENDPOINT" source="aliyun.log.endpoint"/>-->
|
||||
<!--<springProperty name="ALIYUN_LOG_ACCESSKEYID" source="aliyun.log.accessKeyId"/>-->
|
||||
<!--<springProperty name="ALIYUN_LOG_ACCESSKEYSECRET" source="aliyun.log.accessKeySecret"/>-->
|
||||
<!--<springProperty name="ALIYUN_LOG_PROJECT" source="aliyun.log.project"/>-->
|
||||
<!--<springProperty name="ALIYUN_LOG_LOGSTORE_INFO" source="aliyun.log.logstore.info"/>-->
|
||||
<!--<springProperty name="ALIYUN_LOG_LOGSTORE_ERROR" source="aliyun.log.logstore.error"/>-->
|
||||
|
||||
<!-- 彩色日志 -->
|
||||
<!-- 彩色日志依赖的渲染类 -->
|
||||
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/>
|
||||
<conversionRule conversionWord="wex"
|
||||
converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/>
|
||||
<conversionRule conversionWord="wEx"
|
||||
converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/>
|
||||
<!-- 彩色日志格式 -->
|
||||
<property name="CONSOLE_LOG_PATTERN"
|
||||
value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr([%X{logTraceId}]){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
|
||||
<!--<property name="CONSOLE_LOG_PATTERN"-->
|
||||
<!-- value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr([%X{√logTraceId}]){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(at %class.%method){cyan} \\(%file:%line\\) %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>-->
|
||||
|
||||
<!--输出到控制台-->
|
||||
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<!--此日志appender是为开发使用,只配置最底级别,控制台输出的日志级别是大于或等于此级别的日志信息-->
|
||||
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
|
||||
<level>debug</level>
|
||||
</filter>
|
||||
<encoder>
|
||||
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
|
||||
<!-- 设置字符集 -->
|
||||
<charset>UTF-8</charset>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!--输出到文件-->
|
||||
<!-- 时间滚动输出 level为 DEBUG 日志 -->
|
||||
<appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<!-- 正在记录的日志文件的路径及文件名 -->
|
||||
<file>${LOG_PATH}/debug.log</file>
|
||||
<!--日志文件输出格式-->
|
||||
<encoder>
|
||||
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%X{logTraceId}] %logger{50} [%L] - %msg%n</pattern>
|
||||
<charset>UTF-8</charset> <!-- 设置字符集 -->
|
||||
</encoder>
|
||||
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<!-- 日志归档 -->
|
||||
<fileNamePattern>${LOG_PATH}/debug/%d{yyyy-MM-dd}.%i.log</fileNamePattern>
|
||||
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
|
||||
<maxFileSize>100MB</maxFileSize>
|
||||
</timeBasedFileNamingAndTriggeringPolicy>
|
||||
<!--日志文件保留天数-->
|
||||
<maxHistory>15</maxHistory>
|
||||
</rollingPolicy>
|
||||
<!-- 此日志文件只记录debug级别的 -->
|
||||
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||
<level>debug</level>
|
||||
<onMatch>ACCEPT</onMatch>
|
||||
<onMismatch>DENY</onMismatch>
|
||||
</filter>
|
||||
</appender>
|
||||
|
||||
<!-- 时间滚动输出 level为 INFO 日志 -->
|
||||
<appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<!-- 正在记录的日志文件的路径及文件名 -->
|
||||
<file>${LOG_PATH}/info.log</file>
|
||||
<!--日志文件输出格式-->
|
||||
<encoder>
|
||||
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%X{logTraceId}] %logger{50} [%L] - %msg%n</pattern>
|
||||
<charset>UTF-8</charset>
|
||||
</encoder>
|
||||
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<!-- 每天日志归档路径以及格式 -->
|
||||
<fileNamePattern>${LOG_PATH}/info/%d{yyyy-MM-dd}.%i.log</fileNamePattern>
|
||||
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
|
||||
<maxFileSize>100MB</maxFileSize>
|
||||
</timeBasedFileNamingAndTriggeringPolicy>
|
||||
<!--日志文件保留天数-->
|
||||
<maxHistory>15</maxHistory>
|
||||
</rollingPolicy>
|
||||
<!-- 此日志文件只记录info级别的 -->
|
||||
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||
<level>info</level>
|
||||
<onMatch>ACCEPT</onMatch>
|
||||
<onMismatch>DENY</onMismatch>
|
||||
</filter>
|
||||
</appender>
|
||||
|
||||
<!-- 时间滚动输出 level为 WARN 日志 -->
|
||||
<appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<!-- 正在记录的日志文件的路径及文件名 -->
|
||||
<file>${LOG_PATH}/warn.log</file>
|
||||
<!--日志文件输出格式-->
|
||||
<encoder>
|
||||
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%X{logTraceId}] %logger{50} [%L] - %msg%n</pattern>
|
||||
<charset>UTF-8</charset> <!-- 此处设置字符集 -->
|
||||
</encoder>
|
||||
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_PATH}/warn/%d{yyyy-MM-dd}.%i.log</fileNamePattern>
|
||||
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
|
||||
<maxFileSize>100MB</maxFileSize>
|
||||
</timeBasedFileNamingAndTriggeringPolicy>
|
||||
<!--日志文件保留天数-->
|
||||
<maxHistory>15</maxHistory>
|
||||
</rollingPolicy>
|
||||
<!-- 此日志文件只记录warn级别的 -->
|
||||
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||
<level>warn</level>
|
||||
<onMatch>ACCEPT</onMatch>
|
||||
<onMismatch>DENY</onMismatch>
|
||||
</filter>
|
||||
</appender>
|
||||
|
||||
<!-- 时间滚动输出 level为 ERROR 日志 -->
|
||||
<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<!-- 正在记录的日志文件的路径及文件名 -->
|
||||
<file>${LOG_PATH}/error.log</file>
|
||||
<!--日志文件输出格式-->
|
||||
<encoder>
|
||||
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%X{logTraceId}] %logger{50} [%L] - %msg%n</pattern>
|
||||
<charset>UTF-8</charset> <!-- 此处设置字符集 -->
|
||||
</encoder>
|
||||
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_PATH}/error/%d{yyyy-MM-dd}.%i.log</fileNamePattern>
|
||||
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
|
||||
<maxFileSize>100MB</maxFileSize>
|
||||
</timeBasedFileNamingAndTriggeringPolicy>
|
||||
<!--日志文件保留天数-->
|
||||
<maxHistory>15</maxHistory>
|
||||
</rollingPolicy>
|
||||
<!-- 此日志文件只记录ERROR级别的 -->
|
||||
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||
<level>ERROR</level>
|
||||
<onMatch>ACCEPT</onMatch>
|
||||
<onMismatch>DENY</onMismatch>
|
||||
</filter>
|
||||
</appender>
|
||||
<!--
|
||||
<appender name="ALIYUN_LOG_INFO" class="com.aliyun.openservices.log.logback.LoghubAppender">
|
||||
<endpoint>${ALIYUN_LOG_ENDPOINT}</endpoint>
|
||||
<accessKeyId>${ALIYUN_LOG_ACCESSKEYID}</accessKeyId>
|
||||
<accessKeySecret>${ALIYUN_LOG_ACCESSKEYSECRET}</accessKeySecret>
|
||||
<project>${ALIYUN_LOG_PROJECT}</project>
|
||||
<logStore>${ALIYUN_LOG_LOGSTORE_INFO}</logStore>
|
||||
|
||||
<totalSizeInBytes>104857600</totalSizeInBytes>
|
||||
<maxBlockMs>0</maxBlockMs>
|
||||
<ioThreadCount>8</ioThreadCount>
|
||||
<batchSizeThresholdInBytes>524288</batchSizeThresholdInBytes>
|
||||
<batchCountThreshold>4096</batchCountThreshold>
|
||||
<lingerMs>2000</lingerMs>
|
||||
<retries>10</retries>
|
||||
<baseRetryBackoffMs>100</baseRetryBackoffMs>
|
||||
<maxRetryBackoffMs>50000</maxRetryBackoffMs>
|
||||
|
||||
<encoder>
|
||||
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%X{logTraceId}] %logger{50} [%L] - %msg%n</pattern>
|
||||
<charset>UTF-8</charset>
|
||||
</encoder>
|
||||
|
||||
<timeFormat>yyyy-MM-dd'T'HH:mmZ</timeFormat>
|
||||
<timeZone>Asia/Shanghai</timeZone>
|
||||
|
||||
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||
<level>INFO</level>
|
||||
</filter>
|
||||
|
||||
<mdcFields>logTraceId</mdcFields>
|
||||
</appender>
|
||||
|
||||
<appender name="ALIYUN_LOG_ERROR" class="com.aliyun.openservices.log.logback.LoghubAppender">
|
||||
<endpoint>${ALIYUN_LOG_ENDPOINT}</endpoint>
|
||||
<accessKeyId>${ALIYUN_LOG_ACCESSKEYID}</accessKeyId>
|
||||
<accessKeySecret>${ALIYUN_LOG_ACCESSKEYSECRET}</accessKeySecret>
|
||||
<project>${ALIYUN_LOG_PROJECT}</project>
|
||||
<logStore>${ALIYUN_LOG_LOGSTORE_ERROR}</logStore>
|
||||
|
||||
<totalSizeInBytes>104857600</totalSizeInBytes>
|
||||
<maxBlockMs>0</maxBlockMs>
|
||||
<ioThreadCount>8</ioThreadCount>
|
||||
<batchSizeThresholdInBytes>524288</batchSizeThresholdInBytes>
|
||||
<batchCountThreshold>4096</batchCountThreshold>
|
||||
<lingerMs>2000</lingerMs>
|
||||
<retries>10</retries>
|
||||
<baseRetryBackoffMs>100</baseRetryBackoffMs>
|
||||
<maxRetryBackoffMs>50000</maxRetryBackoffMs>
|
||||
|
||||
<encoder>
|
||||
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%X{logTraceId}] %logger{50} [%L] - %msg%n</pattern>
|
||||
<charset>UTF-8</charset>
|
||||
</encoder>
|
||||
|
||||
<timeFormat>yyyy-MM-dd'T'HH:mmZ</timeFormat>
|
||||
<timeZone>Asia/Shanghai</timeZone>
|
||||
|
||||
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
|
||||
<level>ERROR</level>
|
||||
</filter>
|
||||
|
||||
<mdcFields>logTraceId</mdcFields>
|
||||
</appender>
|
||||
-->
|
||||
<!--
|
||||
<logger>用来设置某一个包或者具体的某一个类的日志打印级别、
|
||||
以及指定<appender>。<logger>仅有一个name属性,
|
||||
一个可选的level和一个可选的addtivity属性。
|
||||
name:用来指定受此logger约束的某一个包或者具体的某一个类。
|
||||
level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,
|
||||
还有一个特俗值INHERITED或者同义词NULL,代表强制执行上级的级别。
|
||||
如果未设置此属性,那么当前logger将会继承上级的级别。
|
||||
addtivity:是否向上级logger传递打印信息。默认是true。
|
||||
-->
|
||||
<!--<logger name="org.springframework.web" level="info"/>-->
|
||||
<!--<logger name="org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor" level="INFO"/>-->
|
||||
<!--
|
||||
使用mybatis的时候,sql语句是debug下才会打印,而这里我们只配置了info,所以想要查看sql语句的话,有以下两种操作:
|
||||
第一种把<root level="info">改成<root level="DEBUG">这样就会打印sql,不过这样日志那边会出现很多其他消息
|
||||
第二种就是单独给dao下目录配置debug模式,代码如下,这样配置sql语句会打印,其他还是正常info级别:
|
||||
-->
|
||||
|
||||
<!--
|
||||
root节点是必选节点,用来指定最基础的日志输出级别,只有一个level属性
|
||||
level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,
|
||||
不能设置为INHERITED或者同义词NULL。默认是DEBUG
|
||||
可以包含零个或多个元素,标识这个appender将会添加到这个logger。
|
||||
-->
|
||||
|
||||
<springProfile name="dev">
|
||||
<logger name="io.github.ehlxr" level="debug"/>
|
||||
</springProfile>
|
||||
<!--<logger name="com.netflix.discovery.shared.resolver.aws.ConfigClusterResolver" level="warn"/>-->
|
||||
|
||||
<!-- 可用来获取 StatusManager 中的状态 -->
|
||||
<!--<statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener"/>-->
|
||||
<!-- 解决 aliyun loghub debug模式下循环发送的问题 -->
|
||||
<logger name="org.apache.http.impl.conn.Wire" level="WARN"/>
|
||||
<!--aliyun loghub 为了防止进程退出时,内存中的数据丢失,请加上此选项-->
|
||||
<shutdownHook class="ch.qos.logback.core.hook.DelayingShutdownHook"/>
|
||||
|
||||
<root level="info">
|
||||
<appender-ref ref="CONSOLE"/>
|
||||
<!--<appender-ref ref="DEBUG_FILE"/>-->
|
||||
<!--<appender-ref ref="INFO_FILE"/>-->
|
||||
<!--<appender-ref ref="WARN_FILE"/>-->
|
||||
<!--<appender-ref ref="ERROR_FILE"/>-->
|
||||
<!--<appender-ref ref="ALIYUN_LOG_INFO"/>-->
|
||||
<!--<appender-ref ref="ALIYUN_LOG_ERROR"/>-->
|
||||
</root>
|
||||
</configuration>
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.tzld.activity;
|
||||
|
||||
import io.github.ehlxr.semaphore.RedisSemaphore;
|
||||
import io.github.ehlxr.semaphore.SemaphoreInfo;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import java.util.concurrent.*;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest()
|
||||
class ServerApplicationTests {
|
||||
|
||||
ThreadPoolExecutor pool = new ThreadPoolExecutor(10, 10, 0, TimeUnit.MINUTES,
|
||||
new LinkedBlockingQueue<>(),
|
||||
Executors.defaultThreadFactory(),
|
||||
new ThreadPoolExecutor.CallerRunsPolicy());
|
||||
@Autowired
|
||||
private RedisTemplate<String, String> redisTemplate;
|
||||
|
||||
@Test
|
||||
public void testNonFair() throws InterruptedException {
|
||||
SemaphoreInfo semaphoreInfo = new SemaphoreInfo("NonFair", 5, 10);
|
||||
for (int i = 0; i < 10; i++) {
|
||||
String id = String.valueOf(i);
|
||||
RedisSemaphore semaphore = new RedisSemaphore(semaphoreInfo, redisTemplate, id);
|
||||
CompletableFuture.supplyAsync(semaphore::tryAcquire, pool).thenAcceptAsync((r) -> {
|
||||
if (r) System.out.println(id + "成功获取到信号量 (NonFair)~ ⭐⭐⭐");
|
||||
else System.out.println(id + "没有获取到信号量 (NonFair)");
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
semaphore.release();
|
||||
}, pool);
|
||||
}
|
||||
Thread.sleep(Long.MAX_VALUE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFair() throws ExecutionException, InterruptedException {
|
||||
SemaphoreInfo semaphoreInfo = new SemaphoreInfo("Fair", 5, 10, true);
|
||||
for (int i = 0; i < 10; i++) {
|
||||
String id = String.valueOf(i);
|
||||
RedisSemaphore semaphore = new RedisSemaphore(semaphoreInfo, redisTemplate, id);
|
||||
CompletableFuture.supplyAsync(semaphore::tryAcquire, pool).thenAcceptAsync((r) -> {
|
||||
if (r) System.out.println(id + "成功获取到信号量 (Fair)~~ ⭐⭐⭐");
|
||||
else System.out.println(id + "没有获取到信号量 (Fair)");
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
semaphore.release();
|
||||
}, pool);
|
||||
}
|
||||
Thread.sleep(Long.MAX_VALUE);
|
||||
}
|
||||
|
||||
}
|
||||
38
budd-utils/pom.xml
Normal file
38
budd-utils/pom.xml
Normal file
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>io.github.ehlxr</groupId>
|
||||
<artifactId>budd</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>budd-utils</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<version>3.2.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-sources</id>
|
||||
<goals>
|
||||
<goal>jar-no-fork</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
424
budd-utils/src/main/java/io/github/ehlxr/utils/Try.java
Normal file
424
budd-utils/src/main/java/io/github/ehlxr/utils/Try.java
Normal file
@@ -0,0 +1,424 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2020 xrv <xrv@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* 异常处理,简化 try catch
|
||||
*
|
||||
* @author ehlxr
|
||||
* @since 2020-12-03 10:37.
|
||||
*/
|
||||
public interface Try {
|
||||
/**
|
||||
* 构建消费型(有入参,无返回)Tryable 对象
|
||||
*
|
||||
* @param consumer {@link ThrowableConsumer} 类型函数式接口
|
||||
* @param <P> 入参类型
|
||||
* @return {@link TryConsumer}
|
||||
*/
|
||||
static <P> TryConsumer<P> of(ThrowableConsumer<? super P> consumer) {
|
||||
return new TryConsumer<>(consumer);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建供给型(无入参,有返回)Tryable 对象
|
||||
*
|
||||
* @param supplier {@link ThrowableSupplier} 类型函数式接口
|
||||
* @param <R> 返回值类型
|
||||
* @return {@link TrySupplier}
|
||||
*/
|
||||
static <R> TrySupplier<R> of(ThrowableSupplier<? extends R> supplier) {
|
||||
return new TrySupplier<>(supplier);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建功能型(有入参,有返回)Tryable 对象
|
||||
*
|
||||
* @param function {@link ThrowableFunction} 类型函数式接口
|
||||
* @param <P> 入参类型
|
||||
* @param <R> 返回值类型
|
||||
* @return {@link TryFunction}
|
||||
*/
|
||||
static <P, R> TryFunction<P, R> of(ThrowableFunction<? super P, ? extends R> function) {
|
||||
return new TryFunction<>(function);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建运行型(无入参,无返回)Tryable 对象
|
||||
*
|
||||
* @param runnable {@link ThrowableRunnable} 类型函数式接口
|
||||
* @return {@link TryRunnable}
|
||||
*/
|
||||
static TryRunnable of(ThrowableRunnable runnable) {
|
||||
return new TryRunnable(runnable);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"ConstantConditions", "Convert2MethodRef"})
|
||||
static void main(String[] args) {
|
||||
System.out.println("------------有返回值,无入参----------------");
|
||||
// 有返回值,无入参
|
||||
String param = "hello";
|
||||
Long result = Try.of(() -> Long.valueOf(param)).get(0L);
|
||||
System.out.println("Long.valueOf 1: " + result);
|
||||
|
||||
result = Try.of(() -> Long.valueOf(param)).get();
|
||||
System.out.println("Long.valueOf 2: " + result);
|
||||
|
||||
System.out.println("------------有返回值,有入参----------------");
|
||||
// 有返回值,有入参
|
||||
result = Try.<Map<String, String>, Long>of(s -> Long.valueOf(s.get("k1")))
|
||||
// .apply(ImmutableMap.of("k1", param))
|
||||
.trap(e -> System.out.println("Long.valueOf exception: " + e.getMessage()))
|
||||
.andFinally(() -> System.out.println("This message will ignore."))
|
||||
.andFinally(s -> {
|
||||
// Map<String, Object> returnMap = JsonUtils.string2Obj(JsonUtils.obj2String(s), new TypeReference<Map<String, Object>>() {
|
||||
// });
|
||||
// System.out.println("Long.valueOf finally run code." + s);
|
||||
// // 演示抛异常
|
||||
// String k2 = returnMap.get("k2").toString();
|
||||
// System.out.println(k2);
|
||||
})
|
||||
.finallyTrap(e -> System.out.println("Long.valueOf finally exception: " + e.getMessage()))
|
||||
.get();
|
||||
System.out.println("Long.valueOf 3: " + result);
|
||||
|
||||
ArrayList<String> list = null;
|
||||
|
||||
System.out.println("-----------无返回值,无入参-----------------");
|
||||
// 无返回值,无入参
|
||||
Try.of(() -> Thread.sleep(-1L))
|
||||
.andFinally(() -> list.clear())
|
||||
// .andFinally(list::clear) //https://stackoverflow.com/questions/37413106/java-lang-nullpointerexception-is-thrown-using-a-method-reference-but-not-a-lamb
|
||||
.run();
|
||||
|
||||
System.out.println("--------------无返回值,有入参--------------");
|
||||
// 无返回值,有入参
|
||||
Try.<String>of(v -> list.add(0, v))
|
||||
.andFinally(s -> System.out.println(s))
|
||||
.accept("hello");
|
||||
}
|
||||
|
||||
class TryRunnable extends Tryable<TryRunnable> {
|
||||
private final ThrowableRunnable runnable;
|
||||
|
||||
protected TryRunnable(ThrowableRunnable runnable) {
|
||||
Objects.requireNonNull(runnable, "No runnable present");
|
||||
this.runnable = runnable;
|
||||
|
||||
super.c = this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算结果
|
||||
*/
|
||||
public void run() {
|
||||
try {
|
||||
runnable.run();
|
||||
} catch (final Throwable e) {
|
||||
Optional.ofNullable(throwConsumer).ifPresent(tc -> tc.accept(e));
|
||||
} finally {
|
||||
doFinally();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class TrySupplier<R> extends Tryable<TrySupplier<R>> {
|
||||
private final ThrowableSupplier<? extends R> supplier;
|
||||
|
||||
protected TrySupplier(ThrowableSupplier<? extends R> supplier) {
|
||||
Objects.requireNonNull(supplier, "No supplier present");
|
||||
this.supplier = supplier;
|
||||
|
||||
super.c = this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 如果有异常返回默认值,否则返回计算结果
|
||||
*
|
||||
* @param r 指定默认值
|
||||
* @return 实际值或默认值
|
||||
*/
|
||||
public R get(R r) {
|
||||
try {
|
||||
return supplier.get();
|
||||
} catch (final Throwable e) {
|
||||
Optional.ofNullable(throwConsumer).ifPresent(tc -> tc.accept(e));
|
||||
return r;
|
||||
} finally {
|
||||
doFinally();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 如果有异常返回 null,否则返回计算结果
|
||||
*
|
||||
* @return 实际值或 null
|
||||
*/
|
||||
public R get() {
|
||||
try {
|
||||
return supplier.get();
|
||||
} catch (final Throwable e) {
|
||||
Optional.ofNullable(throwConsumer).ifPresent(tc -> tc.accept(e));
|
||||
return null;
|
||||
} finally {
|
||||
doFinally();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
interface ThrowableConsumer<P> {
|
||||
/**
|
||||
* Performs this operation on the given argument.
|
||||
*
|
||||
* @param p the input argument
|
||||
* @throws Throwable throwable
|
||||
*/
|
||||
void accept(P p) throws Throwable;
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
interface ThrowableSupplier<R> {
|
||||
/**
|
||||
* Gets a result.
|
||||
*
|
||||
* @return a result
|
||||
* @throws Throwable throwable
|
||||
*/
|
||||
R get() throws Throwable;
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
interface ThrowableRunnable {
|
||||
/**
|
||||
* Performs this operation
|
||||
*
|
||||
* @throws Throwable throwable
|
||||
*/
|
||||
void run() throws Throwable;
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
interface ThrowableFunction<P, R> {
|
||||
/**
|
||||
* Applies this function to the given argument.
|
||||
*
|
||||
* @param p the function argument
|
||||
* @return the function result
|
||||
* @throws Throwable throwable
|
||||
*/
|
||||
R apply(P p) throws Throwable;
|
||||
}
|
||||
|
||||
abstract class Tryable<C> {
|
||||
Consumer<? super Throwable> throwConsumer;
|
||||
ThrowableRunnable finallyRunnable;
|
||||
ThrowableConsumer<? super Object> finallyConsumer;
|
||||
Consumer<? super Throwable> finallyThrowConsumer;
|
||||
C c;
|
||||
|
||||
/**
|
||||
* 处理 finally
|
||||
*/
|
||||
protected void doFinally() {
|
||||
Optional.ofNullable(finallyRunnable).ifPresent(r -> {
|
||||
try {
|
||||
r.run();
|
||||
} catch (final Throwable e) {
|
||||
Optional.ofNullable(finallyThrowConsumer).ifPresent(tc -> tc.accept(e));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理带参数类型 finally
|
||||
*
|
||||
* @param p 入参
|
||||
* @param <P> 入参类型
|
||||
*/
|
||||
protected <P> void doFinally(P p) {
|
||||
if (Objects.nonNull(finallyConsumer)) {
|
||||
try {
|
||||
finallyConsumer.accept(p);
|
||||
} catch (final Throwable e) {
|
||||
Optional.ofNullable(finallyThrowConsumer).ifPresent(tc -> tc.accept(e));
|
||||
}
|
||||
} else {
|
||||
doFinally();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 如果有异常,调用自定义异常处理表达式
|
||||
*
|
||||
* @param throwableConsumer 自定义异常处理 lambda 表达式
|
||||
* @return {@link C}
|
||||
*/
|
||||
public C trap(Consumer<? super Throwable> throwableConsumer) {
|
||||
Objects.requireNonNull(throwableConsumer, "No throwableConsumer present");
|
||||
this.throwConsumer = throwableConsumer;
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定义 finally 处理表达式
|
||||
* <p>
|
||||
* 注意:如果类型为 {@link TryConsumer}、{@link TryFunction} 并且已经调用 {@link #andFinally(ThrowableConsumer)} 则忽略
|
||||
*
|
||||
* @param finallyRunnable finally 处理 lambda 表达式
|
||||
* @return {@link C}
|
||||
*/
|
||||
public C andFinally(ThrowableRunnable finallyRunnable) {
|
||||
Objects.requireNonNull(finallyRunnable, "No finallyRunnable present");
|
||||
this.finallyRunnable = finallyRunnable;
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定义 finally 处理表达式
|
||||
* <p>
|
||||
* 注意:只会对 {@link TryConsumer}、{@link TryFunction} 类型对象起作用
|
||||
*
|
||||
* @param finallyConsumer finally 处理 lambda 表达式
|
||||
* @return {@link C}
|
||||
*/
|
||||
public C andFinally(ThrowableConsumer<? super Object> finallyConsumer) {
|
||||
Objects.requireNonNull(finallyConsumer, "No finallyConsumer present");
|
||||
this.finallyConsumer = finallyConsumer;
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* 如果 finally 有异常,调用自定义异常处理表达式
|
||||
*
|
||||
* @param finallyThrowableConsumer 自定义异常处理 lambda 表达式
|
||||
* @return {@link C}
|
||||
*/
|
||||
public C finallyTrap(Consumer<? super Throwable> finallyThrowableConsumer) {
|
||||
Objects.requireNonNull(finallyThrowableConsumer, "No finallyThrowableConsumer present");
|
||||
this.finallyThrowConsumer = finallyThrowableConsumer;
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
class TryConsumer<P> extends Tryable<TryConsumer<P>> {
|
||||
private final ThrowableConsumer<? super P> consumer;
|
||||
|
||||
protected TryConsumer(ThrowableConsumer<? super P> consumer) {
|
||||
Objects.requireNonNull(consumer, "No consumer present");
|
||||
this.consumer = consumer;
|
||||
|
||||
super.c = this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算结果
|
||||
*
|
||||
* @param p 要计算的入参
|
||||
*/
|
||||
public void accept(P p) {
|
||||
try {
|
||||
Objects.requireNonNull(p, "No accept param present");
|
||||
|
||||
consumer.accept(p);
|
||||
} catch (final Throwable e) {
|
||||
Optional.ofNullable(throwConsumer).ifPresent(tc -> tc.accept(e));
|
||||
} finally {
|
||||
// doFinally();
|
||||
doFinally(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class TryFunction<P, R> extends Tryable<TryFunction<P, R>> {
|
||||
private final ThrowableFunction<? super P, ? extends R> function;
|
||||
private P p;
|
||||
|
||||
protected TryFunction(ThrowableFunction<? super P, ? extends R> function) {
|
||||
Objects.requireNonNull(function, "No function present");
|
||||
this.function = function;
|
||||
|
||||
super.c = this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 传入要计算的入参
|
||||
*
|
||||
* @param p 要计算的入参
|
||||
* @return {@link TryFunction}
|
||||
*/
|
||||
public TryFunction<P, R> apply(P p) {
|
||||
Objects.requireNonNull(p, "Apply param should not null");
|
||||
|
||||
this.p = p;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 如果有异常返回默认值,否则返回计算结果
|
||||
*
|
||||
* @param r 指定默认值
|
||||
* @return 实际值或默认值
|
||||
*/
|
||||
public R get(R r) {
|
||||
try {
|
||||
Objects.requireNonNull(function, "No apply param present");
|
||||
|
||||
return function.apply(p);
|
||||
} catch (final Throwable e) {
|
||||
Optional.ofNullable(throwConsumer).ifPresent(tc -> tc.accept(e));
|
||||
return r;
|
||||
} finally {
|
||||
// doFinally();
|
||||
doFinally(p);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 如果有异常返回 null,否则返回计算结果
|
||||
*
|
||||
* @return 实际值或 null
|
||||
*/
|
||||
public R get() {
|
||||
try {
|
||||
Objects.requireNonNull(p, "No apply param present");
|
||||
|
||||
return function.apply(p);
|
||||
} catch (final Throwable e) {
|
||||
Optional.ofNullable(throwConsumer).ifPresent(tc -> tc.accept(e));
|
||||
return null;
|
||||
} finally {
|
||||
// doFinally();
|
||||
doFinally(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
66
jetbrains.svg
Normal file
66
jetbrains.svg
Normal file
@@ -0,0 +1,66 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="120.1px" height="130.2px" viewBox="0 0 120.1 130.2" style="enable-background:new 0 0 120.1 130.2;" xml:space="preserve"
|
||||
>
|
||||
<g>
|
||||
<linearGradient id="XMLID_2_" gradientUnits="userSpaceOnUse" x1="31.8412" y1="120.5578" x2="110.2402" y2="73.24">
|
||||
<stop offset="0" style="stop-color:#FCEE39"/>
|
||||
<stop offset="1" style="stop-color:#F37B3D"/>
|
||||
</linearGradient>
|
||||
<path id="XMLID_3041_" style="fill:url(#XMLID_2_);" d="M118.6,71.8c0.9-0.8,1.4-1.9,1.5-3.2c0.1-2.6-1.8-4.7-4.4-4.9
|
||||
c-1.2-0.1-2.4,0.4-3.3,1.1l0,0l-83.8,45.9c-1.9,0.8-3.6,2.2-4.7,4.1c-2.9,4.8-1.3,11,3.6,13.9c3.4,2,7.5,1.8,10.7-0.2l0,0l0,0
|
||||
c0.2-0.2,0.5-0.3,0.7-0.5l78-54.8C117.3,72.9,118.4,72.1,118.6,71.8L118.6,71.8L118.6,71.8z"/>
|
||||
<linearGradient id="XMLID_3_" gradientUnits="userSpaceOnUse" x1="48.3607" y1="6.9083" x2="119.9179" y2="69.5546">
|
||||
<stop offset="0" style="stop-color:#EF5A6B"/>
|
||||
<stop offset="0.57" style="stop-color:#F26F4E"/>
|
||||
<stop offset="1" style="stop-color:#F37B3D"/>
|
||||
</linearGradient>
|
||||
<path id="XMLID_3049_" style="fill:url(#XMLID_3_);" d="M118.8,65.1L118.8,65.1L55,2.5C53.6,1,51.6,0,49.3,0
|
||||
c-4.3,0-7.7,3.5-7.7,7.7v0c0,2.1,0.8,3.9,2.1,5.3l0,0l0,0c0.4,0.4,0.8,0.7,1.2,1l67.4,57.7l0,0c0.8,0.7,1.8,1.2,3,1.3
|
||||
c2.6,0.1,4.7-1.8,4.9-4.4C120.2,67.3,119.7,66,118.8,65.1z"/>
|
||||
<linearGradient id="XMLID_4_" gradientUnits="userSpaceOnUse" x1="52.9467" y1="63.6407" x2="10.5379" y2="37.1562">
|
||||
<stop offset="0" style="stop-color:#7C59A4"/>
|
||||
<stop offset="0.3852" style="stop-color:#AF4C92"/>
|
||||
<stop offset="0.7654" style="stop-color:#DC4183"/>
|
||||
<stop offset="0.957" style="stop-color:#ED3D7D"/>
|
||||
</linearGradient>
|
||||
<path id="XMLID_3042_" style="fill:url(#XMLID_4_);" d="M57.1,59.5C57,59.5,17.7,28.5,16.9,28l0,0l0,0c-0.6-0.3-1.2-0.6-1.8-0.9
|
||||
c-5.8-2.2-12.2,0.8-14.4,6.6c-1.9,5.1,0.2,10.7,4.6,13.4l0,0l0,0C6,47.5,6.6,47.8,7.3,48c0.4,0.2,45.4,18.8,45.4,18.8l0,0
|
||||
c1.8,0.8,3.9,0.3,5.1-1.2C59.3,63.7,59,61,57.1,59.5z"/>
|
||||
<linearGradient id="XMLID_5_" gradientUnits="userSpaceOnUse" x1="52.1736" y1="3.7019" x2="10.7706" y2="37.8971">
|
||||
<stop offset="0" style="stop-color:#EF5A6B"/>
|
||||
<stop offset="0.364" style="stop-color:#EE4E72"/>
|
||||
<stop offset="1" style="stop-color:#ED3D7D"/>
|
||||
</linearGradient>
|
||||
<path id="XMLID_3057_" style="fill:url(#XMLID_5_);" d="M49.3,0c-1.7,0-3.3,0.6-4.6,1.5L4.9,28.3c-0.1,0.1-0.2,0.1-0.2,0.2l-0.1,0
|
||||
l0,0c-1.7,1.2-3.1,3-3.9,5.1C-1.5,39.4,1.5,45.9,7.3,48c3.6,1.4,7.5,0.7,10.4-1.4l0,0l0,0c0.7-0.5,1.3-1,1.8-1.6l34.6-31.2l0,0
|
||||
c1.8-1.4,3-3.6,3-6.1v0C57.1,3.5,53.6,0,49.3,0z"/>
|
||||
<g id="XMLID_3008_">
|
||||
<rect id="XMLID_3033_" x="34.6" y="37.4" style="fill:#000000;" width="51" height="51"/>
|
||||
<rect id="XMLID_3032_" x="39" y="78.8" style="fill:#FFFFFF;" width="19.1" height="3.2"/>
|
||||
<g id="XMLID_3009_">
|
||||
<path id="XMLID_3030_" style="fill:#FFFFFF;" d="M38.8,50.8l1.5-1.4c0.4,0.5,0.8,0.8,1.3,0.8c0.6,0,0.9-0.4,0.9-1.2l0-5.3l2.3,0
|
||||
l0,5.3c0,1-0.3,1.8-0.8,2.3c-0.5,0.5-1.3,0.8-2.3,0.8C40.2,52.2,39.4,51.6,38.8,50.8z"/>
|
||||
<path id="XMLID_3028_" style="fill:#FFFFFF;" d="M45.3,43.8l6.7,0v1.9l-4.4,0V47l4,0l0,1.8l-4,0l0,1.3l4.5,0l0,2l-6.7,0
|
||||
L45.3,43.8z"/>
|
||||
<path id="XMLID_3026_" style="fill:#FFFFFF;" d="M55,45.8l-2.5,0l0-2l7.3,0l0,2l-2.5,0l0,6.3l-2.3,0L55,45.8z"/>
|
||||
<path id="XMLID_3022_" style="fill:#FFFFFF;" d="M39,54l4.3,0c1,0,1.8,0.3,2.3,0.7c0.3,0.3,0.5,0.8,0.5,1.4v0
|
||||
c0,1-0.5,1.5-1.3,1.9c1,0.3,1.6,0.9,1.6,2v0c0,1.4-1.2,2.3-3.1,2.3l-4.3,0L39,54z M43.8,56.6c0-0.5-0.4-0.7-1-0.7l-1.5,0l0,1.5
|
||||
l1.4,0C43.4,57.3,43.8,57.1,43.8,56.6L43.8,56.6z M43,59l-1.8,0l0,1.5H43c0.7,0,1.1-0.3,1.1-0.8v0C44.1,59.2,43.7,59,43,59z"/>
|
||||
<path id="XMLID_3019_" style="fill:#FFFFFF;" d="M46.8,54l3.9,0c1.3,0,2.1,0.3,2.7,0.9c0.5,0.5,0.7,1.1,0.7,1.9v0
|
||||
c0,1.3-0.7,2.1-1.7,2.6l2,2.9l-2.6,0l-1.7-2.5h-1l0,2.5l-2.3,0L46.8,54z M50.6,58c0.8,0,1.2-0.4,1.2-1v0c0-0.7-0.5-1-1.2-1
|
||||
l-1.5,0v2H50.6z"/>
|
||||
<path id="XMLID_3016_" style="fill:#FFFFFF;" d="M56.8,54l2.2,0l3.5,8.4l-2.5,0l-0.6-1.5l-3.2,0l-0.6,1.5l-2.4,0L56.8,54z
|
||||
M58.8,59l-0.9-2.3L57,59L58.8,59z"/>
|
||||
<path id="XMLID_3014_" style="fill:#FFFFFF;" d="M62.8,54l2.3,0l0,8.3l-2.3,0L62.8,54z"/>
|
||||
<path id="XMLID_3012_" style="fill:#FFFFFF;" d="M65.7,54l2.1,0l3.4,4.4l0-4.4l2.3,0l0,8.3l-2,0L68,57.8l0,4.6l-2.3,0L65.7,54z"
|
||||
/>
|
||||
<path id="XMLID_3010_" style="fill:#FFFFFF;" d="M73.7,61.1l1.3-1.5c0.8,0.7,1.7,1,2.7,1c0.6,0,1-0.2,1-0.6v0
|
||||
c0-0.4-0.3-0.5-1.4-0.8c-1.8-0.4-3.1-0.9-3.1-2.6v0c0-1.5,1.2-2.7,3.2-2.7c1.4,0,2.5,0.4,3.4,1.1l-1.2,1.6
|
||||
c-0.8-0.5-1.6-0.8-2.3-0.8c-0.6,0-0.8,0.2-0.8,0.5v0c0,0.4,0.3,0.5,1.4,0.8c1.9,0.4,3.1,1,3.1,2.6v0c0,1.7-1.3,2.7-3.4,2.7
|
||||
C76.1,62.5,74.7,62,73.7,61.1z"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.8 KiB |
391
pom.xml
391
pom.xml
@@ -1,13 +1,18 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<packaging>pom</packaging>
|
||||
<modules>
|
||||
<module>budd-common</module>
|
||||
<module>budd-demo</module>
|
||||
<module>budd-server</module>
|
||||
<module>budd-utils</module>
|
||||
</modules>
|
||||
|
||||
<groupId>io.github.ehlxr</groupId>
|
||||
<artifactId>budd</artifactId>
|
||||
<packaging>war</packaging>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
|
||||
<name>budd</name>
|
||||
<url>http://maven.apache.org</url>
|
||||
<name>budd-parent</name>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
@@ -16,347 +21,53 @@
|
||||
<maven.compiler.source>11</maven.compiler.source>
|
||||
<maven.compiler.target>11</maven.compiler.target>
|
||||
|
||||
<spring.version>5.2.6.RELEASE</spring.version>
|
||||
<servlet.version>2.5</servlet.version>
|
||||
<mybatis.version>3.2.7</mybatis.version>
|
||||
<mybatis.spring.version>1.1.1</mybatis.spring.version>
|
||||
<mybatis.generator.core.version>1.4.0</mybatis.generator.core.version>
|
||||
<file_encoding>utf-8</file_encoding>
|
||||
<jdk.verion>1.8</jdk.verion>
|
||||
<powermock.version>1.7.1</powermock.version>
|
||||
<kotlin.version>1.3.61</kotlin.version>
|
||||
<spring-boot.version>2.2.6.RELEASE</spring-boot.version>
|
||||
<guava.version>30.0-jre</guava.version>
|
||||
<spring4all.swagger.version>2.0.0.RELEASE</spring4all.swagger.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.jcraft</groupId>
|
||||
<artifactId>jsch</artifactId>
|
||||
<version>0.1.53</version>
|
||||
</dependency>
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-dependencies</artifactId>
|
||||
<version>${spring-boot.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcprov-jdk16</artifactId>
|
||||
<version>1.46</version>
|
||||
</dependency>
|
||||
<!-- Google Guava -->
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>${guava.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.13.1</version>
|
||||
<!-- <scope>test</scope> -->
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.spring4all</groupId>
|
||||
<artifactId>swagger-spring-boot-starter</artifactId>
|
||||
<version>${spring4all.swagger.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-logging</groupId>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
<version>1.1.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.github.ehlxr</groupId>
|
||||
<artifactId>budd-common</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.shiro</groupId>
|
||||
<artifactId>shiro-core</artifactId>
|
||||
<version>1.4.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.github.ehlxr</groupId>
|
||||
<artifactId>budd-demo</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- spring begin-->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-core</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
<version>2.0.25</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-beans</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-web</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-oxm</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-tx</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-jdbc</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-webmvc</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-aop</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context-support</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-jms</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-expression</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</dependency>
|
||||
<!-- spring end-->
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-codec</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
<version>1.6</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>net.sf.json-lib</groupId>
|
||||
<artifactId>json-lib</artifactId>
|
||||
<version>2.4</version>
|
||||
<classifier>jdk15</classifier>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.caucho</groupId>
|
||||
<artifactId>hessian</artifactId>
|
||||
<version>4.0.38</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>redis.clients</groupId>
|
||||
<artifactId>jedis</artifactId>
|
||||
<version>2.8.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>8.0.16</version>
|
||||
</dependency>
|
||||
|
||||
<!-- servlet -->
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
<version>${servlet.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- mybatis start -->
|
||||
<dependency>
|
||||
<groupId>org.mybatis</groupId>
|
||||
<artifactId>mybatis</artifactId>
|
||||
<version>${mybatis.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mybatis</groupId>
|
||||
<artifactId>mybatis-spring</artifactId>
|
||||
<version>${mybatis.spring.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mybatis.generator</groupId>
|
||||
<artifactId>mybatis-generator-core</artifactId>
|
||||
<version>${mybatis.generator.core.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>c3p0</groupId>
|
||||
<artifactId>c3p0</artifactId>
|
||||
<version>0.9.1.2</version>
|
||||
</dependency>
|
||||
|
||||
<!-- mybatis end -->
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>4.5.2</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.cxf</groupId>
|
||||
<artifactId>cxf-rt-frontend-jaxws</artifactId>
|
||||
<version>3.1.6</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.cxf</groupId>
|
||||
<artifactId>cxf-rt-transports-http</artifactId>
|
||||
<version>3.1.6</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.activemq</groupId>
|
||||
<artifactId>activemq-all</artifactId>
|
||||
<version>5.13.3</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.xbean</groupId>
|
||||
<artifactId>xbean-spring</artifactId>
|
||||
<version>4.5</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>2.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.powermock</groupId>
|
||||
<artifactId>powermock-module-junit4</artifactId>
|
||||
<version>${powermock.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.powermock</groupId>
|
||||
<artifactId>powermock-api-mockito2</artifactId>
|
||||
<version>${powermock.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.reactivex</groupId>
|
||||
<artifactId>rxjava</artifactId>
|
||||
<version>1.3.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.reactivex.rxjava2</groupId>
|
||||
<artifactId>rxjava</artifactId>
|
||||
<version>2.1.8</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>28.2-jre</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jodd</groupId>
|
||||
<artifactId>jodd-props</artifactId>
|
||||
<version>3.6.1</version>
|
||||
</dependency>
|
||||
<!--<dependency>-->
|
||||
<!-- <groupId>cn.ceres.did</groupId>-->
|
||||
<!-- <artifactId>did-sdk</artifactId>-->
|
||||
<!-- <version>1.0-SNAPSHOT</version>-->
|
||||
<!--</dependency>-->
|
||||
<!--<dependency>-->
|
||||
<!-- <groupId>cn.enncloud.ceres</groupId>-->
|
||||
<!-- <artifactId>ceres</artifactId>-->
|
||||
<!-- <version>1.1.0-SNAPSHOT</version>-->
|
||||
<!--</dependency>-->
|
||||
|
||||
<dependency>
|
||||
<groupId>com.rabbitmq</groupId>
|
||||
<artifactId>amqp-client</artifactId>
|
||||
<version>4.8.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.hbase</groupId>
|
||||
<artifactId>hbase-client</artifactId>
|
||||
<version>1.3.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-annotations</artifactId>
|
||||
<version>2.10.3</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>2.10.3</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>okhttp</artifactId>
|
||||
<version>3.14.7</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.vavr</groupId>
|
||||
<artifactId>vavr</artifactId>
|
||||
<version>0.10.3</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>pl.touk</groupId>
|
||||
<artifactId>throwing-function</artifactId>
|
||||
<version>1.3</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<artifactId>did-sdk</artifactId>
|
||||
<groupId>io.github.ehlxr</groupId>
|
||||
<version>1.0.2-SNAPSHOT</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>github</id>
|
||||
<url>https://git.ehlxr.me/ehlxr/maven-repository/raw/branch/main</url>
|
||||
<!--<url>https://raw.githubusercontent.com/ehlxr/maven-repository/main</url>-->
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<!--<repositories>-->
|
||||
<!-- <repository>-->
|
||||
<!-- <!–-->
|
||||
<!-- 需要在 setting.xml 中配置认证信息-->
|
||||
<!-- <servers>-->
|
||||
<!-- <server>-->
|
||||
<!-- <id>github</id>-->
|
||||
<!-- <username>ehlxr</username>-->
|
||||
<!-- <password>${env.GITHUB_MVN_TOKEN}</password>-->
|
||||
<!-- </server>-->
|
||||
<!-- </servers>-->
|
||||
<!-- –>-->
|
||||
<!-- <id>github</id>-->
|
||||
<!-- <url>https://maven.pkg.github.com/ehlxr/mvn-repository</url>-->
|
||||
<!-- <releases>-->
|
||||
<!-- <enabled>true</enabled>-->
|
||||
<!-- </releases>-->
|
||||
<!-- <snapshots>-->
|
||||
<!-- <enabled>true</enabled>-->
|
||||
<!-- </snapshots>-->
|
||||
<!-- </repository>-->
|
||||
<!--</repositories>-->
|
||||
</project>
|
||||
|
||||
@@ -1,104 +0,0 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2020 xrv <xrg@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr;
|
||||
|
||||
/**
|
||||
* Created by ehlxr on 2017/8/3.
|
||||
*/
|
||||
public class CharToHex {
|
||||
private final static char[] hexArray = "0123456789ABCDEF".toCharArray();
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
String hex = bytesToHex("彤".getBytes());
|
||||
System.out.println(hex);
|
||||
|
||||
System.out.println(toUnicode("彤"));
|
||||
|
||||
// 十六进制 -> 十进制
|
||||
int i = Integer.parseInt(hex, 16);
|
||||
System.out.println(i);
|
||||
|
||||
// 十进制 -> 二进制
|
||||
String bin = Integer.toBinaryString(i);
|
||||
System.out.println(bin);
|
||||
|
||||
// 十进制 -> 十六进制
|
||||
String hex1 = Integer.toHexString(i);
|
||||
System.out.println(hex1);
|
||||
|
||||
// 十进制 -> 八进制
|
||||
String oct = Integer.toOctalString(i);
|
||||
System.out.println(oct);
|
||||
|
||||
System.out.println("---------------");
|
||||
System.out.println(Integer.toBinaryString(-22));
|
||||
//测试 int 转 byte
|
||||
int int0 = 234;
|
||||
byte byte0 = intToByte(int0);
|
||||
System.out.println("byte0= " + byte0);//byte0=-22
|
||||
//测试 byte 转 int
|
||||
int int1 = byteToInt(byte0);
|
||||
System.out.println("int1= " + int1);//int1=234
|
||||
}
|
||||
|
||||
|
||||
//byte 与 int 的相互转换
|
||||
public static byte intToByte(int x) {
|
||||
return (byte) x;
|
||||
}
|
||||
|
||||
public static int byteToInt(byte b) {
|
||||
//Java 总是把 byte 当做有符处理;我们可以通过将其和 0xFF 进行二进制与得到它的无符值
|
||||
return b & 0xFF;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 字符对应编码的哈希值
|
||||
*
|
||||
* @param bytes
|
||||
* @return
|
||||
*/
|
||||
public static String bytesToHex(byte[] bytes) {
|
||||
char[] hexChars = new char[bytes.length * 2];
|
||||
for (int j = 0; j < bytes.length; j++) {
|
||||
int v = bytes[j] & 0xFF;
|
||||
hexChars[j * 2] = hexArray[v >>> 4];
|
||||
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
|
||||
}
|
||||
return new String(hexChars);
|
||||
}
|
||||
|
||||
public static String toUnicode(String s) {
|
||||
String[] as = new String[s.length()];
|
||||
StringBuilder s1 = new StringBuilder();
|
||||
for (int i = 0; i < s.length(); i++) {
|
||||
as[i] = Integer.toHexString(s.charAt(i) & 0xffff);
|
||||
s1.append("\\u").append(as[i]);
|
||||
}
|
||||
return s1.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,114 +0,0 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2020 xrv <xrg@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* Created by ehlxr on 2017/11/17.
|
||||
* <p>
|
||||
* 递归扫描 Java 文件,添加 CopyRight 信息,已有跳过
|
||||
*/
|
||||
public class ContentReplace {
|
||||
private static int total = 0;
|
||||
private static int unDeal = 0;
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
File dir = new File("/Users/ehlxr/WorkSpaces/Budd");
|
||||
deal(dir);
|
||||
System.out.println("总文件数:" + total);
|
||||
System.out.println("未处理文件数:" + unDeal);
|
||||
}
|
||||
|
||||
private static void deal(File file) throws IOException {
|
||||
if (file.isDirectory()) {
|
||||
File[] fs = file.listFiles(((dir, name) -> {
|
||||
File f = new File(dir.getPath() + File.separator + name);
|
||||
|
||||
return (f.getPath().contains("src") && name.endsWith(".java")) || f.isDirectory();
|
||||
}));
|
||||
|
||||
for (File f : fs != null ? fs : new File[0]) {
|
||||
deal(f);
|
||||
}
|
||||
} else {
|
||||
++total;
|
||||
// System.out.println(file.getPath());
|
||||
|
||||
File tmp = File.createTempFile("tmp", null);
|
||||
try (
|
||||
FileOutputStream tmpOut = new FileOutputStream(tmp);
|
||||
FileInputStream tmpIn = new FileInputStream(tmp);
|
||||
RandomAccessFile raf = new RandomAccessFile(file, "rw")) {
|
||||
byte[] buf = new byte[64];
|
||||
int hasRead;
|
||||
while ((hasRead = raf.read(buf)) > 0) {
|
||||
if (new String(buf).contains("Copyright")) {
|
||||
++unDeal;
|
||||
System.out.println("未处理文件:" + file.getPath());
|
||||
return;
|
||||
}
|
||||
// 把原有内容读入临时文件
|
||||
tmpOut.write(buf, 0, hasRead);
|
||||
}
|
||||
raf.seek(0L);
|
||||
String tmpl = "/*\n" +
|
||||
" * The MIT License (MIT)\n" +
|
||||
" *\n" +
|
||||
" * Copyright © 2020 xrv <xrg@live.com>\n" +
|
||||
" *\n" +
|
||||
" * Permission is hereby granted, free of charge, to any person obtaining a copy\n" +
|
||||
" * of this software and associated documentation files (the \"Software\"), to deal\n" +
|
||||
" * in the Software without restriction, including without limitation the rights\n" +
|
||||
" * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n" +
|
||||
" * copies of the Software, and to permit persons to whom the Software is\n" +
|
||||
" * furnished to do so, subject to the following conditions:\n" +
|
||||
" *\n" +
|
||||
" * The above copyright notice and this permission notice shall be included in\n" +
|
||||
" * all copies or substantial portions of the Software.\n" +
|
||||
" *\n" +
|
||||
" * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n" +
|
||||
" * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n" +
|
||||
" * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n" +
|
||||
" * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n" +
|
||||
" * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n" +
|
||||
" * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n" +
|
||||
" * THE SOFTWARE.\n" +
|
||||
" */\n\n";
|
||||
raf.write(tmpl.getBytes());
|
||||
// raf.write("/*\n".getBytes());
|
||||
// raf.write(Files.readAllBytes(Paths.get(System.getProperty("user.dir") + File.separator + "LICENSE")));
|
||||
// raf.write("\n*/\n\n".getBytes());
|
||||
|
||||
// 追加临时文件内容
|
||||
while ((hasRead = tmpIn.read(buf)) > 0) {
|
||||
raf.write(buf, 0, hasRead);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2020 xrv <xrg@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
@SuppressWarnings("ALL")
|
||||
public class ContentReplace2 {
|
||||
public static void main(String[] args) {
|
||||
File file = new File("/Users/ehlxr/ehlxr/blog/hugoBlog/content/post");
|
||||
File[] files = file.listFiles();
|
||||
|
||||
for (File f : files) {
|
||||
operationFile(f);
|
||||
}
|
||||
}
|
||||
|
||||
private static void operationFile(File file) {
|
||||
File tmpfile = new File(file.getParentFile().getAbsolutePath() + "\\" + file.getName() + ".tmp");
|
||||
try (
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
|
||||
BufferedWriter writer = new BufferedWriter(new FileWriter(tmpfile))) {
|
||||
|
||||
boolean flag = false;
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
|
||||
if (line.startsWith("title")) {
|
||||
System.out.println(line);
|
||||
// StringBuilder sb = new StringBuilder();
|
||||
// line = sb.append("title: \"").append(line.substring(line.indexOf("title") + 7)).append("\"").toString();
|
||||
line = line.replaceAll("'", "");
|
||||
System.out.println(line);
|
||||
|
||||
flag = true;
|
||||
}
|
||||
writer.write(line + "\n");
|
||||
}
|
||||
|
||||
if (flag) {
|
||||
file.delete();
|
||||
tmpfile.renameTo(new File(file.getAbsolutePath()));
|
||||
} else {
|
||||
tmpfile.delete();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,122 +0,0 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2020 xrv <xrg@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
|
||||
import java.security.*;
|
||||
import java.security.interfaces.ECPrivateKey;
|
||||
import java.security.interfaces.ECPublicKey;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
|
||||
/**
|
||||
* Created by ehlxr on 2017/8/1.
|
||||
*/
|
||||
public class DemoECDSA {
|
||||
|
||||
//摘要
|
||||
private static final String strMsg = "hold on";
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
jdkECDSA();
|
||||
}
|
||||
|
||||
/**
|
||||
* ECDSA 微软的椭圆曲线算法 jdk1.7以后引入的算法
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public static void jdkECDSA() throws Exception {
|
||||
//1.初始化密钥
|
||||
KeyPair keyPair = initKey();
|
||||
|
||||
//2.执行签名(用私钥签名)
|
||||
ECPrivateKey ecPrivateKey = (ECPrivateKey) keyPair.getPrivate();
|
||||
byte[] sign = privateKeySign(strMsg, ecPrivateKey);
|
||||
String signStr = Base64.encodeBase64String(sign);
|
||||
System.out.println("sign String :" + signStr);//数字签名格式转换,以便报文传输用
|
||||
|
||||
ECPublicKey ecPublicKey = (ECPublicKey) keyPair.getPublic();
|
||||
String publicKeyStr = Base64.encodeBase64String(ecPublicKey.getEncoded());
|
||||
System.out.println("publicKeyStr String :" + publicKeyStr);//提供给对端,以便于对端使用公钥验证签名
|
||||
|
||||
|
||||
//3.验证签名(公钥验证签名)
|
||||
boolean result = publicKeyVerify(Base64.decodeBase64(signStr), Base64.decodeBase64(publicKeyStr));
|
||||
System.out.println("JDK DSA verify:" + result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 1.初始化密钥,采用ECDSA
|
||||
*
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static KeyPair initKey() throws Exception {
|
||||
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC");
|
||||
keyPairGenerator.initialize(256); //key长度设置
|
||||
KeyPair keyPair = keyPairGenerator.generateKeyPair();
|
||||
|
||||
return keyPair;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 2.执行签名(用私钥签名)
|
||||
*
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static byte[] privateKeySign(String data, ECPrivateKey ecPrivateKey) throws Exception {
|
||||
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(ecPrivateKey.getEncoded());
|
||||
KeyFactory keyFactory = KeyFactory.getInstance("EC");
|
||||
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
|
||||
Signature signature = Signature.getInstance("SHA1withECDSA");
|
||||
signature.initSign(privateKey);
|
||||
signature.update(strMsg.getBytes());
|
||||
byte[] sign = signature.sign();
|
||||
|
||||
return sign;
|
||||
}
|
||||
|
||||
/**
|
||||
* 3.公钥验证签名(摘要+签名串+公钥)
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public static boolean publicKeyVerify(byte[] sign, byte[] dsaPublicKey) throws Exception {
|
||||
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(dsaPublicKey);
|
||||
KeyFactory keyFactory = KeyFactory.getInstance("EC");
|
||||
PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
|
||||
Signature signature = Signature.getInstance("SHA1withECDSA");
|
||||
signature.initVerify(publicKey);
|
||||
signature.update(strMsg.getBytes());
|
||||
boolean result = signature.verify(sign);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,92 +0,0 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2020 xrv <xrg@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.management.*;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Code which writes a stack dump for all threads to a file.
|
||||
*/
|
||||
public class DumpStack {
|
||||
|
||||
// directory where the stack files are written
|
||||
private static final String STACK_DUMP_DIR = "/var/tmp";
|
||||
|
||||
// here for testing
|
||||
public static void main(String[] args) throws Exception {
|
||||
dumpStacks();
|
||||
}
|
||||
|
||||
private static void dumpStacks() throws IOException {
|
||||
ThreadMXBean mxBean = ManagementFactory.getThreadMXBean();
|
||||
MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
|
||||
RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();
|
||||
|
||||
|
||||
ThreadInfo[] threadInfos = mxBean.getThreadInfo(mxBean.getAllThreadIds(), 0);
|
||||
Map<Long, ThreadInfo> threadInfoMap = new HashMap<>();
|
||||
for (ThreadInfo threadInfo : threadInfos) {
|
||||
threadInfoMap.put(threadInfo.getThreadId(), threadInfo);
|
||||
}
|
||||
|
||||
// choose our dump-file
|
||||
File dumpFile = new File(STACK_DUMP_DIR, "stacks." + System.currentTimeMillis());
|
||||
try (Writer writer = new BufferedWriter(new FileWriter(dumpFile))) {
|
||||
dumpTraces(mxBean, threadInfoMap, writer);
|
||||
}
|
||||
}
|
||||
|
||||
private static void dumpTraces(ThreadMXBean mxBean, Map<Long, ThreadInfo> threadInfoMap, Writer writer)
|
||||
throws IOException {
|
||||
Map<Thread, StackTraceElement[]> stacks = Thread.getAllStackTraces();
|
||||
writer.write("Dump of " + stacks.size() + " thread at "
|
||||
+ new SimpleDateFormat("yyyy/MM/dd HH:mm:ss z").format(new Date(System.currentTimeMillis())) + "\n\n");
|
||||
for (Map.Entry<Thread, StackTraceElement[]> entry : stacks.entrySet()) {
|
||||
Thread thread = entry.getKey();
|
||||
writer.write("\"" + thread.getName() + "\" prio=" + thread.getPriority() + " tid=" + thread.getId() + " "
|
||||
+ thread.getState() + " " + (thread.isDaemon() ? "deamon" : "worker") + "\n");
|
||||
ThreadInfo threadInfo = threadInfoMap.get(thread.getId());
|
||||
if (threadInfo != null) {
|
||||
writer.write(" native=" + threadInfo.isInNative() + ", suspended=" + threadInfo.isSuspended()
|
||||
+ ", block=" + threadInfo.getBlockedCount() + ", wait=" + threadInfo.getWaitedCount() + "\n");
|
||||
writer.write(" lock=" + threadInfo.getLockName() + " owned by " + threadInfo.getLockOwnerName()
|
||||
+ " (" + threadInfo.getLockOwnerId() + "), cpu="
|
||||
+ (mxBean.getThreadCpuTime(threadInfo.getThreadId()) / 1000000L) + ", user="
|
||||
+ (mxBean.getThreadUserTime(threadInfo.getThreadId()) / 1000000L) + "\n");
|
||||
}
|
||||
for (StackTraceElement element : entry.getValue()) {
|
||||
writer.write(" ");
|
||||
writer.write(element.toString());
|
||||
writer.write("\n");
|
||||
}
|
||||
writer.write("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2020 xrv <xrg@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
|
||||
/**
|
||||
* @author ehlxr
|
||||
*/
|
||||
public class FindRequestMapping {
|
||||
private static final int total = 0;
|
||||
private static final int unDeal = 0;
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
File dir = new File("/Users/ehlxr/WorkSpaces/enncloud/ceres-epns/ceres-epns-web/src/main/java/com/ceres/epns/web");
|
||||
deal(dir);
|
||||
}
|
||||
|
||||
private static void deal(File file) throws IOException {
|
||||
if (file.isDirectory()) {
|
||||
File[] fs = file.listFiles(((dir, name) -> {
|
||||
File f = new File(dir.getPath() + File.separator + name);
|
||||
|
||||
return (f.getPath().contains("src") && name.endsWith(".java")) || f.isDirectory();
|
||||
}));
|
||||
|
||||
for (File f : fs != null ? fs : new File[0]) {
|
||||
deal(f);
|
||||
}
|
||||
|
||||
} else {
|
||||
InputStreamReader read = new InputStreamReader(new FileInputStream(file));
|
||||
BufferedReader bufferedReader = new BufferedReader(read);
|
||||
String lineTxt;
|
||||
|
||||
while ((lineTxt = bufferedReader.readLine()) != null) {
|
||||
if (lineTxt.contains("@RequestMapping")) {
|
||||
System.out.println(lineTxt);
|
||||
}
|
||||
}
|
||||
bufferedReader.close();
|
||||
read.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2020 xrv <xrg@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr;
|
||||
|
||||
import net.sf.json.JSONObject;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Created by ehlxr on 2016/11/8.
|
||||
*/
|
||||
public class MD2Json {
|
||||
public static void main(String[] args) throws IOException {
|
||||
resume();
|
||||
}
|
||||
|
||||
private static void resume() throws IOException {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("show", 1);
|
||||
String content = FileUtils.readFileToString(new File("E:\\ehlxr\\Git\\md-files\\resume.md"), "UTF-8");
|
||||
jsonObject.put("content", content);
|
||||
System.out.println(jsonObject.toString());
|
||||
}
|
||||
}
|
||||
@@ -1,127 +0,0 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2020 xrv <xrg@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
/*
|
||||
* 替换文件(如果该文件含有子目录,则包括子目录所有文件)中某个字符串并写入新内容(Java代码实现).
|
||||
*
|
||||
*原理:逐行读取源文件的内容,一边读取一边同时写一个*.tmp的文件。
|
||||
*当读取的行中发现有需要被替换和改写的目标内容‘行’时候,用新的内容‘行’替换之。
|
||||
*最终,删掉源文件,把*.tmp的文件重命名为源文件名字。
|
||||
*
|
||||
*注意!代码功能是逐行读取一个字符串,然后检测该字符串‘行’中是否含有替换的内容,有则用新的字符串‘行’替换源文件中该处整个字符串‘行’。没有则继续读。
|
||||
*注意!替换是基于‘行’,逐行逐行的替换!
|
||||
*
|
||||
* */
|
||||
public class Modify {
|
||||
|
||||
private final String target;
|
||||
private final String newContent;
|
||||
private final String path;
|
||||
|
||||
public Modify(String path, String target, String newContent) {
|
||||
// 操作目录。从该目录开始。该文件目录下及其所有子目录的文件都将被替换。
|
||||
this.path = path;
|
||||
// target:需要被替换、改写的内容。
|
||||
this.target = target;
|
||||
// newContent:需要新写入的内容。
|
||||
this.newContent = newContent;
|
||||
|
||||
operation();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
//代码测试:假设有一个test文件夹,test文件夹下含有若干文件或者若干子目录,子目录下可能也含有若干文件或者若干子目录(意味着可以递归操作)。
|
||||
//把test目录下以及所有子目录下(如果有)中文件含有"hi"的字符串行替换成新的"hello,world!"字符串行。
|
||||
new Modify("/Users/ehlxr/WorkSpaces/budd/src/main/java/me/ehlxr/test.txt", "hi", "hello,world!");
|
||||
}
|
||||
|
||||
private void operation() {
|
||||
File file = new File(path);
|
||||
opeationDirectory(file);
|
||||
}
|
||||
|
||||
private void opeationDirectory(File file) {
|
||||
if (file.isFile()) {
|
||||
operationFile(file);
|
||||
}
|
||||
if (file.isDirectory()) {
|
||||
File[] files = file.listFiles();
|
||||
if (files != null) {
|
||||
for (File f : files) {
|
||||
opeationDirectory(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void operationFile(File file) {
|
||||
|
||||
try {
|
||||
InputStream is = new FileInputStream(file);
|
||||
BufferedReader reader = new BufferedReader(
|
||||
new InputStreamReader(is));
|
||||
|
||||
String filename = file.getName();
|
||||
// tmpfile为缓存文件,代码运行完毕后此文件将重命名为源文件名字。
|
||||
File tmpfile = new File(file.getParentFile().getAbsolutePath() + "\\" + filename + ".tmp");
|
||||
|
||||
BufferedWriter writer = new BufferedWriter(new FileWriter(tmpfile));
|
||||
|
||||
boolean flag = false;
|
||||
String str;
|
||||
while (true) {
|
||||
str = reader.readLine();
|
||||
|
||||
if (str == null)
|
||||
break;
|
||||
|
||||
if (str.contains(target)) {
|
||||
writer.write(newContent + "\n");
|
||||
|
||||
flag = true;
|
||||
} else
|
||||
writer.write(str + "\n");
|
||||
}
|
||||
|
||||
is.close();
|
||||
|
||||
writer.flush();
|
||||
writer.close();
|
||||
|
||||
if (flag) {
|
||||
file.delete();
|
||||
tmpfile.renameTo(new File(file.getAbsolutePath()));
|
||||
} else {
|
||||
tmpfile.delete();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,97 +0,0 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2020 xrv <xrg@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr;
|
||||
|
||||
/**
|
||||
* Created by ehlxr on 2018/2/13.
|
||||
*/
|
||||
public class PrintMatrixClockWisely {
|
||||
/**
|
||||
* 题目:输入一个矩阵,按照从外向里以顺时针的顺序打印出每一个数字。
|
||||
* 思路:
|
||||
* 循环打印:
|
||||
* 1:先打印一行(第 1 行肯定会打印)
|
||||
* 2:再打印当前矩阵的最后一列
|
||||
* 3:再倒序打印当前矩阵的最后一行
|
||||
* 4:再倒序打印当前矩阵的第一列
|
||||
* 起始坐标的规律:
|
||||
* (0,0),(1,1),(2,2)...(startX,startY), 起始坐标的两个坐标值相等。
|
||||
* 并且 startX<= (rows-1)/2,startY<=(columns-1)/2
|
||||
* 当前矩阵,第 1 行 坐标 (start,columns-1-start) => (start,endX)
|
||||
* 当前矩阵,最后 1 列 坐标 (start+1,rows-1-start) => (start+1,endY)
|
||||
* 当前矩阵,最后 1 行 坐标 (start,columns-1-start+1) => (start,endX-1)
|
||||
* 当前矩阵,第 1 行 坐标 (start+1,columns-1+1) => (start+1,endY-1)
|
||||
*
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
// TODO Auto-generated method stub
|
||||
// 初始化矩阵 arr[][]
|
||||
int[][] arr = new int[5][5];
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
for (int j = 0; j < arr[i].length; j++) {
|
||||
arr[i][j] = i * arr[i].length + j;
|
||||
System.out.print(arr[i][j] + " " + '\t');
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
System.out.println("顺时针打印矩阵:");
|
||||
// 顺时针打印矩阵 arr[][]
|
||||
printMatrixWisely(arr);
|
||||
}
|
||||
|
||||
// 循环打印
|
||||
private static void printMatrixWisely(int[][] arr) {
|
||||
if (arr == null || arr.length < 1 || arr[0].length < 1)
|
||||
return;
|
||||
int start = 0;
|
||||
int rows = arr.length;
|
||||
int columns = arr[0].length;
|
||||
while (2 * start < columns && 2 * start < rows) {
|
||||
printMatrix(arr, rows, columns, start);
|
||||
start++;
|
||||
}
|
||||
}
|
||||
|
||||
// 打印一圈
|
||||
private static void printMatrix(int[][] arr, int rows, int columns, int start) {
|
||||
int endX = columns - 1 - start; // 最后一列的列号
|
||||
int endY = rows - 1 - start; // 最后一行的行号
|
||||
// 打印该圈第一行
|
||||
for (int i = start; i <= endX; i++)
|
||||
System.out.print(arr[start][i] + " ");
|
||||
// 打印该圈最后一列 (至少是两行)
|
||||
if (start < endY)
|
||||
for (int i = start + 1; i <= endY; i++)
|
||||
System.out.print(arr[i][endX] + " ");
|
||||
// 打印该圈最后一行 (至少是两行两列)
|
||||
if ((start < endX) && (start < endY))
|
||||
for (int i = endX - 1; i >= start; i--)
|
||||
System.out.print(arr[endY][i] + " ");
|
||||
// 打印该圈的第一列 (至少是三行两列)
|
||||
if ((start < endX) && (start < endY - 1))
|
||||
for (int i = endY - 1; i >= start + 1; i--)
|
||||
System.out.print(arr[i][start] + " ");
|
||||
}
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2020 xrv <xrg@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* @author ehlxr
|
||||
* @date 2017/3/27
|
||||
*/
|
||||
public class Rename {
|
||||
public static void main(String[] args) {
|
||||
File dir = new File("/Users/ehlxr/ehlxr/blog/posts");
|
||||
|
||||
File[] files = dir.listFiles();
|
||||
if (null == files || files.length <= 0) {
|
||||
System.out.println("sources is null!");
|
||||
return;
|
||||
}
|
||||
int count = 0;
|
||||
for (File file : files) {
|
||||
try {
|
||||
String oName = file.getName();
|
||||
|
||||
String date = oName.substring(oName.lastIndexOf("-201") + 1, oName.indexOf(".md"));
|
||||
String title = oName.substring(0, oName.lastIndexOf("-201"));
|
||||
|
||||
String nName = date + "-" + title + ".md";
|
||||
|
||||
copyFileUsingFileStreams(file, new File("/Users/ehlxr/Desktop/post/" + nName));
|
||||
count++;
|
||||
} catch (Exception e) {
|
||||
System.out.println("exce file [ " + file.getName() + " ] error, reason: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
System.out.println("complete: " + count);
|
||||
}
|
||||
|
||||
private static void copyFileUsingFileStreams(File source, File dest)
|
||||
throws IOException {
|
||||
try (InputStream input = new FileInputStream(source); OutputStream output = new FileOutputStream(dest)) {
|
||||
byte[] buf = new byte[1024];
|
||||
int bytesRead;
|
||||
while ((bytesRead = input.read(buf)) > 0) {
|
||||
output.write(buf, 0, bytesRead);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2020 xrv <xrg@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.activemq;
|
||||
|
||||
import org.apache.activemq.ActiveMQConnection;
|
||||
import org.apache.activemq.ActiveMQConnectionFactory;
|
||||
|
||||
import javax.jms.*;
|
||||
|
||||
/**
|
||||
* 消息的消费者(接受者)
|
||||
* Created by ehlxr on 2016-07-11
|
||||
*/
|
||||
public class JMSConsumer {
|
||||
|
||||
private static final String USERNAME = ActiveMQConnection.DEFAULT_USER;//默认连接用户名
|
||||
private static final String PASSWORD = ActiveMQConnection.DEFAULT_PASSWORD;//默认连接密码
|
||||
private static final String BROKEURL = ActiveMQConnection.DEFAULT_BROKER_URL;//默认连接地址
|
||||
|
||||
public static void main(String[] args) {
|
||||
ConnectionFactory connectionFactory;//连接工厂
|
||||
Connection connection = null;//连接
|
||||
|
||||
Session session;//会话 接受或者发送消息的线程
|
||||
Destination destination;//消息的目的地
|
||||
|
||||
MessageConsumer messageConsumer;//消息的消费者
|
||||
|
||||
//实例化连接工厂
|
||||
connectionFactory = new ActiveMQConnectionFactory(JMSConsumer.USERNAME, JMSConsumer.PASSWORD, JMSConsumer.BROKEURL);
|
||||
|
||||
try {
|
||||
//通过连接工厂获取连接
|
||||
connection = connectionFactory.createConnection();
|
||||
//启动连接
|
||||
connection.start();
|
||||
//创建session
|
||||
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||
//创建一个连接HelloWorld的消息队列
|
||||
destination = session.createQueue("HelloWorld");
|
||||
//创建消息消费者
|
||||
messageConsumer = session.createConsumer(destination);
|
||||
|
||||
while (true) {
|
||||
TextMessage textMessage = (TextMessage) messageConsumer.receive(100000);
|
||||
if (textMessage != null) {
|
||||
System.out.println("收到的消息:" + textMessage.getText());
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (JMSException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,108 +0,0 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2020 xrv <xrg@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.activemq;
|
||||
|
||||
import org.apache.activemq.ActiveMQConnection;
|
||||
import org.apache.activemq.ActiveMQConnectionFactory;
|
||||
|
||||
import javax.jms.*;
|
||||
|
||||
/**
|
||||
* 消息的生产者(发送者)
|
||||
* Created by ehlxr on 2016-07-11.
|
||||
*/
|
||||
public class JMSProducer {
|
||||
|
||||
//默认连接用户名
|
||||
private static final String USERNAME = ActiveMQConnection.DEFAULT_USER;
|
||||
//默认连接密码
|
||||
private static final String PASSWORD = ActiveMQConnection.DEFAULT_PASSWORD;
|
||||
//默认连接地址
|
||||
private static final String BROKEURL = ActiveMQConnection.DEFAULT_BROKER_URL;
|
||||
//发送的消息数量
|
||||
private static final int SENDNUM = 10;
|
||||
|
||||
public static void main(String[] args) {
|
||||
//连接工厂
|
||||
ConnectionFactory connectionFactory;
|
||||
//连接
|
||||
Connection connection = null;
|
||||
//会话 接受或者发送消息的线程
|
||||
Session session;
|
||||
//消息的目的地
|
||||
Destination destination;
|
||||
//消息生产者
|
||||
MessageProducer messageProducer;
|
||||
//实例化连接工厂
|
||||
connectionFactory = new ActiveMQConnectionFactory(JMSProducer.USERNAME, JMSProducer.PASSWORD, JMSProducer.BROKEURL);
|
||||
|
||||
try {
|
||||
//通过连接工厂获取连接
|
||||
connection = connectionFactory.createConnection();
|
||||
//启动连接
|
||||
connection.start();
|
||||
//创建session
|
||||
session = connection.createSession(true, javax.jms.Session.AUTO_ACKNOWLEDGE);
|
||||
//创建一个名称为HelloWorld的消息队列
|
||||
destination = session.createQueue("HelloWorld");
|
||||
//创建消息生产者
|
||||
messageProducer = session.createProducer(destination);
|
||||
//发送消息
|
||||
sendMessage(session, messageProducer);
|
||||
|
||||
session.commit();
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (connection != null) {
|
||||
try {
|
||||
connection.close();
|
||||
} catch (JMSException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送消息
|
||||
*
|
||||
* @param session
|
||||
* @param messageProducer 消息生产者
|
||||
* @throws Exception
|
||||
*/
|
||||
public static void sendMessage(Session session, MessageProducer messageProducer) throws Exception {
|
||||
for (int i = 0; i < JMSProducer.SENDNUM; i++) {
|
||||
//创建一条文本消息
|
||||
TextMessage message = session.createTextMessage("ActiveMQ 发送消息" + i);
|
||||
System.out.println("发送消息:Activemq 发送消息" + i);
|
||||
//通过消息生产者发出消息
|
||||
messageProducer.send(message);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2020 xrv <xrg@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.annotation;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
|
||||
public class TestPkgAnnotation {
|
||||
|
||||
public static void main(String[] args) {
|
||||
Package pkg = Package.getPackage("osc.git.eh3.annotation");
|
||||
Annotation[] annotations = pkg.getAnnotations();
|
||||
for (Annotation annotation : annotations) {
|
||||
System.out.println(annotation);
|
||||
}
|
||||
|
||||
// ===========================友好类和包内访问常量==============
|
||||
new MyPackageMethod().myPackageMethod();
|
||||
System.out.println(MyPackageConst.PACKAGE_STRING);
|
||||
}
|
||||
}
|
||||
75
src/main/java/io/github/ehlxr/cache/Cache.java
vendored
75
src/main/java/io/github/ehlxr/cache/Cache.java
vendored
@@ -1,75 +0,0 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2020 xrv <xrg@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.cache;
|
||||
|
||||
public class Cache {
|
||||
private String key;// 缓存ID
|
||||
private Object value;// 缓存数据
|
||||
private long timeOut;// 更新时间
|
||||
private boolean expired; // 是否终止
|
||||
|
||||
public Cache() {
|
||||
super();
|
||||
}
|
||||
|
||||
public Cache(String key, Object value, long timeOut, boolean expired) {
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
this.timeOut = timeOut;
|
||||
this.expired = expired;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public long getTimeOut() {
|
||||
return timeOut;
|
||||
}
|
||||
|
||||
public Object getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setKey(String string) {
|
||||
key = string;
|
||||
}
|
||||
|
||||
public void setTimeOut(long l) {
|
||||
timeOut = l;
|
||||
}
|
||||
|
||||
public void setValue(Object object) {
|
||||
value = object;
|
||||
}
|
||||
|
||||
public boolean isExpired() {
|
||||
return expired;
|
||||
}
|
||||
|
||||
public void setExpired(boolean b) {
|
||||
expired = b;
|
||||
}
|
||||
}
|
||||
@@ -1,187 +0,0 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2020 xrv <xrg@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.cache;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
public class CacheManager {
|
||||
private static final HashMap<String, Object> cacheMap = new HashMap<String, Object>();
|
||||
|
||||
// 单实例构造方法
|
||||
private CacheManager() {
|
||||
super();
|
||||
}
|
||||
|
||||
// 得到缓存。同步静态方法
|
||||
private synchronized static Cache getCache(String key) {
|
||||
return (Cache) cacheMap.get(key);
|
||||
}
|
||||
|
||||
// 判断是否存在一个缓存
|
||||
private synchronized static boolean hasCache(String key) {
|
||||
return cacheMap.containsKey(key);
|
||||
}
|
||||
|
||||
// 清除所有缓存
|
||||
public synchronized static void clearAll() {
|
||||
cacheMap.clear();
|
||||
}
|
||||
|
||||
// 清除某一类特定缓存,通过遍历HASHMAP下的所有对象,来判断它的KEY与传入的TYPE是否匹配
|
||||
public synchronized static void clearAll(String type) {
|
||||
Iterator<Entry<String, Object>> i = cacheMap.entrySet().iterator();
|
||||
String key;
|
||||
ArrayList<String> arr = new ArrayList<String>();
|
||||
try {
|
||||
while (i.hasNext()) {
|
||||
Entry<String, Object> entry = i.next();
|
||||
key = entry.getKey();
|
||||
if (key.startsWith(type)) { // 如果匹配则删除掉
|
||||
arr.add(key);
|
||||
}
|
||||
}
|
||||
for (int k = 0; k < arr.size(); k++) {
|
||||
clearOnly(arr.get(k));
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// 清除指定的缓存
|
||||
public synchronized static void clearOnly(String key) {
|
||||
cacheMap.remove(key);
|
||||
}
|
||||
|
||||
// 载入缓存
|
||||
public synchronized static void putCache(String key, Cache obj) {
|
||||
cacheMap.put(key, obj);
|
||||
}
|
||||
|
||||
// 获取缓存信息
|
||||
public static Cache getCacheInfo(String key) {
|
||||
if (hasCache(key)) {
|
||||
Cache cache = getCache(key);
|
||||
if (cacheExpired(cache)) { // 调用判断是否终止方法
|
||||
cache.setExpired(true);
|
||||
}
|
||||
return cache;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// 载入缓存信息
|
||||
public static void putCacheInfo(String key, Cache obj, long dt, boolean expired) {
|
||||
Cache cache = new Cache();
|
||||
cache.setKey(key);
|
||||
cache.setTimeOut(dt + System.currentTimeMillis()); // 设置多久后更新缓存
|
||||
cache.setValue(obj);
|
||||
cache.setExpired(expired); // 缓存默认载入时,终止状态为FALSE
|
||||
cacheMap.put(key, cache);
|
||||
}
|
||||
|
||||
// 重写载入缓存信息方法
|
||||
public static void putCacheInfo(String key, Cache obj, long dt) {
|
||||
Cache cache = new Cache();
|
||||
cache.setKey(key);
|
||||
cache.setTimeOut(dt + System.currentTimeMillis());
|
||||
cache.setValue(obj);
|
||||
cache.setExpired(false);
|
||||
cacheMap.put(key, cache);
|
||||
}
|
||||
|
||||
// 判断缓存是否终止
|
||||
public static boolean cacheExpired(Cache cache) {
|
||||
if (null == cache) { // 传入的缓存不存在
|
||||
return false;
|
||||
}
|
||||
long nowDt = System.currentTimeMillis(); // 系统当前的毫秒数
|
||||
long cacheDt = cache.getTimeOut(); // 缓存内的过期毫秒数
|
||||
// 过期时间小于等于零时,或者过期时间大于当前时间时,则为FALSE
|
||||
// 大于过期时间 即过期
|
||||
return cacheDt > 0 && cacheDt <= nowDt;
|
||||
}
|
||||
|
||||
// 获取缓存中的大小
|
||||
public static int getCacheSize() {
|
||||
return cacheMap.size();
|
||||
}
|
||||
|
||||
// 获取指定的类型的大小
|
||||
public static int getCacheSize(String type) {
|
||||
int k = 0;
|
||||
Iterator<Entry<String, Object>> i = cacheMap.entrySet().iterator();
|
||||
String key;
|
||||
try {
|
||||
while (i.hasNext()) {
|
||||
Entry<String, Object> entry = i.next();
|
||||
key = entry.getKey();
|
||||
if (key.indexOf(type) != -1) { // 如果匹配则删除掉
|
||||
k++;
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
|
||||
return k;
|
||||
}
|
||||
|
||||
// 获取缓存对象中的所有键值名称
|
||||
public static ArrayList<String> getCacheAllkey() {
|
||||
ArrayList<String> a = new ArrayList<String>();
|
||||
try {
|
||||
Iterator<Entry<String, Object>> i = cacheMap.entrySet().iterator();
|
||||
while (i.hasNext()) {
|
||||
Entry<String, Object> entry = i.next();
|
||||
a.add(entry.getKey());
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
// 获取缓存对象中指定类型 的键值名称
|
||||
public static ArrayList<String> getCacheListkey(String type) {
|
||||
ArrayList<String> a = new ArrayList<String>();
|
||||
String key;
|
||||
try {
|
||||
Iterator<Entry<String, Object>> i = cacheMap.entrySet().iterator();
|
||||
while (i.hasNext()) {
|
||||
Entry<String, Object> entry = i.next();
|
||||
key = entry.getKey();
|
||||
if (key.indexOf(type) != -1) {
|
||||
a.add(key);
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
return a;
|
||||
}
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2020 xrv <xrg@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.cache;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
public final class SimpleCache<K, V> {
|
||||
|
||||
private final Lock lock = new ReentrantLock();
|
||||
private final int maxCapacity;
|
||||
private final Map<K, V> eden;
|
||||
private final Map<K, V> perm;
|
||||
|
||||
public SimpleCache(int maxCapacity) {
|
||||
this.maxCapacity = maxCapacity;
|
||||
this.eden = new ConcurrentHashMap<K, V>(maxCapacity);
|
||||
this.perm = new WeakHashMap<K, V>(maxCapacity);
|
||||
}
|
||||
|
||||
public V get(K k) {
|
||||
V v = this.eden.get(k);
|
||||
if (v == null) {
|
||||
lock.lock();
|
||||
try {
|
||||
v = this.perm.get(k);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
if (v != null) {
|
||||
this.eden.put(k, v);
|
||||
}
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
public void put(K k, V v) {
|
||||
if (this.eden.size() >= maxCapacity) {
|
||||
lock.lock();
|
||||
try {
|
||||
this.perm.putAll(this.eden);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
this.eden.clear();
|
||||
}
|
||||
this.eden.put(k, v);
|
||||
}
|
||||
}
|
||||
@@ -1,102 +0,0 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2020 xrv <xrg@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.cache;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class SimpleCacheUtil<T> {
|
||||
private final Map<String, T> m_objects;
|
||||
private final Map<String, Long> m_expiredObjects;
|
||||
private final long m_lExpireTime;
|
||||
private final ExecutorService m_executor;
|
||||
|
||||
public SimpleCacheUtil() {
|
||||
this(500);
|
||||
}
|
||||
|
||||
public SimpleCacheUtil(final int nExpireTime) {
|
||||
m_objects = Collections.synchronizedMap(new HashMap<String, T>());
|
||||
m_expiredObjects = Collections.synchronizedMap(new HashMap<String, Long>());
|
||||
m_lExpireTime = nExpireTime;
|
||||
m_executor = Executors.newFixedThreadPool(256);
|
||||
Executors.newScheduledThreadPool(5).scheduleWithFixedDelay(RemoveExpiredObjects(), m_lExpireTime / 2, m_lExpireTime,
|
||||
TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
private final Runnable RemoveExpiredObjects() {
|
||||
return new Runnable() {
|
||||
public void run() {
|
||||
for (final String name : m_expiredObjects.keySet()) {
|
||||
if (System.currentTimeMillis() > m_expiredObjects.get(name)) {
|
||||
m_executor.execute(CreateRemoveRunnable(name));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private final Runnable CreateRemoveRunnable(final String name) {
|
||||
return new Runnable() {
|
||||
public void run() {
|
||||
m_objects.remove(name);
|
||||
m_expiredObjects.remove(name);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public long getExpireTime() {
|
||||
return m_lExpireTime;
|
||||
}
|
||||
|
||||
public void put(final String name, final T obj) {
|
||||
put(name, obj, m_lExpireTime);
|
||||
}
|
||||
|
||||
public void put(final String name, final T obj, final long expireTime) {
|
||||
m_objects.put(name, obj);
|
||||
m_expiredObjects.put(name, System.currentTimeMillis() + expireTime * 1000);
|
||||
}
|
||||
|
||||
public T get(final String name) {
|
||||
final Long expireTime = m_expiredObjects.get(name);
|
||||
if (expireTime == null)
|
||||
return null;
|
||||
if (System.currentTimeMillis() > expireTime) {
|
||||
m_executor.execute(CreateRemoveRunnable(name));
|
||||
return null;
|
||||
}
|
||||
return m_objects.get(name);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <R extends T> R get(final String name, final Class<R> type) {
|
||||
return (R) get(name);
|
||||
}
|
||||
}
|
||||
35
src/main/java/io/github/ehlxr/cache/Test.java
vendored
35
src/main/java/io/github/ehlxr/cache/Test.java
vendored
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2020 xrv <xrg@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.cache;
|
||||
|
||||
public class Test {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SimpleCacheUtil<Object> cache2 = new SimpleCacheUtil<>(5);
|
||||
cache2.put("123", "fdfd");
|
||||
|
||||
System.out.println(cache2.get("123"));
|
||||
}
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2020 xrv <xrg@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.cache;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class TestCache {
|
||||
public static void main(String[] args) {
|
||||
CacheManager.putCache("abc", new Cache("key", "value", 10, false));
|
||||
CacheManager.putCache("def", new Cache());
|
||||
CacheManager.putCache("ccc", new Cache());
|
||||
CacheManager.clearOnly("");
|
||||
Cache c = new Cache();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
CacheManager.putCache("" + i, c);
|
||||
}
|
||||
CacheManager.putCache("aaaaaaaa", c);
|
||||
CacheManager.putCache("abchcy;alskd", c);
|
||||
CacheManager.putCache("cccccccc", c);
|
||||
CacheManager.putCache("abcoqiwhcy", c);
|
||||
System.out.println("删除前的大小:" + CacheManager.getCacheSize());
|
||||
ArrayList<String> cacheAllkey = CacheManager.getCacheAllkey();
|
||||
for (String key : cacheAllkey) {
|
||||
System.out.println(key + ":" + CacheManager.getCacheInfo(key).getValue());
|
||||
}
|
||||
CacheManager.clearAll("aaaa");
|
||||
System.out.println("删除后的大小:" + CacheManager.getCacheSize());
|
||||
cacheAllkey = CacheManager.getCacheAllkey();
|
||||
for (String key : cacheAllkey) {
|
||||
System.out.println(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,120 +0,0 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2020 xrv <xrg@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.cache;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.FutureTask;
|
||||
|
||||
/**
|
||||
* Created by ehlxr on 2017/4/11.
|
||||
*/
|
||||
public class TestFutureCahe<K, V> {
|
||||
private final ConcurrentHashMap<K, Future<V>> cacheMap = new ConcurrentHashMap<>();
|
||||
|
||||
public static void main(String[] args) {
|
||||
final TestFutureCahe<String, String> TestGuaVA = new TestFutureCahe<String, String>();
|
||||
|
||||
Thread t1 = new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
System.out.println("T1======start========");
|
||||
Object value = TestGuaVA.getCache("key", "T1");
|
||||
System.out.println("T1 value==============" + value);
|
||||
System.out.println("T1======end========");
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
Thread t2 = new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
System.out.println("T2======start========");
|
||||
Object value = TestGuaVA.getCache("key", "T2");
|
||||
System.out.println("T2 value==============" + value);
|
||||
System.out.println("T2======end========");
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
Thread t3 = new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
System.out.println("T3======start========");
|
||||
Object value = TestGuaVA.getCache("key", "T3");
|
||||
System.out.println("T3 value==============" + value);
|
||||
System.out.println("T3======end========");
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
t1.start();
|
||||
t2.start();
|
||||
t3.start();
|
||||
|
||||
}
|
||||
|
||||
public Object getCache(K keyValue, String ThreadName) {
|
||||
Future<V> value = null;
|
||||
try {
|
||||
System.out.println("ThreadName getCache==============" + ThreadName);
|
||||
//从缓存获取数据
|
||||
value = cacheMap.get(keyValue);
|
||||
//如果没有的话,把数据放到缓存
|
||||
if (value == null) {
|
||||
value = putCache(keyValue, ThreadName);
|
||||
return value.get();
|
||||
}
|
||||
return value.get();
|
||||
|
||||
} catch (Exception e) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Future<V> putCache(K keyValue, final String ThreadName) {
|
||||
// //把数据放到缓存
|
||||
Future<V> value = null;
|
||||
Callable<V> callable = new Callable<V>() {
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public V call() throws Exception {
|
||||
//可以根据业务从数据库获取等取得数据,这边就模拟已经获取数据了
|
||||
System.out.println("ThreadName 执行业务数据并返回处理结果的数据(访问数据库等)==============" + ThreadName);
|
||||
return (V) "dataValue";
|
||||
}
|
||||
};
|
||||
FutureTask<V> futureTask = new FutureTask<V>(callable);
|
||||
value = cacheMap.putIfAbsent(keyValue, futureTask);
|
||||
if (value == null) {
|
||||
value = futureTask;
|
||||
futureTask.run();
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2020 xrv <xrg@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.date;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.FormatStyle;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
|
||||
/**
|
||||
* @author ehlxr
|
||||
* @since 2021-01-28 16:03.
|
||||
*/
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
// 旧 API 转新 API
|
||||
// Date -> Instant:
|
||||
Instant ins1 = new Date().toInstant();
|
||||
System.out.println(ins1);
|
||||
|
||||
ZonedDateTime zonedDateTime = ins1.atZone(ZoneId.systemDefault());
|
||||
System.out.println(zonedDateTime);
|
||||
|
||||
LocalDateTime localDateTime = zonedDateTime.toLocalDateTime();
|
||||
System.out.println(localDateTime);
|
||||
|
||||
// Calendar -> Instant -> ZonedDateTime:
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
Instant ins2 = calendar.toInstant();
|
||||
ZonedDateTime zdt = ins2.atZone(calendar.getTimeZone().toZoneId());
|
||||
System.out.println(zdt);
|
||||
|
||||
// 新 API 转旧 API
|
||||
// ZonedDateTime -> long:
|
||||
ZonedDateTime zdt1 = ZonedDateTime.now();
|
||||
long ts = zdt1.toEpochSecond() * 1000;
|
||||
|
||||
// long -> Date:
|
||||
Date date = new Date(ts);
|
||||
|
||||
// long -> Calendar:
|
||||
Calendar calendar1 = Calendar.getInstance();
|
||||
calendar1.clear();
|
||||
calendar1.setTimeZone(TimeZone.getTimeZone(zdt.getZone().getId()));
|
||||
calendar1.setTimeInMillis(zdt.toEpochSecond() * 1000);
|
||||
|
||||
|
||||
// 在数据库中存储时间戳时,尽量使用 long 型时间戳,它具有省空间,效率高,不依赖数据库的优点
|
||||
ts = 1574208900000L;
|
||||
System.out.println(timestampToString(ts, Locale.CHINA, "Asia/Shanghai"));
|
||||
System.out.println(timestampToString(ts, Locale.US, "America/New_York"));
|
||||
}
|
||||
|
||||
/**
|
||||
* 不同用户以不同的偏好来显示不同的本地时间
|
||||
*/
|
||||
static String timestampToString(long epochMilli, Locale lo, String zoneId) {
|
||||
Instant ins = Instant.ofEpochMilli(epochMilli);
|
||||
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM, FormatStyle.SHORT)
|
||||
// 按照 Locale 默认习惯格式化
|
||||
.withLocale(lo);
|
||||
|
||||
return f.withLocale(lo).format(ZonedDateTime.ofInstant(ins, ZoneId.of(zoneId)));
|
||||
}
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2020 xrv <xrg@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
/**
|
||||
* Created by ehlxr on 2016/12/23.
|
||||
*/
|
||||
public class dfd {
|
||||
|
||||
public static void main(String[] args) {
|
||||
var map = Maps.newHashMap();
|
||||
map.put("d", 1);
|
||||
System.out.println(map);
|
||||
}
|
||||
|
||||
public void printCircle(int[][] matrix, int startX, int startY, int endX, int endY) {
|
||||
// only one column left
|
||||
if (startY == endY) {
|
||||
for (int i = startX; i <= endX; i++) {
|
||||
System.out.println(matrix[i][endY]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// only one row left
|
||||
if (startX == endX) {
|
||||
for (int i = startY; i <= endY; i++) {
|
||||
System.out.println(matrix[startX][i]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
for (int i = startY; i < endY; i++) {
|
||||
System.out.println(matrix[startX][i]);
|
||||
}
|
||||
for (int i = startX; i < endX; i++) {
|
||||
System.out.println(matrix[i][endY]);
|
||||
}
|
||||
for (int i = endY; i > startY; i--) {
|
||||
System.out.println(matrix[endX][i]);
|
||||
}
|
||||
for (int i = endX; i > startX; i--) {
|
||||
System.out.println(matrix[i][startY]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void printMatrix(int[][] matrix) {
|
||||
|
||||
if (matrix == null) {
|
||||
return;
|
||||
}
|
||||
int startX = 0;
|
||||
int startY = 0;
|
||||
int endY = matrix[0].length - 1;
|
||||
int endX = matrix.length - 1;
|
||||
|
||||
while ((startX <= endX) && (startY <= endY)) {
|
||||
printCircle(matrix, startX, startY, endX, endY);
|
||||
startX++;
|
||||
startY++;
|
||||
endX--;
|
||||
endY--;
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user