This commit is contained in:
2021-08-29 23:16:35 +08:00
parent cc5cbc1ebb
commit 9d6a001b85
213 changed files with 1711 additions and 18656 deletions

View File

@@ -1,6 +1,6 @@
The MIT License (MIT) The MIT License (MIT)
Copyright © 2020 xrv <xrg@live.com> Copyright © 2021 xrv <xrg@live.com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@@ -1,21 +0,0 @@
# Security Policy
## Supported Versions
Use this section to tell people about which versions of your project are
currently being supported with security updates.
| Version | Supported |
| ------- | ------------------ |
| 5.1.x | :white_check_mark: |
| 5.0.x | :x: |
| 4.0.x | :white_check_mark: |
| < 4.0 | :x: |
## Reporting a Vulnerability
Use this section to tell people how to report a vulnerability.
Tell them where to go, how often they can expect to get an update on a
reported vulnerability, what to expect if the vulnerability is accepted or
declined, etc.

44
budd-common/pom.xml Normal file
View File

@@ -0,0 +1,44 @@
<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>
<relativePath/>
</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>
</project>

View File

@@ -1,7 +1,7 @@
/* /*
* The MIT License (MIT) * The MIT License (MIT)
* *
* Copyright © 2020 xrv <xrg@live.com> * Copyright © 2021 xrv <xrg@live.com>
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@@ -22,10 +22,7 @@
* THE SOFTWARE. * THE SOFTWARE.
*/ */
/** package io.github.ehlxr.annotations;
*
*/
package io.github.ehlxr.annotation;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
@@ -33,11 +30,12 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; import java.lang.annotation.Target;
/** /**
* @author ehlxr * 请求日志排除注解
* *
* @author ehlxr
* @since 2021-08-18 14:03.
*/ */
@Target(ElementType.PACKAGE)
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@interface PkgAnnotation { @Target(ElementType.METHOD)
public @interface NoRequestLog {
} }

View File

@@ -22,26 +22,26 @@
* THE SOFTWARE. * THE SOFTWARE.
*/ */
package io.github.ehlxr.jvm.stack; package io.github.ehlxr.common;
/** /**
* 常量
*
* @author ehlxr * @author ehlxr
* @since 2021-07-11 15:19. * @since 2021-08-29 18:32.
*/ */
public class ReturnAddressTest { public interface Constant {
/**
* traceID
*/
String LOG_TRACE_ID = "logTraceId";
public void methodA() { /**
int k = 10; * 接口请求开始时间戳
int l = 20; */
String REQUEST_START_TIME = "request_start_time";
methodB();
}
public void methodB() {
int i = 10;
int j = 20;
int a = i + j;
}
int SUCCESS_CODE = 0;
String SUCCESS_MSG = "success";
} }

View File

@@ -1,28 +1,4 @@
/* package io.github.ehlxr.common;
* 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;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
@@ -30,6 +6,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.SerializationFeature;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import com.google.common.base.Throwables; import com.google.common.base.Throwables;
import io.github.ehlxr.enums.CodeEnum;
import java.io.Serializable; import java.io.Serializable;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
@@ -38,7 +15,7 @@ import java.util.Objects;
/** /**
* 统一输出结果集 * 统一输出结果集
* *
* @author ehlxr * @author lixiangrong
* @since 2020/3/18. * @since 2020/3/18.
*/ */
@JsonInclude(JsonInclude.Include.NON_NULL) @JsonInclude(JsonInclude.Include.NON_NULL)
@@ -67,7 +44,7 @@ public class Result<T> implements Serializable {
} }
public static <T> Result<T> success(T data, String message) { 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) { public static <T> Result<T> success(T data) {
@@ -82,35 +59,35 @@ public class Result<T> implements Serializable {
return new Result<>(c, d, m); 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); return new Result<>(c.getCode(), d, m);
} }
public static <T> Result<T> fail(Code code, String message) { public static <T> Result<T> fail(CodeEnum codeEnum, String message) {
return of(code.getCode(), null, message); return of(codeEnum.getCode(), null, message);
} }
public static <T> Result<T> fail(Code code) { public static <T> Result<T> fail(CodeEnum codeEnum) {
return fail(code, code.getMessage()); return fail(codeEnum, codeEnum.getMessage());
} }
public static <T> Result<T> fail(Throwable e) { public static <T> Result<T> fail(Throwable e) {
// 格式化异常消息防止输出异常栈信息到结果集 // 格式化异常消息防止输出异常栈信息到结果集
e = Throwables.getRootCause(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() { public String getMessage() {
// return Strings.isNullOrEmpty(m) ? c.getMessage() : m; // return Strings.isNullOrEmpty(m) ? c.getMessage() : m;
if (Strings.isNullOrEmpty(message)) { if (Strings.isNullOrEmpty(message)) {
Code code; CodeEnum codeEnum;
try { try {
code = Code.code(this.code); codeEnum = CodeEnum.code(this.code);
} catch (Exception e) { } catch (Exception e) {
return message; return message;
} }
return Objects.isNull(code) ? "" : code.getMessage(); return Objects.isNull(codeEnum) ? "" : codeEnum.getMessage();
} }
return message; return message;
} }

View File

@@ -0,0 +1,56 @@
/*
* The MIT License (MIT)
*
* Copyright © 2021 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.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;
}
}

View File

@@ -0,0 +1,195 @@
/*
* The MIT License (MIT)
*
* Copyright © 2021 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.enums;
/**
* 自定义状态码
*
* @author lixiangrong
* @since 2020/3/18.
*/
public enum CodeEnum {
/**
* 成功
*/
SUCCESSFUL(200, "success"),
LOGIN_TYPE_ERROR(201, "登录类型错误"),
/**
* 用户不存在
*/
USER_NOT_EXIST(202, "用户不存在"),
/**
* 医生状态修改失败
*/
DOCTOR_STATUS_FAILURE(204,"医生状态修改失败"),
/**
* 医生状态不正常
*/
DOCTOR_STATUS_NOT_NORMAL(205,"医生状态不正常"),
DOCTOR_ID_EMPTY(206,"医生不允许为空"),
DEVICE_LOGIN_NULL(209, "设备尚未登录"),
/**
* 成功
*/
UC_CONNECT_ERROR(211, "用户中心异常,请联系管理员"),
UC_NOT_PHRID(212,"用户中心异常未返回用户ID"),
/**
* 诊断记录不存在
*/
RAINQUIRY_NOT_EXIST(301, "诊断记录不存在"),
/**
* 成功
*/
LOGIN_TYPE_NULL(700, "登录方式不能为空"),
/**
* 成功
*/
MOBILE_NULL(701, "手机号码不能为空"),
/**
* 成功
*/
VCODE_ERROR(702, "验证码错误"),
MOBILE_HAVE(703, "此手机号已经注册过"),
/**
* 成功
*/
VCODE_NULL_ERROR(704, "验证码不能为空"),
/**
* 成功
*/
GENDER_RELATION_ERROR(705, "性别和关系错误"),
ID_CARD_NO_ERROR(706, "身份证号不能为空"),
HEAD_IMG_ERROR(707, "人脸识别照片不能为空"),
DEVICE_CODE_ERROR(708, "设备号不能为空"),
/**
* 未知异常
*/
UNKNOWN_EXCEPTION(600, "unknown server exception"),
/**
* 请求参数不能为空
*/
REQUEST_PARAM_NULL_EXCEPTION(601, "required param should not be null"),
/**
* 业务异常
*/
SERVICE_EXCEPTION(602, "service exception"),
/**
* 上善三疗的token没有获取到
*/
NO_SANLIAO_TOKEN(801, "上善三疗的Token没有"),
/**
* No report generated
*/
NO_REPORT_GENERATED(603, "no report generated"),
NO_MATCH_DOCTOR(604,"没有空闲医生"),
NO_MATCH_DATA(604,"没有查询到数据"),
/**
* 未选择全部检查项
*/
SELECT_EXAM_WRAN(2001, "未选择全部检查项"),
/**
* 创建订单失败
*/
CREATE_ORDER_FAIL(2002,"创建订单失败"),
PENDING_ORDER_ERROR(2003,"抢单失败"),
INVALID_ORDER_ERROR(2004,"无效订单"),
INVALID_SHOP_ROLE_ERROR(2005,"当前用户无商铺管理员角色"),
DUPLICATE_VOUCHING_ORDER_ERROR(2006,"您已审核过此订单"),
GET_ORDER_ERROR(2007,"获取订单信息失败"),
GET_SHOP_ROLE_ERROR(2008,"获取商铺角色失败");
private final int code;
private final String message;
CodeEnum(int code, String message) {
this.code = code;
this.message = message;
}
public int getCode() {
return code;
}
public String getCodeString() {
return code + "";
}
public String getMessage() {
return message;
}
@Override
public String toString() {
return "Code{" +
"code=" + code +
", message='" + message + '\'' +
'}';
}
private static final CodeEnum[] CODE_ENUMS = CodeEnum.values();
public static CodeEnum code(int code) {
for (CodeEnum c : CODE_ENUMS) {
if (code == c.getCode()) {
return c;
}
}
return null;
}
}

View File

@@ -1,7 +1,7 @@
/* /*
* The MIT License (MIT) * The MIT License (MIT)
* *
* Copyright © 2020 xrv <xrg@live.com> * Copyright © 2021 xrv <xrg@live.com>
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@@ -22,7 +22,7 @@
* THE SOFTWARE. * THE SOFTWARE.
*/ */
package io.github.ehlxr.utils; package io.github.ehlxr.enums;
/** /**
* FORM 表单提交类型 * FORM 表单提交类型

View File

@@ -1,7 +1,7 @@
/* /*
* The MIT License (MIT) * The MIT License (MIT)
* *
* Copyright © 2020 xrv <xrg@live.com> * Copyright © 2021 xrv <xrg@live.com>
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@@ -22,7 +22,7 @@
* THE SOFTWARE. * THE SOFTWARE.
*/ */
package io.github.ehlxr.utils; package io.github.ehlxr.enums;
/** /**
* @author ehlxr * @author ehlxr

View File

@@ -22,14 +22,30 @@
* THE SOFTWARE. * THE SOFTWARE.
*/ */
package io.github.ehlxr; package io.github.ehlxr.exception;
/** /**
* @author ehlxr * @author ehlxr
* @since 2021-07-07 22:54. * @since 2020-05-06.
*/ */
public class ClassLoaderTest { public class JsonParseException extends RuntimeException {
public static void main(String[] args) { private static final long serialVersionUID = -2626765995683345473L;
System.out.println(ClassLoader.getSystemClassLoader());
public JsonParseException(String msg) {
super(msg);
}
public JsonParseException(String msg, Throwable e) {
super(msg, e);
}
public JsonParseException(Throwable e) {
super(e);
}
@Override
public synchronized Throwable fillInStackTrace() {
// 不拷贝栈信息
return null;
} }
} }

View File

@@ -22,28 +22,46 @@
* THE SOFTWARE. * 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 * @author ehlxr
* @since 2021-02-18 11:23. * @since 2021-08-29 19:18.
*/ */
public class SingleTonStaticInnerClass { public class ServiceDataException extends RuntimeException {
private SingleTonStaticInnerClass() { /**
* 错误码
*/
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) { public ServiceDataException(CodeEnum codeEnum) {
IntStream.range(0, 5).parallel().forEach(i -> System.out.println(Thread.currentThread().getName() + " => " + SingleTonStaticInnerClass.getInstance())); this.code = codeEnum.getCode();
this.msg = codeEnum.getMessage();
} }
public ServiceDataException(int code, String msg) {
super(msg);
this.code = code;
this.msg = msg;
}
} }

View File

@@ -0,0 +1,323 @@
/*
* The MIT License (MIT)
*
* Copyright © 2021 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.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));
}
}

View File

@@ -1,7 +1,7 @@
/* /*
* The MIT License (MIT) * The MIT License (MIT)
* *
* Copyright © 2020 xrv <xrg@live.com> * Copyright © 2021 xrv <xrg@live.com>
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@@ -22,9 +22,11 @@
* THE SOFTWARE. * THE SOFTWARE.
*/ */
package io.github.ehlxr.utils; package io.github.ehlxr.util;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import io.github.ehlxr.enums.FormType;
import io.github.ehlxr.enums.HttpContentType;
import okhttp3.*; import okhttp3.*;
import java.io.File; import java.io.File;

View File

@@ -0,0 +1,108 @@
/*
* The MIT License (MIT)
*
* Copyright © 2021 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.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;
}
}

View File

@@ -1,7 +1,7 @@
/* /*
* The MIT License (MIT) * The MIT License (MIT)
* *
* Copyright © 2020 xrv <xrg@live.com> * Copyright © 2021 xrv <xrg@live.com>
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@@ -22,7 +22,7 @@
* THE SOFTWARE. * THE SOFTWARE.
*/ */
package io.github.ehlxr.utils; package io.github.ehlxr.util;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
@@ -30,6 +30,7 @@ import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.*;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import io.github.ehlxr.exception.JsonParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
@@ -75,7 +76,7 @@ public class JsonUtils {
try { try {
return OBJECT_MAPPER.readTree(obj2String(obj)); return OBJECT_MAPPER.readTree(obj2String(obj));
} catch (JsonProcessingException e) { } catch (JsonProcessingException e) {
throw new RuntimeException(e); throw new JsonParseException(e);
} }
} }
@@ -93,7 +94,7 @@ public class JsonUtils {
try { try {
return obj instanceof String ? (String) obj : OBJECT_MAPPER.writeValueAsString(obj); return obj instanceof String ? (String) obj : OBJECT_MAPPER.writeValueAsString(obj);
} catch (JsonProcessingException e) { } catch (JsonProcessingException e) {
throw new RuntimeException(e); throw new JsonParseException(e);
} }
} }
@@ -111,7 +112,7 @@ public class JsonUtils {
try { try {
return obj instanceof String ? (String) obj : OBJECT_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(obj); return obj instanceof String ? (String) obj : OBJECT_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
} catch (JsonProcessingException e) { } catch (JsonProcessingException e) {
throw new RuntimeException(e); throw new JsonParseException(e);
} }
} }
@@ -130,7 +131,7 @@ public class JsonUtils {
try { try {
return clazz.equals(String.class) ? (T) str : OBJECT_MAPPER.readValue(str, clazz); return clazz.equals(String.class) ? (T) str : OBJECT_MAPPER.readValue(str, clazz);
} catch (JsonProcessingException e) { } catch (JsonProcessingException e) {
throw new RuntimeException(e); throw new JsonParseException(e);
} }
} }
@@ -149,7 +150,7 @@ public class JsonUtils {
try { try {
return typeReference.getType().equals(String.class) ? (T) str : OBJECT_MAPPER.readValue(str, typeReference); return typeReference.getType().equals(String.class) ? (T) str : OBJECT_MAPPER.readValue(str, typeReference);
} catch (JsonProcessingException e) { } catch (JsonProcessingException e) {
throw new RuntimeException(e); throw new JsonParseException(e);
} }
} }
@@ -167,7 +168,7 @@ public class JsonUtils {
try { try {
return OBJECT_MAPPER.readValue(str, javaType); return OBJECT_MAPPER.readValue(str, javaType);
} catch (JsonProcessingException e) { } catch (JsonProcessingException e) {
throw new RuntimeException(e); throw new JsonParseException(e);
} }
} }
@@ -246,4 +247,3 @@ public class JsonUtils {
} }
} }

View File

@@ -0,0 +1,174 @@
/*
* The MIT License (MIT)
*
* Copyright © 2021 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.util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
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.
*/
@SuppressWarnings("unused")
@Component
public class RedisUtil {
/**
* 解锁 lua 脚本
*/
public 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;
/**
* 加锁 不可重入
*
* @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;
}
}

View File

@@ -22,9 +22,11 @@
* THE SOFTWARE. * THE SOFTWARE.
*/ */
package io.github.ehlxr.utils; package io.github.ehlxr.util;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import io.github.ehlxr.common.Constant;
import org.slf4j.MDC;
import java.util.Objects; import java.util.Objects;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
@@ -48,11 +50,11 @@ public class SendAlarmUtil {
/** /**
* 异步发送预警信息 * 异步发送预警信息
* *
* @param msg 预警信息 * @param message 预警信息
* @param action {@link BiConsumer} 完成后回调函数式接口 * @param action {@link BiConsumer} 完成后回调函数式接口
*/ */
public static void send(String msg, BiConsumer<? super String, ? super Throwable> action) { public static void send(String message, BiConsumer<? super String, ? super Throwable> action) {
// String msg = String.format("%s\ntraceid: %s", msg, MDC.get(Constants.LOG_TRACE_ID)); String msg = String.format("%s\ntraceid: %s", message, MDC.get(Constant.LOG_TRACE_ID));
CompletableFuture.supplyAsync(() -> { CompletableFuture.supplyAsync(() -> {
Objects.requireNonNull(dingtalkUrl, "SendAlarmUtil not init."); Objects.requireNonNull(dingtalkUrl, "SendAlarmUtil not init.");
@@ -79,10 +81,10 @@ public class SendAlarmUtil {
.trap(System.out::println) .trap(System.out::println)
.run(); .run();
send("dsfsdf", send("hello",
(t, u) -> System.out.println("send exception message to dingtalk result " + t + ". " + u)); (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); Thread.sleep(2000);
} }

View File

@@ -22,7 +22,7 @@
* THE SOFTWARE. * THE SOFTWARE.
*/ */
package io.github.ehlxr.utils; package io.github.ehlxr.util;
import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.core.type.TypeReference;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
@@ -84,6 +84,163 @@ public interface Try {
return new TryRunnable(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> { abstract class Tryable<C> {
Consumer<? super Throwable> throwConsumer; Consumer<? super Throwable> throwConsumer;
ThrowableRunnable finallyRunnable; 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>> { class TryConsumer<P> extends Tryable<TryConsumer<P>> {
private final ThrowableConsumer<? super P> consumer; 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");
}
} }

13
budd-demo/pom.xml Normal file
View File

@@ -0,0 +1,13 @@
<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>
<relativePath/>
</parent>
<artifactId>budd-demo</artifactId>
<name>budd-demo</name>
</project>

60
budd-server/pom.xml Normal file
View File

@@ -0,0 +1,60 @@
<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>
<relativePath/>
</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-common</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>

View File

@@ -1,7 +1,7 @@
/* /*
* The MIT License (MIT) * The MIT License (MIT)
* *
* Copyright © 2021 xrv <xrg@live.com> * Copyright © 2020 xrv <xrg@live.com>
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@@ -26,14 +26,16 @@ package io.github.ehlxr;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
/** /**
* @author ehlxr * @author ehlxr
* @since 2021-08-29 09:35. * @since 2021-08-29 18:32.
*/ */
@SpringBootApplication @SpringBootApplication
public class BuddApplication { @ServletComponentScan("io.github.ehlxr.filter")
public class BuddServerApplication {
public static void main(String[] args) { public static void main(String[] args) {
SpringApplication.run(BuddApplication.class, args); SpringApplication.run(BuddServerApplication.class, args);
} }
} }

View File

@@ -0,0 +1,141 @@
/*
* The MIT License (MIT)
*
* Copyright © 2021 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.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();
}
}

View File

@@ -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();
}
}

View File

@@ -22,31 +22,29 @@
* THE SOFTWARE. * THE SOFTWARE.
*/ */
package io.github.ehlxr.singleton; package io.github.ehlxr.controller;
import java.util.stream.IntStream; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/** /**
* 枚举单例模式
*
* @author ehlxr * @author ehlxr
* @since 2021-02-18 10:28. * @since 2021-08-29 18:45.
*/ */
public enum SingleEnum { @RestController
@Api(tags = "测试辅助接口")
public class IndexController {
/** /**
* 唯一实例 * 健康检测
*/ */
INSTANCE; @ApiOperation(value = "健康检测", notes = "健康检测")
@GetMapping("/healthcheck")
public static SingleEnum getInstance() { public String healthcheck() {
return INSTANCE; return "ok";
} }
public String hello(String str) {
return "hello " + str;
}
public static void main(String[] args) {
IntStream.range(0, 5).parallel().forEach(i -> System.out.println(Thread.currentThread().getName() + " => " + SingleEnum.getInstance()));
}
} }

View File

@@ -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");
}
}

View File

@@ -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";
}
}

View File

@@ -22,35 +22,31 @@
* THE SOFTWARE. * THE SOFTWARE.
*/ */
package io.github.ehlxr.leetcode; 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 * @author ehlxr
* @since 2021-02-27 21:09. * @since 2020-12-23 11:23.
*/ */
public class ListNode { public class TraceInterceptor extends HandlerInterceptorAdapter {
int val; @Override
ListNode next; public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
MDC.put(Constant.LOG_TRACE_ID, String.valueOf(IdUtil.localId()));
ListNode() { return true;
}
ListNode(int val) {
this.val = val;
}
ListNode(int val, ListNode next) {
this.val = val;
this.next = next;
} }
@Override @Override
public String toString() { public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
return "ListNode{" + MDC.remove(Constant.LOG_TRACE_ID);
"val=" + val +
", next=" + next +
'}';
} }
} }

View 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

View File

@@ -4,11 +4,6 @@ spring:
application: application:
name: budd name: budd
logging:
file:
path: /datalog/weblog/${spring.application.name}
config: classpath:logback-spring.xml
server: server:
tomcat: tomcat:
uri-encoding: UTF-8 uri-encoding: UTF-8
@@ -18,3 +13,6 @@ server:
context-path: /budd context-path: /budd
session: session:
timeout: 60 timeout: 60
logging:
file:
path: /Users/ehlxr/logs/${spring.application.name}

View File

@@ -150,71 +150,71 @@
<onMismatch>DENY</onMismatch> <onMismatch>DENY</onMismatch>
</filter> </filter>
</appender> </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>
<!--<appender name="ALIYUN_LOG_INFO" class="com.aliyun.openservices.log.logback.LoghubAppender">--> <totalSizeInBytes>104857600</totalSizeInBytes>
<!-- <endpoint>${ALIYUN_LOG_ENDPOINT}</endpoint>--> <maxBlockMs>0</maxBlockMs>
<!-- <accessKeyId>${ALIYUN_LOG_ACCESSKEYID}</accessKeyId>--> <ioThreadCount>8</ioThreadCount>
<!-- <accessKeySecret>${ALIYUN_LOG_ACCESSKEYSECRET}</accessKeySecret>--> <batchSizeThresholdInBytes>524288</batchSizeThresholdInBytes>
<!-- <project>${ALIYUN_LOG_PROJECT}</project>--> <batchCountThreshold>4096</batchCountThreshold>
<!-- <logStore>${ALIYUN_LOG_LOGSTORE_INFO}</logStore>--> <lingerMs>2000</lingerMs>
<retries>10</retries>
<baseRetryBackoffMs>100</baseRetryBackoffMs>
<maxRetryBackoffMs>50000</maxRetryBackoffMs>
<!-- <totalSizeInBytes>104857600</totalSizeInBytes>--> <encoder>
<!-- <maxBlockMs>0</maxBlockMs>--> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%X{logTraceId}] %logger{50} [%L] - %msg%n</pattern>
<!-- <ioThreadCount>8</ioThreadCount>--> <charset>UTF-8</charset>
<!-- <batchSizeThresholdInBytes>524288</batchSizeThresholdInBytes>--> </encoder>
<!-- <batchCountThreshold>4096</batchCountThreshold>-->
<!-- <lingerMs>2000</lingerMs>-->
<!-- <retries>10</retries>-->
<!-- <baseRetryBackoffMs>100</baseRetryBackoffMs>-->
<!-- <maxRetryBackoffMs>50000</maxRetryBackoffMs>-->
<!-- <encoder>--> <timeFormat>yyyy-MM-dd'T'HH:mmZ</timeFormat>
<!-- <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%X{logTraceId}] %logger{50} [%L] - %msg%n</pattern>--> <timeZone>Asia/Shanghai</timeZone>
<!-- <charset>UTF-8</charset>-->
<!-- </encoder>-->
<!-- <timeFormat>yyyy-MM-dd'T'HH:mmZ</timeFormat>--> <filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- <timeZone>Asia/Shanghai</timeZone>--> <level>INFO</level>
</filter>
<!-- <filter class="ch.qos.logback.classic.filter.LevelFilter">--> <mdcFields>logTraceId</mdcFields>
<!-- <level>INFO</level>--> </appender>
<!-- </filter>-->
<!-- <mdcFields>logTraceId</mdcFields>--> <appender name="ALIYUN_LOG_ERROR" class="com.aliyun.openservices.log.logback.LoghubAppender">
<!--</appender>--> <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>
<!--<appender name="ALIYUN_LOG_ERROR" class="com.aliyun.openservices.log.logback.LoghubAppender">--> <totalSizeInBytes>104857600</totalSizeInBytes>
<!-- <endpoint>${ALIYUN_LOG_ENDPOINT}</endpoint>--> <maxBlockMs>0</maxBlockMs>
<!-- <accessKeyId>${ALIYUN_LOG_ACCESSKEYID}</accessKeyId>--> <ioThreadCount>8</ioThreadCount>
<!-- <accessKeySecret>${ALIYUN_LOG_ACCESSKEYSECRET}</accessKeySecret>--> <batchSizeThresholdInBytes>524288</batchSizeThresholdInBytes>
<!-- <project>${ALIYUN_LOG_PROJECT}</project>--> <batchCountThreshold>4096</batchCountThreshold>
<!-- <logStore>${ALIYUN_LOG_LOGSTORE_ERROR}</logStore>--> <lingerMs>2000</lingerMs>
<retries>10</retries>
<baseRetryBackoffMs>100</baseRetryBackoffMs>
<maxRetryBackoffMs>50000</maxRetryBackoffMs>
<!-- <totalSizeInBytes>104857600</totalSizeInBytes>--> <encoder>
<!-- <maxBlockMs>0</maxBlockMs>--> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%X{logTraceId}] %logger{50} [%L] - %msg%n</pattern>
<!-- <ioThreadCount>8</ioThreadCount>--> <charset>UTF-8</charset>
<!-- <batchSizeThresholdInBytes>524288</batchSizeThresholdInBytes>--> </encoder>
<!-- <batchCountThreshold>4096</batchCountThreshold>-->
<!-- <lingerMs>2000</lingerMs>-->
<!-- <retries>10</retries>-->
<!-- <baseRetryBackoffMs>100</baseRetryBackoffMs>-->
<!-- <maxRetryBackoffMs>50000</maxRetryBackoffMs>-->
<!-- <encoder>--> <timeFormat>yyyy-MM-dd'T'HH:mmZ</timeFormat>
<!-- <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%X{logTraceId}] %logger{50} [%L] - %msg%n</pattern>--> <timeZone>Asia/Shanghai</timeZone>
<!-- <charset>UTF-8</charset>-->
<!-- </encoder>-->
<!-- <timeFormat>yyyy-MM-dd'T'HH:mmZ</timeFormat>--> <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<!-- <timeZone>Asia/Shanghai</timeZone>--> <level>ERROR</level>
</filter>
<!-- <filter class="ch.qos.logback.classic.filter.ThresholdFilter">-->
<!-- <level>ERROR</level>-->
<!-- </filter>-->
<!-- <mdcFields>logTraceId</mdcFields>-->
<!--</appender>-->
<mdcFields>logTraceId</mdcFields>
</appender>
-->
<!-- <!--
<logger>用来设置某一个包或者具体的某一个类的日志打印级别、 <logger>用来设置某一个包或者具体的某一个类的日志打印级别、
以及指定<appender><logger>仅有一个name属性 以及指定<appender><logger>仅有一个name属性
@@ -243,18 +243,6 @@
<springProfile name="dev"> <springProfile name="dev">
<logger name="io.github.ehlxr" level="debug"/> <logger name="io.github.ehlxr" level="debug"/>
</springProfile> </springProfile>
<!--<springProfile name="test">-->
<!-- <logger name="io.github.ehlxr" level="info"/>-->
<!--</springProfile>-->
<!--<springProfile name="pre">-->
<!-- <logger name="io.github.ehlxr" level="info"/>-->
<!--</springProfile>-->
<!--<springProfile name="stress">-->
<!-- <logger name="io.github.ehlxr" level="info"/>-->
<!--</springProfile>-->
<!--<springProfile name="prod">-->
<!-- <logger name="io.github.ehlxr" level="info"/>-->
<!--</springProfile>-->
<!--<logger name="com.netflix.discovery.shared.resolver.aws.ConfigClusterResolver" level="warn"/>--> <!--<logger name="com.netflix.discovery.shared.resolver.aws.ConfigClusterResolver" level="warn"/>-->
<!-- 可用来获取 StatusManager 中的状态 --> <!-- 可用来获取 StatusManager 中的状态 -->

461
pom.xml
View File

@@ -1,25 +1,17 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"
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> <modelVersion>4.0.0</modelVersion>
<packaging>pom</packaging>
<modules>
<module>budd-common</module>
<module>budd-demo</module>
<module>budd-server</module>
</modules>
<groupId>io.github.ehlxr</groupId> <groupId>io.github.ehlxr</groupId>
<artifactId>budd</artifactId> <artifactId>budd</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version> <version>0.0.1-SNAPSHOT</version>
<!--<build>--> <name>budd-parent</name>
<!-- <plugins>-->
<!-- <plugin>-->
<!-- <groupId>org.apache.maven.plugins</groupId>-->
<!-- <artifactId>maven-compiler-plugin</artifactId>-->
<!-- <configuration>-->
<!-- <source>11</source>-->
<!-- <target>11</target>-->
<!-- </configuration>-->
<!-- </plugin>-->
<!-- </plugins>-->
<!--</build>-->
<name>budd</name>
<url>http://maven.apache.org</url>
<properties> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@@ -28,18 +20,11 @@
<maven.compiler.source>11</maven.compiler.source> <maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target> <maven.compiler.target>11</maven.compiler.target>
<spring.version>5.2.6.RELEASE</spring.version>
<servlet.version>2.5</servlet.version>
<mybatis.version>3.5.6</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> <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> </properties>
<dependencyManagement> <dependencyManagement>
<dependencies> <dependencies>
<dependency> <dependency>
@@ -49,430 +34,26 @@
<type>pom</type> <type>pom</type>
<scope>import</scope> <scope>import</scope>
</dependency> </dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.53</version>
</dependency>
<dependency> <!-- Google Guava -->
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<version>1.46</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<!-- <scope>test</scope> -->
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.3</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.4.2</version>
<exclusions>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- spring begin-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<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>3.4.1</version>
<exclusions>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>
<!-- Servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</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>-->
<!-- activemq依赖包 -->
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-broker</artifactId>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-client</artifactId>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-pool</artifactId>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-spring</artifactId>
</dependency>
<dependency>
<groupId>javax.jms</groupId>
<artifactId>javax.jms-api</artifactId>
</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> <dependency>
<groupId>com.google.guava</groupId> <groupId>com.google.guava</groupId>
<artifactId>guava</artifactId> <artifactId>guava</artifactId>
<version>29.0-jre</version> <version>${guava.version}</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>
<exclusions>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.hbase</groupId> <groupId>com.spring4all</groupId>
<artifactId>hbase-client</artifactId> <artifactId>swagger-spring-boot-starter</artifactId>
<version>1.3.5</version> <version>${spring4all.swagger.version}</version>
<exclusions>
<exclusion>
<artifactId>slf4j-log4j12</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
<exclusion>
<artifactId>log4j</artifactId>
<groupId>log4j</groupId>
</exclusion>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency> </dependency>
<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.5.1</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> <groupId>io.github.ehlxr</groupId>
<version>1.0.2-SNAPSHOT</version> <artifactId>budd-common</artifactId>
<version>${project.version}</version>
</dependency> </dependency>
</dependencies> </dependencies>
</dependencyManagement>
<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>-->
<!-- &lt;!&ndash;-->
<!-- 需要在 setting.xml 中配置认证信息-->
<!-- <servers>-->
<!-- <server>-->
<!-- <id>github</id>-->
<!-- <username>ehlxr</username>-->
<!-- <password>${env.GITHUB_MVN_TOKEN}</password>-->
<!-- </server>-->
<!-- </servers>-->
<!-- &ndash;&gt;-->
<!-- <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>-->
<build>
<!--单元测试时引用src/main/resources下的资源文件-->
<testResources>
<testResource>
<directory>src/test/resources</directory>
</testResource>
<testResource>
<directory>src/main/resources</directory>
</testResource>
</testResources>
<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> </project>

View File

@@ -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();
}
}

View File

@@ -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();
}
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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;
}
}

View File

@@ -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");
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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());
}
}

View File

@@ -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();
}
}
}

View File

@@ -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] + " ");
}
}

View File

@@ -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;
/**
* @author ehlxr
* @date 2018/8/21
*/
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;
// 假设在这行发生 GCobjA 和 objB 是否能被回收?
System.gc();
}
public static void main(String[] args) {
testGC();
}
}

View File

@@ -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);
}
}
}
}

View File

@@ -1,73 +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.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class SerializeUtil {
/**
* 序列化
*
* @param object
* @return
*/
public static byte[] serialize(Object object) {
ObjectOutputStream oos = null;
ByteArrayOutputStream baos = null;
try {
// 序列化
baos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(baos);
oos.writeObject(object);
byte[] bytes = baos.toByteArray();
return bytes;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 反序列化
*
* @param bytes
* @return
*/
public static Object unserialize(byte[] bytes) {
ByteArrayInputStream bais = null;
try {
// 反序列化
bais = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bais);
return ois.readObject();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}

View File

@@ -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();
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}

View File

@@ -1,49 +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.
*/
/**
* @author ehlxr
*/
/**
* @author ehlxr
*
*/
@PkgAnnotation
package io.github.ehlxr.annotation;
/**
* 包内方法
*/
class MyPackageMethod {
public void myPackageMethod() {
System.out.println("MyPackageMethod...");
}
}
/**
* 包内常量
*/
class MyPackageConst {
static final java.lang.String PACKAGE_STRING = "myPackageConst";
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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"));
}
}

View File

@@ -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);
}
}
}

View File

@@ -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;
}
}

View File

@@ -1,180 +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.datastructure.linkedlist;
/**
* @author ehlxr
* @since 2021-04-04 14:19.
*/
public class DoubleLinkedListDemo {
public static void main(String[] args) {
HeroNode2 hero1 = new HeroNode2(1, "宋江", "及时雨");
HeroNode2 hero2 = new HeroNode2(3, "卢俊义", "玉麒麟");
HeroNode2 hero3 = new HeroNode2(5, "吴用", "智多星");
HeroNode2 hero4 = new HeroNode2(8, "林冲", "豹子头");
DoubleLinkedList doubleLinkedList = new DoubleLinkedList();
doubleLinkedList.addByOrder(hero1);
doubleLinkedList.addByOrder(hero2);
doubleLinkedList.addByOrder(hero3);
doubleLinkedList.addByOrder(hero4);
doubleLinkedList.list();
doubleLinkedList.update(new HeroNode2(3, "小卢", "玉麒麟--"));
System.out.println("修改后的结果");
doubleLinkedList.list();
doubleLinkedList.del(3);
System.out.println("删除后的结果");
doubleLinkedList.list();
}
}
/**
* 双向链表
*/
class DoubleLinkedList {
private final HeroNode2 head = new HeroNode2(0, "", "");
public HeroNode2 getHead() {
return head;
}
public void list() {
HeroNode2 temp = head.next;
while (temp != null) {
System.out.println(temp);
temp = temp.next;
}
}
public void add(HeroNode2 heroNode) {
HeroNode2 temp = head;
while (temp.next != null) {
temp = temp.next;
}
temp.next = heroNode;
heroNode.pre = temp;
}
public void addByOrder(HeroNode2 heroNode) {
HeroNode2 temp = head;
while (true) {
if (temp.next == null) {
break;
}
// 找到需要插入位置的前一个节点
if (temp.next.no > heroNode.no) {
break;
}
temp = temp.next;
}
heroNode.next = temp.next;
heroNode.pre = temp;
if (temp.next != null) {
temp.next.pre = heroNode;
}
temp.next = heroNode;
}
public void update(HeroNode2 newHeroNode) {
HeroNode2 temp = head.next;
if (temp == null) {
System.out.println("链表为空!");
}
while (true) {
if (temp == null) {
System.out.printf("没找到 %d 的节点\n", newHeroNode.no);
break;
}
if (temp.no == newHeroNode.no) {
temp.name = newHeroNode.name;
temp.nickname = newHeroNode.nickname;
break;
}
temp = temp.next;
}
}
public void del(int no) {
HeroNode2 temp = head.next;
if (temp == null) {
System.out.println("链表为空!");
}
while (true) {
if (temp == null) {
System.out.printf("没找到要删除的 %d 节点\n", no);
break;
}
// 找到待删除节点
if (temp.no == no) {
temp.pre.next = temp.next;
if (temp.next != null) {
temp.next.pre = temp.pre;
}
break;
}
temp = temp.next;
}
}
}
/**
* 定义HeroNode 每个HeroNode 对象就是一个节点
*/
class HeroNode2 {
public int no;
public String name;
public String nickname;
public HeroNode2 next; //指向下一个节点
public HeroNode2 pre;// 指向上一个节点
public HeroNode2(int no, String name, String nickname) {
this.no = no;
this.name = name;
this.nickname = nickname;
}
/**
* 为了显示方法,我们重新 toString
*/
@Override
public String toString() {
return "HeroNode2 [no=" + no + ", name=" + name + ", nickname=" + nickname + "]";
}
}

View File

@@ -1,144 +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.datastructure.linkedlist;
/**
* @author ehlxr
* @since 2021-04-09 21:14.
*/
public class Josephu {
public static void main(String[] args) {
CircleSingleLinkedList circleSingleLinkedList = new CircleSingleLinkedList();
circleSingleLinkedList.addBoy(5);
circleSingleLinkedList.show();
circleSingleLinkedList.countBoy(1, 2, 5);
}
}
/**
* 循环单向链表
*/
class CircleSingleLinkedList {
private Boy first = null;
public void addBoy(int nums) {
if (nums < 1) {
return;
}
Boy curBoy = null;
for (int i = 1; i <= nums; i++) {
Boy boy = new Boy(i);
if (i == 1) {
first = boy;
curBoy = first;
first.setNext(first);
} else {
curBoy.setNext(boy);
boy.setNext(first);
curBoy = boy;
}
}
}
public void show() {
if (first == null) {
System.out.println("没有boy");
return;
}
Boy curBoy = first;
while (true) {
System.out.printf("boy no %d\n", curBoy.getNo());
if (curBoy.getNext() == first) {
break;
}
curBoy = curBoy.getNext();
}
}
public void countBoy(int startNo, int countNum, int size) {
if (first == null || startNo > size || startNo < 1) {
return;
}
// 找到最后一个节点
Boy helper = first;
while (true) {
if (helper.getNext() == first) {
break;
}
helper = helper.getNext();
}
// 找到开始报数的位置
for (int i = 0; i < startNo - 1; i++) {
helper = helper.getNext();
first = first.getNext();
}
while (true) {
if (helper == first) {
break;
}
for (int i = 0; i < countNum - 1; i++) {
helper = helper.getNext();
first = first.getNext();
}
System.out.printf("出圈的小孩 %d\n", first.getNo());
first = first.getNext();
helper.setNext(first);
}
System.out.printf("最后出圈的小孩 %d\n", first.getNo());
}
}
class Boy {
private int no;
private Boy next;
public Boy(int no) {
this.no = no;
}
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public Boy getNext() {
return next;
}
public void setNext(Boy next) {
this.next = next;
}
}

View File

@@ -1,282 +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.datastructure.linkedlist;
import java.util.Stack;
/**
* @author ehlxr
* @since 2021-04-04 14:19.
*/
public class SingleLinkedListDemo {
public static void main(String[] args) {
HeroNode hero1 = new HeroNode(1, "宋江", "及时雨");
HeroNode hero2 = new HeroNode(3, "卢俊义", "玉麒麟");
HeroNode hero3 = new HeroNode(5, "吴用", "智多星");
HeroNode hero4 = new HeroNode(8, "林冲", "豹子头");
SingleLinkedList singleLinkedList = new SingleLinkedList();
// 加入
// singleLinkedList.add(hero1);
// singleLinkedList.add(hero4);
// singleLinkedList.add(hero2);
// singleLinkedList.add(hero3);
singleLinkedList.addByOrder(hero1);
singleLinkedList.addByOrder(hero4);
singleLinkedList.addByOrder(hero2);
singleLinkedList.addByOrder(hero3);
singleLinkedList.list();
// 反转链表
// reverseList(singleLinkedList.getHead());
// System.out.println("反转之后的链表");
// singleLinkedList.list();
//
// HeroNode newHeroNode = new HeroNode(3, "小吴", "智多星..");
// singleLinkedList.update(newHeroNode);
// System.out.println("修改后的链表");
// singleLinkedList.list();
//
// singleLinkedList.del(3);
// System.out.println("删除 no 为 3 的节点");
// singleLinkedList.list();
SingleLinkedList singleLinkedList2 = new SingleLinkedList();
singleLinkedList2.addByOrder(new HeroNode(2, "2", "2"));
singleLinkedList2.addByOrder(new HeroNode(3, "3", "3"));
singleLinkedList2.addByOrder(new HeroNode(8, "8", "8"));
singleLinkedList2.addByOrder(new HeroNode(9, "9", "9"));
singleLinkedList2.list();
bind2(singleLinkedList.getHead(), singleLinkedList2.getHead());
}
/**
* 反转链表
*/
public static void reverseList(HeroNode head) {
HeroNode pre = null;
HeroNode cur = head.next;
while (cur != null) {
HeroNode next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
head.next = pre;
}
/**
* 合并有序链表
*/
public static void bind2(HeroNode node1, HeroNode node2) {
Stack<HeroNode> stack = new Stack<>();
HeroNode cur = node1.next;
while (cur != null) {
stack.push(cur);
cur = cur.next;
}
cur = node2.next;
while (cur != null) {
stack.push(cur);
cur = cur.next;
}
SingleLinkedList result = new SingleLinkedList();
for (HeroNode node : stack) {
result.addByOrder(node);
}
// 打印结果
System.out.println("合并结果");
result.list();
}
/**
* 合并有序链表
*/
public static void bind(HeroNode node1, HeroNode node2) {
SingleLinkedList result = new SingleLinkedList();
if (node1.next == null) {
result.add(node2.next);
return;
}
if (node2.next == null) {
result.add(node1.next);
return;
}
while (node1.next != null || node2.next != null) {
HeroNode temp = null;
if (node1.next == null) {
result.add(node2.next);
break;
}
if (node2.next == null) {
result.add(node1.next);
break;
}
if (node1.next.no < node2.next.no) {
temp = node1.next;
node1.next = node1.next.next;
} else {
temp = node2.next;
node2.next = node2.next.next;
}
temp.next = null;
result.add(temp);
}
// 打印结果
System.out.println("合并结果");
result.list();
}
}
class SingleLinkedList {
private final HeroNode head = new HeroNode(0, "", "");
public HeroNode getHead() {
return head;
}
public void list() {
HeroNode temp = head.next;
while (temp != null) {
System.out.println(temp);
temp = temp.next;
}
}
public void add(HeroNode heroNode) {
HeroNode temp = head;
while (temp.next != null) {
temp = temp.next;
}
temp.next = heroNode;
}
public void addByOrder(HeroNode heroNode) {
HeroNode temp = head;
while (true) {
if (temp.next == null) {
break;
}
// 找到需要插入位置的前一个节点
if (temp.next.no > heroNode.no) {
break;
}
temp = temp.next;
}
heroNode.next = temp.next;
temp.next = heroNode;
}
public void update(HeroNode newHeroNode) {
HeroNode temp = head.next;
if (temp == null) {
System.out.println("链表为空!");
}
while (true) {
if (temp == null) {
System.out.printf("没找到 %d 的节点\n", newHeroNode.no);
break;
}
if (temp.no == newHeroNode.no) {
temp.name = newHeroNode.name;
temp.nickname = newHeroNode.nickname;
break;
}
temp = temp.next;
}
}
public void del(int no) {
HeroNode temp = head;
if (temp.next == null) {
System.out.println("链表为空!");
}
while (true) {
if (temp.next == null) {
System.out.printf("没找到要删除的 %d 节点\n", no);
break;
}
// 找到待删除节点的前一个节点
if (temp.next.no == no) {
temp.next = temp.next.next;
break;
}
temp = temp.next;
}
}
}
/**
* 定义HeroNode 每个HeroNode 对象就是一个节点
*/
class HeroNode {
public int no;
public String name;
public String nickname;
public HeroNode next; //指向下一个节点
// 构造器
public HeroNode(int no, String name, String nickname) {
this.no = no;
this.name = name;
this.nickname = nickname;
}
/**
* 为了显示方法,我们重新 toString
*/
@Override
public String toString() {
return "HeroNode [no=" + no + ", name=" + name + ", nickname=" + nickname + "]";
}
}

View File

@@ -1,153 +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.datastructure.queue;
import java.util.Scanner;
/**
* 使用数组模拟队列
*
* @author ehlxr
* @since 2021-03-30 22:26.
*/
public class ArrayQueueDemo {
public static void main(String[] args) {
//测试一把
//创建一个队列
ArrayQueue queue = new ArrayQueue(3);
char key; //接收用户输入
Scanner scanner = new Scanner(System.in);//
boolean loop = true;
//输出一个菜单
while (loop) {
System.out.println("s(show): 显示队列");
System.out.println("e(exit): 退出程序");
System.out.println("a(add): 添加数据到队列");
System.out.println("g(get): 从队列取出数据");
System.out.println("h(head): 查看队列头的数据");
key = scanner.next().charAt(0);//接收一个字符
switch (key) {
case 's':
queue.showQueue();
break;
case 'a':
System.out.println("输出一个数");
int value = scanner.nextInt();
queue.addQueue(value);
break;
case 'g': //取出数据
try {
int res = queue.getQueue();
System.out.printf("取出的数据是%d\n", res);
} catch (Exception e) {
// TODO: handle exception
System.out.println(e.getMessage());
}
break;
case 'h': //查看队列头的数据
try {
int res = queue.headQueue();
System.out.printf("队列头的数据是%d\n", res);
} catch (Exception e) {
// TODO: handle exception
System.out.println(e.getMessage());
}
break;
case 'e': //退出
scanner.close();
loop = false;
break;
default:
break;
}
}
System.out.println("程序退出~~");
}
}
class ArrayQueue {
private final int maxSize; // 表示数组的最大容量
private int front; // 队列头
private int rear; // 队列尾
private final int[] arr; // 该数据用于存放数据, 模拟队列
// 创建队列的构造器
public ArrayQueue(int maxSize) {
this.maxSize = maxSize;
this.arr = new int[maxSize];
}
// 判断队列是否满
public boolean isFull() {
return rear == maxSize;
}
// 判断队列是否为空
public boolean isEmpty() {
return rear == front;
}
// 添加数据到队列
public void addQueue(int n) {
if (isFull()) {
System.out.println("队列已满,无法添加数据!");
return;
}
arr[rear++] = n;
}
// 获取队列的数据, 出队列
public int getQueue() {
if (isEmpty()) {
throw new RuntimeException("队列为空,无法获取数据!");
}
return arr[front++];
}
// 显示队列的所有数据
public void showQueue() {
if (isEmpty()) {
System.out.println("队列为空!");
return;
}
for (int i = front; i < rear; i++) {
System.out.printf("arr[%d]=%d\n", i, arr[i]);
}
}
// 显示队列的头数据, 注意不是取出数据
public int headQueue() {
if (isEmpty()) {
throw new RuntimeException("队列为空,无法获取数据!");
}
return arr[front];
}
}

View File

@@ -1,152 +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.datastructure.queue;
import java.util.Scanner;
/**
* @author ehlxr
* @since 2021-03-30 22:52.
*/
public class CircleArrayQueueDemo {
public static void main(String[] args) {
//创建一个环形队列
CircleArrayQueue queue = new CircleArrayQueue(3);
char key; //接收用户输入
Scanner scanner = new Scanner(System.in);
boolean loop = true;
//输出一个菜单
while (loop) {
System.out.println("s(show): 显示队列");
System.out.println("e(exit): 退出程序");
System.out.println("a(add): 添加数据到队列");
System.out.println("g(get): 从队列取出数据");
System.out.println("h(head): 查看队列头的数据");
key = scanner.next().charAt(0);//接收一个字符
switch (key) {
case 's':
queue.showQueue();
break;
case 'a':
System.out.println("输出一个数");
int value = scanner.nextInt();
queue.addQueue(value);
break;
case 'g': //取出数据
try {
int res = queue.getQueue();
System.out.printf("取出的数据是%d\n", res);
} catch (Exception e) {
// TODO: handle exception
System.out.println(e.getMessage());
}
break;
case 'h': //查看队列头的数据
try {
int res = queue.headQueue();
System.out.printf("队列头的数据是%d\n", res);
} catch (Exception e) {
// TODO: handle exception
System.out.println(e.getMessage());
}
break;
case 'e': //退出
scanner.close();
loop = false;
break;
default:
break;
}
}
System.out.println("程序退出~~");
}
}
class CircleArrayQueue {
private final int maxSize; // 表示数组的最大容量
private int front; // 队列头
private int rear; // 队列尾
private final int[] arr; // 该数据用于存放数据, 模拟队列
// 创建队列的构造器
public CircleArrayQueue(int maxSize) {
this.maxSize = maxSize;
this.arr = new int[maxSize];
}
// 判断队列是否满
public boolean isFull() {
return rear - front == maxSize;
// return (rear + 1) % maxSize == front;
}
// 判断队列是否为空
public boolean isEmpty() {
return rear == front;
}
// 添加数据到队列
public void addQueue(int n) {
if (isFull()) {
System.out.println("队列已满,无法添加数据!");
return;
}
arr[(rear++) % maxSize] = n;
}
// 获取队列的数据, 出队列
public int getQueue() {
if (isEmpty()) {
throw new RuntimeException("队列为空,无法获取数据!");
}
int tem = arr[front % maxSize];
front++;
return tem;
}
// 显示队列的所有数据
public void showQueue() {
if (isEmpty()) {
System.out.println("队列为空!");
return;
}
for (int i = front; i < rear; i++) {
System.out.printf("arr[%d]=%d\n", i % maxSize, arr[i % maxSize]);
}
}
// 显示队列的头数据, 注意不是取出数据
public int headQueue() {
if (isEmpty()) {
throw new RuntimeException("队列为空,无法获取数据!");
}
return arr[front];
}
}

View File

@@ -1,249 +0,0 @@
/*
* The MIT License (MIT)
*
* Copyright © 2021 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.datastructure.stack;
import java.util.Scanner;
/**
* @author ehlxr
* @since 2021-04-15 22:18.
*/
public class LinkedListStackDemo {
public static void main(String[] args) {
LinkedListStack2 stack = new LinkedListStack2(4);
String key;
boolean loop = true; //控制是否退出菜单
Scanner scanner = new Scanner(System.in);
while (loop) {
System.out.println("show: 表示显示栈");
System.out.println("exit: 退出程序");
System.out.println("push: 表示添加数据到栈(入栈)");
System.out.println("pop: 表示从栈取出数据(出栈)");
System.out.println("请输入你的选择");
key = scanner.next();
switch (key) {
case "show":
stack.list();
break;
case "push":
System.out.println("请输入一个数");
int value = scanner.nextInt();
stack.push(value);
break;
case "pop":
try {
int res = stack.pop();
System.out.printf("出栈的数据是 %d\n", res);
} catch (Exception e) {
// TODO: handle exception
System.out.println(e.getMessage());
}
break;
case "exit":
scanner.close();
loop = false;
break;
default:
break;
}
}
System.out.println("程序退出~~~");
}
}
/**
* 栈顶是链表的最后一个节点
*/
class LinkedListStack {
private final int maxSize;
private int top = -1;
private final Node head = new Node(0);
public LinkedListStack(int maxSize) {
this.maxSize = maxSize;
}
public boolean isFull() {
return maxSize == top + 1;
}
public boolean isEmpty() {
return top == -1;
}
public void push(int value) {
if (isFull()) {
System.out.println("栈满");
return;
}
Node temp = head;
while (true) {
if (temp.next == null) {
temp.next = new Node(value);
top++;
break;
}
temp = temp.next;
}
}
public int pop() {
if (isEmpty()) {
throw new RuntimeException("栈空");
}
Node temp = head;
while (true) {
// if (temp.next == null) {
// throw new RuntimeException("栈空~~~");
// }
if (temp.next.next == null) {
top--;
int id = temp.next.id;
temp.next = null;
return id;
}
temp = temp.next;
}
}
public void list() {
if (isEmpty()) {
System.out.println("栈空");
return;
}
revert();
Node temp = head.next;
while (temp != null) {
System.out.println(temp);
temp = temp.next;
}
revert();
}
/**
* 反转单向链表
*/
private void revert() {
Node pre = null;
Node cur = head.next;
while (cur != null) {
Node next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
head.next = pre;
}
}
/**
* 栈底是链表的最后一个节点
*/
class LinkedListStack2 {
private final Node head = new Node(0);
private final int maxSize;
private int top = -1;
public LinkedListStack2(int maxSize) {
this.maxSize = maxSize;
}
public boolean isEmpty() {
return top == -1;
}
public boolean isFull() {
return top == maxSize - 1;
}
/**
* 入栈:插入新元素到链表第一个节点
*/
public void push(int id) {
if (isFull()) {
System.out.println("栈满");
return;
}
Node newNode = new Node(id);
Node temp = head.next;
head.next = newNode;
newNode.next = temp;
top++;
}
/**
* 出栈:取出链表第一个元素
*/
public int pop() {
if (isEmpty()) {
throw new RuntimeException("栈空,无法取出数据");
}
Node temp = head.next;
head.next = temp.next;
top--;
return temp.id;
}
public void list() {
if (isEmpty()) {
System.out.println("栈空,无数据");
}
Node temp = head.next;
while (temp != null) {
System.out.println(temp);
temp = temp.next;
}
}
}
class Node {
public int id;
public Node next;
public Node(int id) {
this.id = id;
}
@Override
public String toString() {
return "Node{" + id + "}";
}
}

View File

@@ -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)));
}
}

View File

@@ -1,86 +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 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--;
}
}
}

View File

@@ -1,379 +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.extension;
import io.netty.util.internal.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.regex.Pattern;
/**
* 加载和管理扩展(简化版 Dubbo SPI
*
* @author ehlxr
*/
@SuppressWarnings("unused")
public class ExtensionLoader<T> {
private static final Logger logger = LoggerFactory.getLogger(ExtensionLoader.class);
private static final String EXTENSIONS_DIRECTORY = "META-INF/extensions/";
private static final String EXTENSIONS_INTERNAL_DIRECTORY = "META-INF/extensions/internal/";
private static final Pattern NAME_SEPARATOR = Pattern.compile("\\s*,+\\s*");
private static final ConcurrentMap<Class<?>, ExtensionLoader<?>> EXTENSION_LOADERS = new ConcurrentHashMap<>();
private static final ConcurrentMap<Class<?>, Object> EXTENSION_INSTANCES = new ConcurrentHashMap<>();
private final Class<T> type;
private final ConcurrentMap<String, Holder<Object>> cachedInstances = new ConcurrentHashMap<>();
private final ConcurrentMap<Class<?>, String> cachedNames = new ConcurrentHashMap<>();
private final Holder<Map<String, Class<?>>> cachedClasses = new Holder<>();
private final Map<String, IllegalStateException> exceptions = new ConcurrentHashMap<>();
private String defaultExtension;
private ExtensionLoader(Class<T> type) {
this.type = type;
}
/**
* {@link ExtensionLoader} 的工厂方法。
*
* @param type 扩展点接口类型
* @param <T> 扩展点类型
* @return {@link ExtensionLoader} 实例
* @throws IllegalArgumentException 参数为 <code>null</code>
* 或是扩展点接口上没有 {@link SPI} 注解。
*/
@SuppressWarnings("unchecked")
public static <T> ExtensionLoader<T> getExtensionLoader(Class<T> type) {
if (type == null) {
throw new IllegalArgumentException("SPI type == null");
}
if (!type.isInterface()) {
throw new IllegalArgumentException("SPI type(" + type.getName() + ") is not interface!");
}
if (!type.isAnnotationPresent(SPI.class)) {
throw new IllegalArgumentException("type(" + type.getName() +
") is not a extension, because WITHOUT @SPI Annotation!");
}
ExtensionLoader<T> loader = (ExtensionLoader<T>) EXTENSION_LOADERS.get(type);
if (loader == null) {
EXTENSION_LOADERS.putIfAbsent(type, new ExtensionLoader<>(type));
loader = (ExtensionLoader<T>) EXTENSION_LOADERS.get(type);
}
return loader;
}
/**
* Get the String of Throwable, like the output of {@link Throwable#printStackTrace()}.
*
* @param throwable the input throwable.
*/
private static String throwable2String(Throwable throwable) {
StringWriter w = new StringWriter(1024);
try (PrintWriter p = new PrintWriter(w)) {
throwable.printStackTrace(p);
return w.toString();
}
}
public T getExtension(String name) {
if (StringUtil.isNullOrEmpty(name)) {
throw new IllegalArgumentException("SPI name == null");
}
Holder<Object> holder = cachedInstances.get(name);
if (holder == null) {
cachedInstances.putIfAbsent(name, new Holder<>());
holder = cachedInstances.get(name);
}
Object instance = holder.get();
if (instance == null) {
synchronized (cachedInstances) {
instance = holder.get();
if (instance == null) {
instance = createExtension(name);
holder.set(instance);
}
}
}
//noinspection unchecked
return (T) instance;
}
/**
* 返回缺省的扩展。
*
* @throws IllegalStateException 指定的扩展没有设置缺省扩展点
*/
public T getDefaultExtension() {
loadExtensionClasses0();
if (null == defaultExtension || defaultExtension.length() == 0) {
throw new IllegalStateException("No default extension on extension " + type.getName());
}
return getExtension(defaultExtension);
}
/**
* 获取扩展点实现的所有扩展点名。
*
* @since 0.1.0
*/
public Set<String> getSupportedExtensions() {
Map<String, Class<?>> classes = getExtensionClasses();
return Collections.unmodifiableSet(new HashSet<>(classes.keySet()));
}
public String getExtensionName(Class<?> spi) {
getExtensionClasses();
return cachedNames.get(spi);
}
private T createExtension(String name) {
Class<?> clazz = getExtensionClasses().get(name);
if (clazz == null) {
throw findExtensionClassLoadException(name);
}
try {
//noinspection unchecked
T instance = (T) EXTENSION_INSTANCES.get(clazz);
if (instance == null) {
EXTENSION_INSTANCES.putIfAbsent(clazz, clazz.newInstance());
//noinspection unchecked
instance = (T) EXTENSION_INSTANCES.get(clazz);
}
return instance;
} catch (Throwable t) {
throw new IllegalStateException("SPI instance(name: " + name + ", class: " +
type + ") could not be instantiated: " + t.getMessage(), t);
}
}
private Map<String, Class<?>> getExtensionClasses() {
Map<String, Class<?>> classes = cachedClasses.get();
if (classes == null) {
synchronized (cachedClasses) {
classes = cachedClasses.get();
if (classes == null) {
loadExtensionClasses0();
classes = cachedClasses.get();
}
}
}
return classes;
}
private IllegalStateException findExtensionClassLoadException(String name) {
for (Map.Entry<String, IllegalStateException> entry : exceptions.entrySet()) {
if (entry.getKey().toLowerCase().contains(name.toLowerCase())) {
return entry.getValue();
}
}
int i = 1;
StringBuilder buf = new StringBuilder("No such extension " + type.getName() + " by name " + name);
for (Map.Entry<String, IllegalStateException> entry : exceptions.entrySet()) {
if (i == 1) {
buf.append(", possible causes: ");
}
buf.append("\r\n(");
buf.append(i++);
buf.append(") ");
buf.append(entry.getKey());
buf.append(":\r\n");
buf.append(throwable2String(entry.getValue()));
}
return new IllegalStateException(buf.toString());
}
private void loadExtensionClasses0() {
final SPI annotation = type.getAnnotation(SPI.class);
if (annotation != null) {
String value = annotation.value();
if ((value = value.trim()).length() > 0) {
String[] names = NAME_SEPARATOR.split(value);
if (names.length > 1) {
throw new IllegalStateException("more than 1 default extension name on extension " +
type.getName() + ": " + Arrays.toString(names));
}
if (names.length == 1 && names[0].trim().length() > 0) {
defaultExtension = names[0].trim();
}
}
}
Map<String, Class<?>> extensionClasses = new HashMap<>();
loadFile(extensionClasses, EXTENSIONS_DIRECTORY);
loadFile(extensionClasses, EXTENSIONS_INTERNAL_DIRECTORY);
cachedClasses.set(extensionClasses);
}
private void loadFile(Map<String, Class<?>> extensionClasses, String dir) {
String fileName = dir + type.getName();
try {
Enumeration<URL> urls;
ClassLoader classLoader = ExtensionLoader.class.getClassLoader();
if (classLoader != null) {
urls = classLoader.getResources(fileName);
} else {
urls = ClassLoader.getSystemResources(fileName);
}
if (urls != null) {
while (urls.hasMoreElements()) {
URL url = urls.nextElement();
try (
BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream(), StandardCharsets.UTF_8))
) {
String line;
while ((line = reader.readLine()) != null) {
// delete comments
final int ci = line.indexOf('#');
if (ci >= 0) {
line = line.substring(0, ci);
}
line = line.trim();
if (line.length() == 0) {
continue;
}
try {
String name = null;
int i = line.indexOf('=');
if (i > 0) {
name = line.substring(0, i).trim();
line = line.substring(i + 1).trim();
}
if (line.length() > 0) {
Class<? extends T> clazz = Class.forName(line, true, classLoader).asSubclass(type);
if (!type.isAssignableFrom(clazz)) {
throw new IllegalStateException("Error when load extension class(interface: " +
type.getName() + ", class line: " + clazz.getName() + "), class "
+ clazz.getName() + "is not subtype of interface.");
}
if (name == null || name.length() == 0) {
// clazz: xxx.xxx.ZfyAPI
// type: xxx.xxx.API
// -> name: zfy
if (clazz.getSimpleName().length() > type.getSimpleName().length()
&& clazz.getSimpleName().endsWith(type.getSimpleName())) {
name = clazz.getSimpleName().substring(0, clazz.getSimpleName().length()
- type.getSimpleName().length()).toLowerCase();
} else {
throw new IllegalStateException("No such extension name for the class "
+ clazz.getName() + " in the config " + url);
}
}
if (!cachedNames.containsKey(clazz)) {
cachedNames.put(clazz, name);
}
Class<?> c = extensionClasses.get(name);
if (c == null) {
extensionClasses.put(name, clazz);
} else if (c != clazz) {
throw new IllegalStateException("Duplicate extension "
+ type.getName() + " name " + name + " on " + c.getName()
+ " and " + clazz.getName());
}
}
} catch (Throwable t) {
IllegalStateException e = new IllegalStateException("Failed to load extension class(interface: "
+ type + ", class line: " + line + ") in " + url + ", cause: " + t.getMessage(), t);
exceptions.put(line, e);
}
}
} catch (Throwable t) {
logger.error("Exception when load extension class(interface: " +
type + ", class file: " + url + ") in " + url, t);
}
}
}
} catch (Throwable t) {
logger.error("Exception when load extension class(interface: " +
type + ", description file: " + fileName + ").", t);
}
}
@Override
public String toString() {
return this.getClass().getName() + "[" + type.getName() + "]";
}
/**
* Holds a value of type <code>T</code>.
*/
@SuppressWarnings("unused")
private static final class Holder<T> {
/**
* The value contained in the holder.
*/
private volatile T value;
/**
* Creates a new holder with a <code>null</code> value.
*/
Holder() {
}
/**
* Create a new holder with the specified value.
*
* @param value The value to be stored in the holder.
*/
public Holder(T value) {
this.value = value;
}
public T get() {
return value;
}
public void set(T value) {
this.value = value;
}
}
}

View File

@@ -1,46 +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.extension;
import java.lang.annotation.*;
/**
* 把一个接口标识成扩展点。
* <p>
* 没有此注释的接口 {@link ExtensionLoader} 会拒绝接管
*
* @author ehlxr
* @see ExtensionLoader
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface SPI {
/**
* the default extension name.
*/
String value() default "";
}

View File

@@ -1,96 +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.forkjoin;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;
import java.util.stream.IntStream;
/**
* @author ehlxr
* @since 2020-12-30 17:59.
*/
public class Main {
public static void main(String[] args) {
ForkJoinPool forkJoinPool = new ForkJoinPool(Runtime.getRuntime().availableProcessors());
// Future<Integer> future = forkJoinPool.submit(new RecursiveTaskDemo(arr, 0, arr.length));
// System.out.println("计算出来的总和="+future.get());
int[] arr = IntStream.range(0, 1000).toArray();
Integer integer = forkJoinPool.invoke(new RecursiveTaskDemo(arr, 0, arr.length));
System.out.println("计算出来的总和=" + integer);
// 关闭线程池
forkJoinPool.shutdown();
System.out.println(IntStream.range(0, 1000).parallel().reduce((i, j) -> i + j));
System.out.println(IntStream.range(0, 1000).parallel().reduce(Integer::sum));
System.out.println(IntStream.range(0, 1000).parallel().sum());
}
static class RecursiveTaskDemo extends RecursiveTask<Integer> {
/**
* 每个"小任务"最多只打印70个数
*/
private static final int MAX = 100;
private static final long serialVersionUID = -134954066152987391L;
private final int[] arr;
private final int start;
private final int end;
public RecursiveTaskDemo(int[] arr, int start, int end) {
this.arr = arr;
this.start = start;
this.end = end;
}
@Override
protected Integer compute() {
int sum = 0;
// 当end-start的值小于MAX时候开始打印
if ((end - start) < MAX) {
for (int i = start; i < end; i++) {
sum += arr[i];
}
return sum;
} else {
System.err.println("=====任务分解======");
// 将大任务分解成两个小任务
int middle = (start + end) / 2;
RecursiveTaskDemo left = new RecursiveTaskDemo(arr, start, middle);
RecursiveTaskDemo right = new RecursiveTaskDemo(arr, middle, end);
// 并行执行两个小任务
left.fork();
right.fork();
// 把两个小任务累加的结果合并起来
return left.join() + right.join();
}
}
}
}

View File

@@ -1,50 +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.hashing;
public class Cluster {
private static final int SERVER_SIZE_MAX = 1024;
private final Server[] servers = new Server[SERVER_SIZE_MAX];
private int size = 0;
public void put(Entry e) {
int index = e.hashCode() % size;
servers[index].put(e);
}
public Entry get(Entry e) {
int index = e.hashCode() % size;
return servers[index].get(e);
}
public boolean addServer(Server s) {
if (size >= SERVER_SIZE_MAX)
return false;
servers[size++] = s;
return true;
}
}

View File

@@ -1,38 +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.hashing;
public class Entry {
private final String key;
Entry(String key) {
this.key = key;
}
@Override
public String toString() {
return key;
}
}

View File

@@ -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.hashing;
public class Main {
public static void main(String[] args) {
Cluster c = createCluster();
Entry[] entries = {
new Entry("i"),
new Entry("have"),
new Entry("a"),
new Entry("pen"),
new Entry("an"),
new Entry("apple"),
new Entry("applepen"),
new Entry("pineapple"),
new Entry("pineapplepen"),
new Entry("PPAP")
};
for (Entry e : entries) {
c.put(e);
}
c.addServer(new Server("192.168.0.6"));
findEntries(c, entries);
}
private static Cluster createCluster() {
Cluster c = new Cluster();
c.addServer(new Server("192.168.0.0"));
c.addServer(new Server("192.168.0.1"));
c.addServer(new Server("192.168.0.2"));
c.addServer(new Server("192.168.0.3"));
c.addServer(new Server("192.168.0.4"));
c.addServer(new Server("192.168.0.5"));
return c;
}
private static void findEntries(Cluster c, Entry[] entries) {
for (Entry e : entries) {
if (e == c.get(e)) {
System.out.println("重新找到了entry:" + e);
} else {
System.out.println("entry已失效:" + e);
}
}
}
}

View File

@@ -1,46 +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.hashing;
import java.util.HashMap;
import java.util.Map;
public class Server {
private final String name;
private final Map<Entry, Entry> entries;
Server(String name) {
this.name = name;
entries = new HashMap<>();
}
public void put(Entry e) {
entries.put(e, e);
}
public Entry get(Entry e) {
return entries.get(e);
}
}

View File

@@ -1,65 +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.hashing.consistent;
import java.util.SortedMap;
import java.util.TreeMap;
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();
}
return servers.get(hash);
}
public boolean addServer(Server s) {
if (size >= SERVER_SIZE_MAX)
return false;
servers.put(s.hashCode(), s);
size++;
return true;
}
}

View File

@@ -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.hashing.consistent;
public class Entry {
private final String key;
Entry(String key) {
this.key = key;
}
@Override
public String toString() {
return key;
}
public int hashCode() {
return key.hashCode();
}
}

View File

@@ -1,73 +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.hashing.consistent;
public class Main {
public static void main(String[] args) {
Cluster c = createCluster();
Entry[] entries = {
new Entry("i"),
new Entry("have"),
new Entry("a"),
new Entry("pen"),
new Entry("an"),
new Entry("apple"),
new Entry("applepen"),
new Entry("pineapple"),
new Entry("pineapplepen"),
new Entry("PPAP")
};
for (Entry e : entries) {
c.put(e);
}
c.addServer(new Server("achuguniadsfaang"));
findEntries(c, entries);
}
private static Cluster createCluster() {
Cluster c = new Cluster();
c.addServer(new Server("international"));
c.addServer(new Server("china"));
c.addServer(new Server("japanjapan"));
c.addServer(new Server("Amarica"));
c.addServer(new Server("samsungtsisger"));
c.addServer(new Server("achuguniang"));
return c;
}
private static void findEntries(Cluster c, Entry[] entries) {
for (Entry e : entries) {
if (e == c.get(e)) {
System.out.println("重新找到了entry: " + e);
} else {
System.out.println("entry已失效: " + e);
}
}
}
}

View File

@@ -1,51 +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.hashing.consistent;
import java.util.HashMap;
import java.util.Map;
public class Server {
private final String name;
private final Map<Entry, Entry> entries;
Server(String name) {
this.name = name;
entries = new HashMap<>();
}
public void put(Entry e) {
entries.put(e, e);
}
public Entry get(Entry e) {
return entries.get(e);
}
public int hashCode() {
return name.hashCode();
}
}

View File

@@ -1,300 +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.hbase;
import io.github.ehlxr.utils.Pair;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.filter.FilterList;
import org.apache.hadoop.hbase.util.Bytes;
import java.io.IOException;
import java.util.List;
/**
* @author ehlxr
*/
public class HBaseUtils {
private static Connection connection;
static {
Configuration configuration = HBaseConfiguration.create();
configuration.set("hbase.zookeeper.property.clientPort", "2181");
// 如果是集群 则主机名用逗号分隔
configuration.set("hbase.zookeeper.quorum", "127.0.0.1");
// configuration.set("hbase.master", "127.0.0.1:16000");
try {
connection = ConnectionFactory.createConnection(configuration);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 创建 HBase 表
*
* @param tableName 表名
* @param columnFamilies 列族的数组
*/
public static boolean createTable(String tableName, List<String> columnFamilies) {
try {
HBaseAdmin admin = (HBaseAdmin) connection.getAdmin();
if (admin.tableExists(tableName)) {
return false;
}
HTableDescriptor tableDescriptor = new HTableDescriptor(TableName.valueOf(tableName));
columnFamilies.forEach(columnFamily -> {
HColumnDescriptor columnDescriptor = new HColumnDescriptor(columnFamily);
columnDescriptor.setMaxVersions(1);
tableDescriptor.addFamily(columnDescriptor);
});
admin.createTable(tableDescriptor);
} catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* 删除 hBase 表
*
* @param tableName 表名
*/
public static boolean deleteTable(String tableName) {
try {
HBaseAdmin admin = (HBaseAdmin) connection.getAdmin();
// 删除表前需要先禁用表
admin.disableTable(tableName);
admin.deleteTable(tableName);
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* 插入数据
*
* @param tableName 表名
* @param rowKey 唯一标识
* @param columnFamilyName 列族名
* @param qualifier 列标识
* @param value 数据
*/
public static boolean putRow(String tableName, String rowKey, String columnFamilyName, String qualifier,
String value) {
try {
Table table = connection.getTable(TableName.valueOf(tableName));
Put put = new Put(Bytes.toBytes(rowKey));
put.addColumn(Bytes.toBytes(columnFamilyName), Bytes.toBytes(qualifier), Bytes.toBytes(value));
table.put(put);
table.close();
} catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* 插入数据
*
* @param tableName 表名
* @param rowKey 唯一标识
* @param columnFamilyName 列族名
* @param pairList 列标识和值的集合
*/
public static boolean putRow(String tableName, String rowKey, String columnFamilyName, List<Pair<String, String>> pairList) {
try {
Table table = connection.getTable(TableName.valueOf(tableName));
Put put = new Put(Bytes.toBytes(rowKey));
pairList.forEach(pair -> put.addColumn(Bytes.toBytes(columnFamilyName), Bytes.toBytes(pair.getKey()), Bytes.toBytes(pair.getValue())));
table.put(put);
table.close();
} catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* 根据 rowKey 获取指定行的数据
*
* @param tableName 表名
* @param rowKey 唯一标识
*/
public static Result getRow(String tableName, String rowKey) {
try {
Table table = connection.getTable(TableName.valueOf(tableName));
Get get = new Get(Bytes.toBytes(rowKey));
return table.get(get);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
/**
* 获取指定行指定列 (cell) 的最新版本的数据
*
* @param tableName 表名
* @param rowKey 唯一标识
* @param columnFamily 列族
* @param qualifier 列标识
*/
public static String getCell(String tableName, String rowKey, String columnFamily, String qualifier) {
try {
Table table = connection.getTable(TableName.valueOf(tableName));
Get get = new Get(Bytes.toBytes(rowKey));
if (!get.isCheckExistenceOnly()) {
get.addColumn(Bytes.toBytes(columnFamily), Bytes.toBytes(qualifier));
Result result = table.get(get);
byte[] resultValue = result.getValue(Bytes.toBytes(columnFamily), Bytes.toBytes(qualifier));
return Bytes.toString(resultValue);
} else {
return null;
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
/**
* 检索全表
*
* @param tableName 表名
*/
public static ResultScanner getScanner(String tableName) {
try {
Table table = connection.getTable(TableName.valueOf(tableName));
Scan scan = new Scan();
return table.getScanner(scan);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
/**
* 检索表中指定数据
*
* @param tableName 表名
* @param filterList 过滤器
*/
public static ResultScanner getScanner(String tableName, FilterList filterList) {
try {
Table table = connection.getTable(TableName.valueOf(tableName));
Scan scan = new Scan();
scan.setFilter(filterList);
return table.getScanner(scan);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
/**
* 检索表中指定数据
*
* @param tableName 表名
* @param startRowKey 起始 RowKey
* @param endRowKey 终止 RowKey
* @param filterList 过滤器
*/
public static ResultScanner getScanner(String tableName, String startRowKey, String endRowKey,
FilterList filterList) {
try {
Table table = connection.getTable(TableName.valueOf(tableName));
Scan scan = new Scan();
scan.setStartRow(Bytes.toBytes(startRowKey));
scan.setStopRow(Bytes.toBytes(endRowKey));
scan.setFilter(filterList);
return table.getScanner(scan);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
/**
* 删除指定行记录
*
* @param tableName 表名
* @param rowKey 唯一标识
*/
public static boolean deleteRow(String tableName, String rowKey) {
try {
Table table = connection.getTable(TableName.valueOf(tableName));
Delete delete = new Delete(Bytes.toBytes(rowKey));
table.delete(delete);
} catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* 删除指定行的指定列
*
* @param tableName 表名
* @param rowKey 唯一标识
* @param familyName 列族
* @param qualifier 列标识
*/
public static boolean deleteColumn(String tableName, String rowKey, String familyName,
String qualifier) {
try {
Table table = connection.getTable(TableName.valueOf(tableName));
Delete delete = new Delete(Bytes.toBytes(rowKey));
delete.addColumn(Bytes.toBytes(familyName), Bytes.toBytes(qualifier));
table.delete(delete);
table.close();
} catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}
}

View File

@@ -1,132 +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.hbase;
import io.github.ehlxr.utils.Pair;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.hadoop.hbase.filter.CompareFilter;
import org.apache.hadoop.hbase.filter.FilterList;
import org.apache.hadoop.hbase.filter.SingleColumnValueFilter;
import org.apache.hadoop.hbase.util.Bytes;
import java.util.Arrays;
import java.util.List;
/**
* @author ehlxr
* @since 2020/2/26.
*/
public class Main {
private static final String TABLE_NAME = "class";
private static final String TEACHER = "teacher";
private static final String STUDENT = "student";
public static void main(String[] args) {
createTable();
insertData();
getScanner();
// deleteTable();
}
private static void createTable() {
// 新建表
List<String> columnFamilies = Arrays.asList(TEACHER, STUDENT);
boolean table = HBaseUtils.createTable(TABLE_NAME, columnFamilies);
System.out.println("表创建结果:" + table);
}
private static void insertData() {
List<Pair<String, String>> pairs1 = Arrays.asList(new Pair<>("name", "Tom"),
new Pair<>("age", "22"),
new Pair<>("gender", "1"));
HBaseUtils.putRow(TABLE_NAME, "rowKey1", STUDENT, pairs1);
List<Pair<String, String>> pairs2 = Arrays.asList(new Pair<>("name", "Jack"),
new Pair<>("age", "33"),
new Pair<>("gender", "2"));
HBaseUtils.putRow(TABLE_NAME, "rowKey2", STUDENT, pairs2);
List<Pair<String, String>> pairs3 = Arrays.asList(new Pair<>("name", "Mike"),
new Pair<>("age", "44"),
new Pair<>("gender", "1"));
HBaseUtils.putRow(TABLE_NAME, "rowKey3", STUDENT, pairs3);
}
private static void getRow() {
Result result = HBaseUtils.getRow(TABLE_NAME, "rowKey1");
if (result != null) {
System.out.println(Bytes
.toString(result.getValue(Bytes.toBytes(STUDENT), Bytes.toBytes("name"))));
}
}
private static void getCell() {
String cell = HBaseUtils.getCell(TABLE_NAME, "rowKey2", STUDENT, "age");
System.out.println("cell age :" + cell);
}
private static void getScanner() {
ResultScanner scanner = HBaseUtils.getScanner(TABLE_NAME);
if (scanner != null) {
scanner.forEach(result -> System.out.println(Bytes.toString(result.getRow()) + "->" + Bytes
.toString(result.getValue(Bytes.toBytes(STUDENT), Bytes.toBytes("name")))));
scanner.close();
}
}
private static void getScannerWithFilter() {
FilterList filterList = new FilterList(FilterList.Operator.MUST_PASS_ALL);
SingleColumnValueFilter nameFilter = new SingleColumnValueFilter(Bytes.toBytes(STUDENT),
Bytes.toBytes("name"), CompareFilter.CompareOp.EQUAL, Bytes.toBytes("Jack"));
filterList.addFilter(nameFilter);
ResultScanner scanner = HBaseUtils.getScanner(TABLE_NAME, filterList);
if (scanner != null) {
scanner.forEach(result -> System.out.println(Bytes.toString(result.getRow()) + "->" + Bytes
.toString(result.getValue(Bytes.toBytes(STUDENT), Bytes.toBytes("name")))));
scanner.close();
}
}
private static void deleteColumn() {
boolean b = HBaseUtils.deleteColumn(TABLE_NAME, "rowKey2", STUDENT, "age");
System.out.println("删除结果: " + b);
}
private static void deleteRow() {
boolean b = HBaseUtils.deleteRow(TABLE_NAME, "rowKey2");
System.out.println("删除结果: " + b);
}
private static void deleteTable() {
boolean b = HBaseUtils.deleteTable(TABLE_NAME);
System.out.println("删除结果: " + b);
}
}

View File

@@ -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.http;
import java.io.IOException;
import java.net.URI;
// import java.net.http.HttpClient;
// import java.net.http.HttpRequest;
// import java.net.http.HttpResponse;
import java.time.Duration;
/**
* @author ehlxr
* @since 2021-01-31 20:54.
*/
public class Main {
public static void main(String[] args) throws IOException, InterruptedException {
// HttpClient client = HttpClient.newBuilder()
// .version(HttpClient.Version.HTTP_1_1)
// .followRedirects(HttpClient.Redirect.NORMAL)
// .connectTimeout(Duration.ofSeconds(20))
// // .proxy(ProxySelector.of(new InetSocketAddress("proxy.example.com", 80)))
// // .authenticator(Authenticator.getDefault())
// .build();
//
// HttpRequest request = HttpRequest.newBuilder()
// .uri(URI.create("https://ehlxr.me/"))
// .timeout(Duration.ofMinutes(2))
// .header("Content-Type", "application/json")
// .GET()
// // .POST(HttpRequest.BodyPublishers.ofFile(Paths.get("file.json")))
// .build();
//
// // Synchronous Example
// // HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
// // System.out.println(response.statusCode());
// // System.out.println(response.body());
//
//
// // Asynchronous Example
//
// client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
// .thenApply(HttpResponse::body)
// .thenAccept(body -> System.out.println("response body is:\n" + body))
// .join();
}
}

View File

@@ -1,95 +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.io;
import org.apache.commons.io.IOUtils;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.StandardCharsets;
/**
* @author ehlxr
* @since 2021-01-23 20:07.
*/
public class BioServer {
public static void main(String[] args) throws IOException {
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
// 监听 8080 端口进来的 TCP 链接
serverSocketChannel.socket().bind(new InetSocketAddress(8080));
//noinspection InfiniteLoopStatement
while (true) {
// 这里会阻塞,直到有一个请求的连接进来
SocketChannel socketChannel = serverSocketChannel.accept();
// 开启一个新的线程来处理这个请求,然后在 while 循环中继续监听 8080 端口
SocketHandler handler = new SocketHandler(socketChannel);
//noinspection AlibabaAvoidManuallyCreateThread
new Thread(handler).start();
}
}
static class SocketHandler implements Runnable {
private final SocketChannel socketChannel;
public SocketHandler(SocketChannel socketChannel) {
this.socketChannel = socketChannel;
}
@Override
public void run() {
ByteBuffer buffer = ByteBuffer.allocate(1024);
try {
// 将请求数据读入 Buffer 中
int num;
while ((num = socketChannel.read(buffer)) > 0) {
// 读取 Buffer 内容之前先 flip 一下
buffer.flip();
// 提取 Buffer 中的数据
byte[] bytes = new byte[num];
buffer.get(bytes);
String re = new String(bytes, StandardCharsets.UTF_8);
System.out.println("收到请求:" + re);
// 回应客户端
ByteBuffer writeBuffer = ByteBuffer.wrap(("我已经收到你的请求,你的请求内容是:" + re).getBytes());
socketChannel.write(writeBuffer);
buffer.clear();
}
} catch (IOException e) {
IOUtils.closeQuietly(socketChannel);
}
}
}
}

View File

@@ -1,59 +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.io;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.nio.charset.StandardCharsets;
/**
* @author ehlxr
* @since 2021-01-23 20:09.
*/
public class Client {
public static void main(String[] args) throws IOException {
SocketChannel socketChannel = SocketChannel.open();
socketChannel.connect(new InetSocketAddress("localhost", 8080));
// 发送请求
ByteBuffer buffer = ByteBuffer.wrap("1234567890".getBytes());
socketChannel.write(buffer);
// 读取响应
ByteBuffer readBuffer = ByteBuffer.allocate(1024);
int num;
if ((num = socketChannel.read(readBuffer)) > 0) {
readBuffer.flip();
byte[] re = new byte[num];
readBuffer.get(re);
String result = new String(re, StandardCharsets.UTF_8);
System.out.println("返回值: " + result);
}
}
}

View File

@@ -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.io;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;
/**
* @author ehlxr
* @since 2021-01-23 20:18.
*/
public class SelectorServer {
public static void main(String[] args) throws IOException {
Selector selector = Selector.open();
ServerSocketChannel server = ServerSocketChannel.open();
server.socket().bind(new InetSocketAddress(8080));
// 将其注册到 Selector 中,监听 OP_ACCEPT 事件
server.configureBlocking(false);
server.register(selector, SelectionKey.OP_ACCEPT);
//noinspection InfiniteLoopStatement
while (true) {
int readyChannels = selector.select();
if (readyChannels == 0) {
continue;
}
Set<SelectionKey> readyKeys = selector.selectedKeys();
// 遍历
Iterator<SelectionKey> iterator = readyKeys.iterator();
while (iterator.hasNext()) {
SelectionKey key = iterator.next();
iterator.remove();
if (key.isAcceptable()) {
// 有已经接受的新的到服务端的连接
SocketChannel socketChannel = server.accept();
// 有新的连接并不代表这个通道就有数据,
// 这里将这个新的 SocketChannel 注册到 Selector监听 OP_READ 事件,等待数据
socketChannel.configureBlocking(false);
socketChannel.register(selector, SelectionKey.OP_READ);
} else if (key.isReadable()) {
// 有数据可读
// 上面一个 if 分支中注册了监听 OP_READ 事件的 SocketChannel
SocketChannel socketChannel = (SocketChannel) key.channel();
ByteBuffer readBuffer = ByteBuffer.allocate(1024);
int num = socketChannel.read(readBuffer);
if (num > 0) {
// 处理进来的数据...
System.out.println("收到数据:" + new String(readBuffer.array()).trim());
ByteBuffer buffer = ByteBuffer.wrap("返回给客户端的数据...".getBytes());
socketChannel.write(buffer);
} else if (num == -1) {
// -1 代表连接已经关闭
socketChannel.close();
}
}
}
}
}
}

View File

@@ -1,91 +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.leetcode;
/**
* 反转链表
* 假设链表为 1 → 2 → 3 → null我们想要把它改成 null ← 1 ← 2 ← 3
*
* @author ehlxr
* @since 2021-02-27 21:08.
*/
public class Solution206 {
/*
方法一:迭代
https://leetcode-cn.com/problems/reverse-linked-list/solution/fan-zhuan-lian-biao-by-leetcode-solution-d1k2/
*/
public static ListNode reverseList1(ListNode head) {
ListNode prev = null;
while (head != null) {
// 先存储当前节点的下一个节点
ListNode next = head.next;
// 将当前节点的下一个节点改为前一个节点
head.next = prev;
// 指针后移
// 更改前一个节点为当前节点
prev = head;
// 更改当前节点为下一个节点
head = next;
}
return prev;
}
/*
方法一:递归
https://leetcode-cn.com/problems/reverse-linked-list/solution/shi-pin-jiang-jie-die-dai-he-di-gui-hen-hswxy/
*/
public static ListNode reverseList2(ListNode head) {
// 递归终止条件
if (head == null || head.next == null) {
return head;
}
ListNode h = reverseList2(head.next);
head.next.next = head;
// 防止链表循环
head.next = null;
return h;
}
public static void main(String[] args) {
ListNode n1 = new ListNode(1);
ListNode n2 = new ListNode(2);
ListNode n3 = new ListNode(3);
ListNode n4 = new ListNode(4);
n1.next = n2;
n2.next = n3;
n3.next = n4;
System.out.println(n1);
System.out.println(reverseList2(n1));
}
}

View File

@@ -1,126 +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.leetcode;
/**
* 4. 寻找两个正序数组的中位数
*
* @author ehlxr
* @since 2020-09-27 21:12.
*/
public class Solution4 {
/**
* 解法一
* 简单粗暴,先将两个数组合并,两个有序数组的合并也是归并排序中的一部分。然后根据奇数,还是偶数,返回中位数。
*/
public static double findMedianSortedArrays(int[] nums1, int[] nums2) {
int[] result = new int[nums1.length + nums2.length];
int x = 0, y = 0, z = 0;
while (x < nums1.length || y < nums2.length) {
if (x >= nums1.length) {
result[z] = nums2[y];
y++;
z++;
continue;
}
if (y >= nums2.length) {
result[z] = nums1[x];
x++;
z++;
continue;
}
if (nums1[x] < nums2[y]) {
result[z] = nums1[x];
x++;
} else {
result[z] = nums2[y];
y++;
}
z++;
}
int m = result.length / 2;
if (result.length % 2 == 0) {
return (result[m] + result[m - 1]) / 2.0;
} else {
return result[m];
}
}
/**
* 用 len 表示合并后数组的长度,
* 如果是奇数,我们需要知道第 len+1/2 个数就可以了,如果遍历的话需要遍历 int(len/2 ) + 1 次。
* 如果是偶数,我们需要知道第 len/2 和 len/2+1 个数,也是需要遍历 len/2+1 次。
*
* 所以遍历的话,奇数和偶数都是 len/2+1 次。
*
* https://leetcode-cn.com/problems/median-of-two-sorted-arrays/solution/xiang-xi-tong-su-de-si-lu-fen-xi-duo-jie-fa-by-w-2/
*/
public static double findMedianSortedArrays2(int[] nums1, int[] nums2) {
int l1 = nums1.length, l2 = nums2.length,
left = 0, right = 0,
len = l1 + l2,
x = 0, y = 0;
for (int i = 0; i < len/2 +1; i++) {
left = right;
if (x >= nums1.length) {
right = nums2[y];
y++;
continue;
}
if (y >= nums2.length) {
right = nums1[x];
x++;
continue;
}
if (nums1[x] < nums2[y]) {
right = nums1[x];
x++;
} else {
right = nums2[y];
y++;
}
}
if (len % 2 == 0) {
return (left + right) / 2.0;
} else {
return right;
}
}
public static void main(String[] args) {
System.out.println(findMedianSortedArrays(new int[]{}, new int[]{2, 3}));
System.out.println(findMedianSortedArrays2(new int[]{1, 4}, new int[]{2, 3}));
System.out.println(findMedianSortedArrays2(new int[]{3}, new int[]{1, 4, 6}));
}
}

View File

@@ -1,63 +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.leetcode;
import java.util.Arrays;
import java.util.PriorityQueue;
/**
* @author ehlxr
* @since 2020-10-20 17:54.
*/
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 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()));
}
}

View File

@@ -1,47 +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.lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* @author ehlxr
* @since 2021-02-15 18:11.
*/
public class Locker {
public static void main(String[] args) {
ReentrantLock lock = new ReentrantLock();
lock.lock(); // block until condition holds
try {
// ... method body
} finally {
lock.unlock();
}
}
}

View File

@@ -1,212 +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.pack;
import javax.swing.*;
import java.awt.*;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
public class FileUtil {
private static int sumError = 0;
private static int sumExistError = 0;
private static int sumNotFoundError = 0;
private static int sumSuccess = 0;
private static int sumNum = 1;
private static String getDate(Date date) {
SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return sd.format(date);
}
private static BufferedReader getBufferedReader(String path) throws FileNotFoundException {
return new BufferedReader(new InputStreamReader(new FileInputStream(path)));
}
public static void setInfo(String info, JFrame root) {
sumError += 1;
info.equals("");
Component[] components = root.getRootPane().getContentPane().getComponents();
for (int i = 0; i < components.length; i++) {
if (components[i].getClass().toString().equals("class javax.swing.JScrollPane")) {
JTextArea textarea = (JTextArea) ((JScrollPane) components[i]).getViewport().getView();
if (info.equals("")) {
sumError = 0;
sumExistError = 0;
sumNotFoundError = 0;
sumSuccess = 0;
sumNum = 1;
textarea.setText("");
} else if ((textarea.getText().equals("")) || (textarea.getText() == null)) {
textarea.setText(sumNum + ". " + info);
} else {
textarea.setText(textarea.getText() + "\n" + sumNum + ". " + info);
}
}
}
}
private static boolean copy(String from, String dirPath, JFrame root) {
boolean isCommon = true;
File fromFile = new File(from);
if (!fromFile.exists()) {
sumExistError += 1;
setInfo(from + "-------未找到!", root);
System.out.println(from + "---------------未找到!");
return false;
}
makeDirs(dirPath);
try {
File toFile = new File(dirPath + File.separatorChar + fromFile.getName());
if (toFile.exists()) {
sumNotFoundError += 1;
int k = checkFileVersion(fromFile, toFile);
if (k == -1) {
setInfo(fromFile.getAbsolutePath() + "--输出失败(已存在!)", root);
System.out.println(
"文件版本在目标版本之前,处理为不覆盖!若要处理请人工处理!\n原文件:" + fromFile.getAbsolutePath() + "\n目标文件:" + toFile.getAbsolutePath());
JOptionPane jp = new JOptionPane();
jp.setBounds(new Rectangle(new Point(400, 400)));
int isYes = JOptionPane.showConfirmDialog(root, "发现相同的文件,文件版本在目标版本之前!是否要进行覆盖?\n当前文件" +
fromFile.getAbsolutePath() + ",修改日期:" + getDate(new Date(fromFile.lastModified())) + "\n目标文件"
+ toFile.getAbsolutePath() + ",修改日期:" + getDate(new Date(toFile.lastModified())));
if (isYes == 0) {
isCommon = false;
System.out.println("您选择了是!");
} else {
return false;
}
}
if (k == 0) {
setInfo(fromFile.getAbsolutePath() + "--输出失败(已存在)", root);
System.out
.println("相同文件重复,处理为不覆盖!若要处理请人工处理!\n原文件:" + fromFile.getAbsolutePath() + "\n目标文件:" + toFile.getAbsolutePath());
return true;
}
if (k == 1) {
isCommon = false;
}
} else if (!toFile.exists()) {
toFile.createNewFile();
isCommon = false;
}
if (!isCommon) {
InputStream is = new FileInputStream(fromFile);
OutputStream out = new FileOutputStream(toFile);
byte[] b = new byte[1024];
int len = -1;
while ((len = is.read(b)) != -1) {
out.write(b, 0, len);
}
out.flush();
out.close();
is.close();
toFile.setLastModified(fromFile.lastModified());
sumSuccess += 1;
return true;
}
} catch (Exception e) {
System.out.println("Copy Error!");
}
return false;
}
private static void makeDirs(String path) {
File f = new File(path);
if (!f.exists()) {
f.mkdirs();
}
}
private static int checkFileVersion(File file1, File file2) {
long file1LastTime = file1.lastModified();
long file2LastTime = file2.lastModified();
if (file1LastTime > file2LastTime) {
return 1;
}
if (file1LastTime < file2LastTime) {
return -1;
}
return 0;
}
public static boolean becomePackage(String fileList, String cutStr, String dir, JFrame root) throws Exception {
dir = dir + "\\";
String filePath = null;
String addStr = null;
String fromFile = null;
String toFile = null;
boolean flag = false;
try {
BufferedReader br = getBufferedReader(fileList);
addStr = br.readLine();
addStr = addStr.trim();
setInfo("", root);
while ((filePath = br.readLine()) != null) {
sumNum += 1;
if (!"".equals(filePath.trim())) {
filePath = filePath.replaceAll("/", "\\\\");
System.out.println(filePath.replaceAll("\\\\", "/"));
if (filePath.startsWith(cutStr)) {
fromFile = filePath.trim();
toFile = dir + addStr + File.separatorChar + getCenter(cutStr, fromFile);
flag = copy(fromFile, toFile, root);
} else {
fromFile = cutStr + File.separatorChar + filePath.trim();
toFile = dir + addStr + File.separatorChar + filePath.substring(0, filePath.trim().lastIndexOf("\\"));
flag = copy(fromFile, toFile, root);
}
}
}
br.close();
setInfo("----成功:" + sumSuccess + "\n" + "----失败:" + sumError + "\n" + "--------未找到:" + sumNotFoundError + "\n" + "--------已存在:"
+ sumExistError, root);
return flag;
} catch (FileNotFoundException e) {
System.out.println("列表文件没有找到!");
throw new Exception("列表文件没有找到!");
} catch (IOException e) {
System.out.println("列表文件读取出错!");
throw new Exception("列表文件读取出错!");
}
}
private static String getCenter(String flag, String message) {
int k1 = message.trim().indexOf(flag);
int k2 = message.trim().lastIndexOf("\\");
if ((k1 != -1) && (k2 != -1)) {
return message.substring(flag.length() + 1, k2 + 1);
}
return null;
}
}

View File

@@ -1,284 +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.pack;
import javax.swing.*;
import javax.swing.filechooser.FileFilter;
import javax.swing.filechooser.FileSystemView;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
@SuppressWarnings("serial")
public class PackView extends JFrame {
private final JButton jb = new JButton();
private final JButton jb1 = new JButton();
private final JButton jb2 = new JButton();
private final JLabel jl0 = new JLabel();
private final JButton cancel = new JButton("退出");
private final JTextPane jText1 = new JTextPane();
private final JTextPane jText2 = new JTextPane();
public JTextArea jArea = new JTextArea();
public JScrollPane p = new JScrollPane(this.jArea);
private String inputPath = "D:\\wins-dsp";
private String outputPath = "C:\\Users\\ehlxr\\Desktop";
private PackView() {
setTitle("打包工具By:Henry");
setBounds(400, 400, 500, 300);
setLayout(null);
setResizable(false);
this.jb.setText("打包清单");
this.jb1.setText("打包根目录");
this.jb2.setText("输出目录");
this.jText1.setText(this.inputPath);
this.jText2.setText(this.outputPath);
this.jb.addMouseListener(new MouseListener() {
public void mouseReleased(MouseEvent e) {
if (PackView.this.packs()) {
PackView.this.jl0.setText("成功打包!");
PackView.this.jb.setText("...继续");
} else {
PackView.this.jl0.setText("打包失败!");
}
}
public void mousePressed(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseClicked(MouseEvent e) {
}
});
this.jb1.addMouseListener(new MouseListener() {
public void mouseReleased(MouseEvent e) {
PackView.this.choosePath(1);
PackView.this.jText1.setText(PackView.this.inputPath);
}
public void mousePressed(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseClicked(MouseEvent e) {
}
});
this.jb2.addMouseListener(new MouseListener() {
public void mouseReleased(MouseEvent e) {
PackView.this.choosePath(2);
PackView.this.jText2.setText(PackView.this.outputPath);
}
public void mousePressed(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseClicked(MouseEvent e) {
}
});
this.cancel.addMouseListener(new MouseListener() {
public void mouseReleased(MouseEvent e) {
PackView.this.close();
}
public void mousePressed(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseClicked(MouseEvent e) {
}
});
this.jb1.setBounds(10, 5, 100, 30);
this.jText1.setBounds(120, 5, 250, 30);
this.jb2.setBounds(10, 40, 100, 30);
this.jText2.setBounds(120, 40, 250, 30);
this.jb.setBounds(10, 100, 100, 30);
this.cancel.setBounds(120, 100, 100, 30);
this.jl0.setBounds(230, 100, 100, 30);
this.jArea.setLineWrap(true);
this.jArea.setForeground(Color.red);
this.jArea.setEditable(false);
this.p.setBounds(10, 130, 480, 130);
this.p.setVerticalScrollBarPolicy(22);
this.p.setHorizontalScrollBarPolicy(32);
add(this.jb1);
add(this.jText1);
add(this.jb2);
add(this.jText2);
add(this.jb);
add(this.cancel);
add(this.jl0);
add(this.p);
setVisible(true);
setDefaultCloseOperation(3);
}
public static void main(String[] args) {
new PackView();
}
private List<String> chooseFile(int chooseMode) {
try {
JFileChooser fileChooser = new JFileChooser();
fileChooser.setMultiSelectionEnabled(true);
fileChooser.setDialogTitle("文件打包");
fileChooser.setDragEnabled(true);
fileChooser.setAutoscrolls(true);
fileChooser.setFileFilter(new FileFilter() {
public boolean accept(File f) {
if (f.isDirectory()) {
return true;
}
return (f.getName().endsWith(".TXT")) || (f.getName().endsWith(".txt"));
}
public String getDescription() {
return ".txt";
}
});
fileChooser.setCurrentDirectory(FileSystemView.getFileSystemView().getHomeDirectory());
fileChooser.setOpaque(true);
fileChooser.setDoubleBuffered(true);
int returnVal = -1;
switch (chooseMode) {
case 1:
returnVal = fileChooser.showOpenDialog(this);
break;
case 2:
returnVal = fileChooser.showSaveDialog(this);
}
File[] fileName;
if (returnVal == 0) {
fileName = fileChooser.getSelectedFiles();
} else {
fileName = null;
}
List<String> list = new ArrayList<String>();
System.out.println("打包文件路径列表:");
String filePath = null;
for (int i = 0; i < fileName.length; i++) {
filePath = fileName[i].getAbsolutePath();
if (filePath.toUpperCase().endsWith("TXT")) {
list.add(filePath);
System.out.println("序号 " + i + " " + filePath);
} else {
System.out.println("序号 " + i + " " + filePath + " >>该文件不能作为打包文件! ");
}
}
return list;
} catch (Exception e) {
}
return null;
}
private boolean choosePath(int id) {
try {
JFileChooser fileChooser = new JFileChooser();
fileChooser.setMultiSelectionEnabled(true);
switch (id) {
case 1:
fileChooser.setDialogTitle("打包文件根目录");
fileChooser.setCurrentDirectory(new File(this.inputPath));
break;
case 2:
fileChooser.setDialogTitle("输出文件目录");
fileChooser.setCurrentDirectory(new File(this.outputPath));
}
fileChooser.setDragEnabled(true);
fileChooser.setAutoscrolls(true);
fileChooser.setAcceptAllFileFilterUsed(true);
fileChooser.setOpaque(true);
fileChooser.setDoubleBuffered(true);
fileChooser.setFileSelectionMode(1);
fileChooser.showOpenDialog(this);
switch (id) {
case 1:
this.inputPath = fileChooser.getSelectedFile().toString();
break;
case 2:
this.outputPath = fileChooser.getSelectedFile().toString();
}
return true;
} catch (Exception e) {
}
return false;
}
private void close() {
dispose();
}
private boolean packs() {
boolean flag = true;
List<String> fileName = chooseFile(1);
if ((fileName == null) || (fileName.size() <= 0)) {
System.out.println("打包原始文件没有找到");
flag = false;
} else {
for (int i = 0; i < fileName.size(); i++) {
try {
flag = FileUtil.becomePackage(fileName.get(i), this.inputPath, this.outputPath, this);
} catch (Exception e) {
return false;
}
}
}
return flag;
}
}

View File

@@ -1,45 +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.powermock;
/**
* Created by ehlxr on 2017/11/3.
*/
public class ClassDependency {
public static boolean isExist() {
// do something
return false;
}
public final boolean isAlive() {
// do something
return false;
}
public boolean isGod(String oh){
System.out.println(oh);
return false;
}
}

View File

@@ -1,86 +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.powermock;
/**
* Created by ehlxr on 2017/11/3.
*/
import java.io.File;
/**
* Created by ehlxr on 2017/7/21.
*/
public class ClassUnderTest {
private final String f1 = "test";
public boolean callArgumentInstance(File file) {
return file.exists();
}
public boolean callInternalInstance(String path) {
File file = new File(path);
return file.exists();
}
public boolean callFinalMethod(ClassDependency refer) {
return refer.isAlive();
}
public boolean callSystemFinalMethod(String str) {
return str.isEmpty();
}
public boolean callStaticMethod() {
return ClassDependency.isExist();
}
public String callSystemStaticMethod(String str) {
return System.getProperty(str);
}
public boolean callPrivateMethod() {
return isExist();
}
public boolean callVoidPrivateMethod() {
testVoid();
return true;
}
private boolean isExist() {
// do something
return false;
}
private void testVoid() {
System.out.println("do nothing");
}
public boolean callDependency() {
ClassDependency classDependency = new ClassDependency();
return classDependency.isGod("hh");
}
}

View File

@@ -1,139 +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.powermock;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.powermock.reflect.Whitebox;
import java.io.File;
import static org.mockito.ArgumentMatchers.anyString;
import static org.powermock.api.mockito.PowerMockito.*;
/**
* Created by ehlxr on 2017/7/21.
*/
@RunWith(PowerMockRunner.class)
public class TestClassUnderTest {
@Test
public void testCallArgumentInstance() {
File file = mock(File.class);
ClassUnderTest underTest = new ClassUnderTest();
PowerMockito.when(file.exists()).thenReturn(true);
Assert.assertTrue(underTest.callArgumentInstance(file));
}
@Test
@PrepareForTest(ClassUnderTest.class)
public void testCallInternalInstance() throws Exception {
File file = mock(File.class);
ClassUnderTest underTest = new ClassUnderTest();
PowerMockito.whenNew(File.class).withArguments("bbb").thenReturn(file);
PowerMockito.when(file.exists()).thenReturn(true);
Assert.assertTrue(underTest.callInternalInstance("bbb"));
}
@Test
@PrepareForTest(ClassDependency.class)
public void testCallFinalMethod() {
ClassDependency depencency = mock(ClassDependency.class);
ClassUnderTest underTest = new ClassUnderTest();
when(depencency.isAlive()).thenReturn(true);
Assert.assertTrue(underTest.callFinalMethod(depencency));
}
@Test
@PrepareForTest(ClassUnderTest.class)
public void testCallSystemFinalMethod() {
String str = mock(String.class);
ClassUnderTest underTest = new ClassUnderTest();
PowerMockito.when(str.isEmpty()).thenReturn(false);
Assert.assertFalse(underTest.callSystemFinalMethod(str));
}
@Test
@PrepareForTest(ClassDependency.class)
public void testCallStaticMethod() {
ClassUnderTest underTest = new ClassUnderTest();
PowerMockito.mockStatic(ClassDependency.class);
when(ClassDependency.isExist()).thenReturn(true);
Assert.assertTrue(underTest.callStaticMethod());
}
@Test
@PrepareForTest(ClassUnderTest.class)
public void testCallSystemStaticMethod() {
ClassUnderTest underTest = new ClassUnderTest();
PowerMockito.mockStatic(System.class);
PowerMockito.when(System.getProperty("aaa")).thenReturn("bbb");
Assert.assertEquals("bbb", underTest.callSystemStaticMethod("aaa"));
}
@Test
@PrepareForTest(ClassUnderTest.class)
public void testCallPrivateMethod() throws Exception {
ClassUnderTest underTest = mock(ClassUnderTest.class);
when(underTest.callPrivateMethod()).thenCallRealMethod();
when(underTest, "isExist").thenReturn(true);
Assert.assertTrue(underTest.callPrivateMethod());
}
@Test
@PrepareForTest(ClassUnderTest.class)
public void testCallVoidPrivateMethod() throws Exception {
ClassUnderTest underTest = mock(ClassUnderTest.class);
when(underTest.callVoidPrivateMethod()).thenCallRealMethod();
PowerMockito.doNothing().when(underTest, "testVoid");
Assert.assertTrue(underTest.callVoidPrivateMethod());
}
@Test
@PrepareForTest(ClassUnderTest.class)
public void testDependency() throws Exception {
ClassUnderTest underTest = new ClassUnderTest();
ClassDependency dependency = mock(ClassDependency.class);
// @PrepareForTest(ClassUnderTest.class)
whenNew(ClassDependency.class).withAnyArguments().thenReturn(dependency);
when(dependency.isGod(anyString())).thenReturn(true);
Assert.assertTrue(underTest.callDependency());
}
@Test
@PrepareForTest(ClassUnderTest.class)
public void testInvokPrivate() throws Exception {
ClassUnderTest underTest = PowerMockito.spy(new ClassUnderTest());
Whitebox.invokeMethod(underTest, "isExist");
verifyPrivate(underTest).invoke("isExist");
}
}

View File

@@ -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.proxy;
import java.util.Random;
/**
* @author ehlxr
* @since 2019-06-28.
*/
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();
}
}
// @Override
// public void run() {
// System.out.println("Bird is running...");
// }
}

View File

@@ -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.proxy;
/**
* @author ehlxr
* @since 2019-06-28.
*/
public interface Flyable {
void fly();
// void run();
}

View File

@@ -1,66 +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.proxy;
import java.lang.reflect.Proxy;
/**
* @author ehlxr
* @since 2019-06-28.
*/
public class Main {
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();
}
}
}
*/
proxy.fly();
}
}

View File

@@ -1,56 +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.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* @author ehlxr
* @since 2019-06-28.
*/
public class MyInvocationHandler implements InvocationHandler {
private final Bird bird;
public MyInvocationHandler(Bird bird) {
this.bird = bird;
}
@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;
}
}

View File

@@ -1,90 +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.queue;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;
/**
* 订单延迟队列
*
* @author ehlxr
* @since 2021-02-20 16:28.
*/
public class Order implements Delayed {
/**
* 延迟时间
*/
private long time;
String name;
public Order(String name, long time, TimeUnit unit) {
this.name = name;
this.time = System.currentTimeMillis() + (time > 0 ? unit.toMillis(time) : 0);
}
@Override
public long getDelay(TimeUnit unit) {
return time - System.currentTimeMillis();
}
@Override
public int compareTo(Delayed delayed) {
Order order = (Order) delayed;
long diff = this.time - order.time;
if (diff <= 0) {
return -1;
} else {
return 1;
}
}
public static void main(String[] args) throws InterruptedException {
Order order1 = new Order("Order1", 5, TimeUnit.SECONDS);
Order order2 = new Order("Order2", 10, TimeUnit.SECONDS);
Order order3 = new Order("Order3", 15, TimeUnit.SECONDS);
DelayQueue<Order> delayQueue = new DelayQueue<>();
delayQueue.put(order1);
delayQueue.put(order3);
delayQueue.put(order2);
System.out.println("订单延迟队列开始时间:" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
while (delayQueue.size() != 0) {
/*
* 取队列头部元素是否过期
*/
Order task = delayQueue.take(); // 阻塞
// Order task = delayQueue.poll(); // 非阻塞
// if (task != null) {
System.out.format("订单:{%s}被取消, 取消时间:{%s}\n", task.name, LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
// }
// TimeUnit.SECONDS.sleep(1);
}
}
}

View File

@@ -1,56 +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.rabbitmq;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
* @author ehlxr
* @since 2019-01-22.
*/
public class ConnectionUtil {
public static Connection getConnection() throws IOException, TimeoutException {
// 连接工厂
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
// 连接 5672 端口;注意 15672 为工具界面端口25672 为集群端口
factory.setPort(5672);
/*
* 当我们在创建用户时,会指定用户能访问一个虚拟机,并且该用户只能访问该虚拟机下的队列和交换机,如果没有指定,默认的是”/”;
* 一个 rabbitmq 服务器上可以运行多个 vhost以便于适用不同的业务需要
* 这样做既可以满足权限配置的要求,也可以避免不同业务之间队列、交换机的命名冲突问题,因为不同 vhost 之间是隔离的。
*/
factory.setVirtualHost("/tdd");
factory.setUsername("ehlxr");
factory.setPassword("123456");
//获取连接
return factory.newConnection();
}
}

View File

@@ -1,70 +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.rabbitmq.routing;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.QueueingConsumer;
import io.github.ehlxr.rabbitmq.ConnectionUtil;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
* 发送消息到交换机并且要指定路由 key ,消费者将队列绑定到交换机时需要指定路由 key
*
* @author ehlxr
* @since 2019-01-22.
*/
public class Receiver1 {
private final static String QUEUE_NAME = "queue_routing";
private final static String EXCHANGE_NAME = "exchange_direct";
public static void main(String[] args) throws IOException, InterruptedException, TimeoutException {
// 获取到连接以及mq通道
Connection connection = ConnectionUtil.getConnection();
Channel channel = connection.createChannel();
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "key");
channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "key2");
channel.basicQos(1);
QueueingConsumer consumer = new QueueingConsumer(channel);
channel.basicConsume(QUEUE_NAME, false, consumer);
while (true) {
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String message = new String(delivery.getBody());
System.out.println("[x] Received1 " + message);
Thread.sleep(10);
channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
}
}
}

View File

@@ -1,69 +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.rabbitmq.routing;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.QueueingConsumer;
import io.github.ehlxr.rabbitmq.ConnectionUtil;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
* 发送消息到交换机并且要指定路由 key ,消费者将队列绑定到交换机时需要指定路由 key
*
* @author ehlxr
* @since 2019-01-22.
*/
public class Receiver2 {
private final static String QUEUE_NAME = "queue_routing2";
private final static String EXCHANGE_NAME = "exchange_direct";
public static void main(String[] args) throws IOException, InterruptedException, TimeoutException {
// 获取到连接以及mq通道
Connection connection = ConnectionUtil.getConnection();
Channel channel = connection.createChannel();
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "key2");
channel.basicQos(1);
QueueingConsumer consumer = new QueueingConsumer(channel);
channel.basicConsume(QUEUE_NAME, false, consumer);
while (true) {
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String message = new String(delivery.getBody());
System.out.println("[x] Received2 " + message);
Thread.sleep(10);
channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
}
}
}

View File

@@ -1,57 +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.rabbitmq.routing;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import io.github.ehlxr.rabbitmq.ConnectionUtil;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
* 发送消息到交换机并且要指定路由 key ,消费者将队列绑定到交换机时需要指定路由 key
*
* @author ehlxr
* @since 2019-01-22.
*/
public class Sender {
private final static String EXCHANGE_NAME = "exchange_direct";
private final static String EXCHANGE_TYPE = "direct";
public static void main(String[] args) throws IOException, TimeoutException {
Connection connection = ConnectionUtil.getConnection();
Channel channel = connection.createChannel();
channel.exchangeDeclare(EXCHANGE_NAME, EXCHANGE_TYPE);
String message = "那一定是蓝色";
channel.basicPublish(EXCHANGE_NAME, "key2", null, message.getBytes());
System.out.println("[x] Sent '" + message + "'");
channel.close();
connection.close();
}
}

View File

@@ -1,62 +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.rabbitmq.simple;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.QueueingConsumer;
import io.github.ehlxr.rabbitmq.ConnectionUtil;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
* 简单模式:一个生产者,一个消费者
*
* @author ehlxr
* @since 2019-01-22.
*/
public class Receiver {
private final static String QUEUE_NAME = "simple_queue";
public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
//获取连接
Connection connection = ConnectionUtil.getConnection();
//获取通道
Channel channel = connection.createChannel();
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
QueueingConsumer consumer = new QueueingConsumer(channel);
channel.basicConsume(QUEUE_NAME, true, consumer);
while (true) {
//该方法会阻塞
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String message = new String(delivery.getBody());
System.out.println("[x] Received '" + message + "'");
}
}
}

View File

@@ -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.rabbitmq.simple;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import io.github.ehlxr.rabbitmq.ConnectionUtil;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
* 简单模式:一个生产者,一个消费者
*
* @author ehlxr
* @since 2019-01-22.
*/
public class Sender {
private final static String QUEUE_NAME = "simple_queue";
public static void main(String[] args) throws IOException, TimeoutException {
//创建连接
Connection connection = ConnectionUtil.getConnection();
//创建通道
Channel channel = connection.createChannel();
/*
* 声明队列
* 1. 队列名
* 2. 是否持久化
* 3. 是否排外即只允许该channel访问该队列 一般等于true的话用于一个队列只能有一个消费者来消费的场景
* 4. 是否自动删除(消费完删除)
* 6. 其他属性
*
*/
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
/*
* 消息内容
* 1. 交换机
* 2. 队列名
* 3. 其他属性(路由)
* 4. 消息body
*/
String message = "错的不是我,是这个世界~";
channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
System.out.println("[x]Sent '" + message + "'");
//最后关闭通关和连接
channel.close();
connection.close();
}
}

Some files were not shown because too many files have changed in this diff Show More