Files
redkale/src/main/java/org/redkale/util/Utility.java
2024-09-23 17:49:48 +08:00

6041 lines
240 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.util;
import java.io.*;
import java.lang.invoke.*;
import java.lang.reflect.*;
import java.math.*;
import java.net.*;
import java.net.http.HttpClient;
import java.nio.*;
import java.nio.channels.CompletionHandler;
import java.nio.charset.*;
import static java.nio.charset.StandardCharsets.UTF_8;
import java.security.*;
import java.time.*;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.*;
import java.util.stream.Stream;
import java.util.zip.GZIPInputStream;
import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import org.redkale.annotation.ClassDepends;
import org.redkale.annotation.Priority;
import org.redkale.convert.json.JsonConvert;
/**
* 常见操作的工具类
*
* <p>详情见: https://redkale.org
*
* @author zhangjx
*/
public final class Utility {
private static final char hex[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
private static final int CPUS =
Integer.getInteger("redkale.cpus", Runtime.getRuntime().availableProcessors());
private static final int MAX_POW2 = 1 << 30;
private static final ConcurrentHashMap<Class, String> lambdaFieldNameCache = new ConcurrentHashMap();
private static final ConcurrentHashMap<Class, Class> lambdaClassNameCache = new ConcurrentHashMap();
private static final Class JAVA_RECORD_CLASS;
private static final SecureRandom random = new SecureRandom();
private static final IntFunction<CompletableFuture[]> futureArrayFunc = c -> new CompletableFuture[c];
private static final IntFunction<Serializable[]> serialArrayFunc = v -> new Serializable[v];
static {
Class clz = null;
try {
clz = Thread.currentThread().getContextClassLoader().loadClass("java.lang.Record");
} catch (Throwable t) { // JDK14以下版本会异常
}
JAVA_RECORD_CLASS = clz;
}
private static final Executor defaultExecutorConsumer = new Executor() {
@Override
public void execute(Runnable command) {
command.run();
}
};
// org.redkale.util.AnonymousThreadLocal
private static final String functionThreadLocalBinary =
"cafebabe0000004100480a000200030700040c000500060100156a6176612f6c616e672f5468726561644c6f63616c0100063c696e69743e010003282956090008000907000a0c000b000c0100256f72672f7265646b616c652f7574696c2f416e6f6e796d6f75735468726561644c6f63616c010008737570706c69657201001d4c6a6176612f7574696c2f66756e6374696f6e2f537570706c6965723b0a0008000e0c0005000f010020284c6a6176612f7574696c2f66756e6374696f6e2f537570706c6965723b29560b001100120700130c0014001501001b6a6176612f7574696c2f66756e6374696f6e2f537570706c69657201000367657401001428294c6a6176612f6c616e672f4f626a6563743b0a001700180700190c001a001b0100106a6176612f6c616e672f54687265616401000d63757272656e7454687265616401001428294c6a6176612f6c616e672f5468726561643b0a0017001d0c001e001f01000969735669727475616c01000328295a0a000200210c00220023010003736574010015284c6a6176612f6c616e672f4f626a6563743b29560a000800250c0026001501000c696e697469616c56616c75650a000200120a000800290c002a002b0100056170706c79010036284c6a6176612f7574696c2f66756e6374696f6e2f537570706c6965723b294c6a6176612f6c616e672f5468726561644c6f63616c3b07002d01001b6a6176612f7574696c2f66756e6374696f6e2f46756e6374696f6e0100095369676e61747572650100224c6a6176612f7574696c2f66756e6374696f6e2f537570706c6965723c54543b3e3b010004436f646501000f4c696e654e756d6265725461626c650100124c6f63616c5661726961626c655461626c65010004746869730100274c6f72672f7265646b616c652f7574696c2f416e6f6e796d6f75735468726561644c6f63616c3b0100164c6f63616c5661726961626c65547970655461626c6501002c4c6f72672f7265646b616c652f7574696c2f416e6f6e796d6f75735468726561644c6f63616c3c54543b3e3b0100104d6574686f64506172616d6574657273010025284c6a6176612f7574696c2f66756e6374696f6e2f537570706c6965723c54543b3e3b2956010040284c6a6176612f7574696c2f66756e6374696f6e2f537570706c6965723c54543b3e3b294c6a6176612f6c616e672f5468726561644c6f63616c3c54543b3e3b010005282954543b01000576616c75650100124c6a6176612f6c616e672f4f626a6563743b010001740100124c6a6176612f6c616e672f5468726561643b01000354543b01000d537461636b4d61705461626c650100062854543b29560700430100106a6176612f6c616e672f4f626a656374010026284c6a6176612f6c616e672f4f626a6563743b294c6a6176612f6c616e672f4f626a6563743b01008f3c543a4c6a6176612f6c616e672f4f626a6563743b3e4c6a6176612f6c616e672f5468726561644c6f63616c3c54543b3e3b4c6a6176612f7574696c2f66756e6374696f6e2f46756e6374696f6e3c4c6a6176612f7574696c2f66756e6374696f6e2f537570706c6965723c54543b3e3b4c6a6176612f6c616e672f5468726561644c6f63616c3c54543b3e3b3e3b01000a536f7572636546696c65010019416e6f6e796d6f75735468726561644c6f63616c2e6a6176610021000800020001002c00010012000b000c0001002e00000002002f000600010005000f0003003000000062000200020000000a2ab700012a2bb50007b10000000300310000000e000300000016000400170009001800320000001600020000000a0033003400000000000a000b000c000100350000001600020000000a0033003600000000000a000b002f000100370000000501000b0000002e0000000200380001002a002b00030030000000590003000200000009bb0008592bb7000db00000000300310000000600010000001b00320000001600020000000900330034000000000009000b000c000100350000001600020000000900330036000000000009000b002f000100370000000501000b0000002e0000000200390004002600150002003000000046000100010000000a2ab40007b900100100b00000000300310000000600010000002000320000000c00010000000a00330034000000350000000c00010000000a003300360000002e00000002003a00010022002300030030000000850002000300000011b800164d2cb6001c9a00082a2bb70020b10000000400310000001200040000002500040026000b00270010002900320000002000030000001100330034000000000011003b003c00010004000d003d003e000200350000001600020000001100330036000000000011003b003f00010040000000080001fc001007001700370000000501003b0000002e00000002004100010014001500020030000000730001000200000017b800164c2bb6001c99000a2ab60024a700072ab70027b00000000400310000000a00020000002d0004002e00320000001600020000001700330034000000040013003d003e000100350000000c00010000001700330036000000400000000c0002fc001207001743070042002e00000002003a1041002a0044000200300000004500020002000000092a2bc00011b60028b00000000300310000000600010000001200320000000c00010000000900330034000000350000000c00010000000900330036000000370000000501000b10000002002e0000000200450046000000020047";
private static final Function<Supplier, ThreadLocal> virtualThreadLocalFunction;
// org.redkale.util.AnonymousThreadFactory
private static final String functionThreadFactoryBinary =
"cafebabe0000004100450a000200030700040c000500060100106a6176612f6c616e672f4f626a6563740100063c696e69743e0100032829560a0008000907000a0c000b000c0100106a6176612f6c616e672f5468726561640100096f665669727475616c01002628294c6a6176612f6c616e672f546872656164244275696c646572244f665669727475616c3b0b000e000f0700100c001100120100226a6176612f6c616e672f546872656164244275696c646572244f665669727475616c010007666163746f727901002628294c6a6176612f7574696c2f636f6e63757272656e742f546872656164466163746f72793b09001400150700160c001100170100276f72672f7265646b616c652f7574696c2f416e6f6e796d6f7573546872656164466163746f72790100244c6a6176612f7574696c2f636f6e63757272656e742f546872656164466163746f72793b09001400190c001a001b0100046e616d650100124c6a6176612f6c616e672f537472696e673b0a0014001d0c0005001e010015284c6a6176612f6c616e672f537472696e673b29560b002000210700220c002300240100226a6176612f7574696c2f636f6e63757272656e742f546872656164466163746f72790100096e6577546872656164010028284c6a6176612f6c616e672f52756e6e61626c653b294c6a6176612f6c616e672f5468726561643b0a000800260c0027001e0100077365744e616d650700290100106a6176612f6c616e672f537472696e670a0014002b0c002c002d0100056170706c79010038284c6a6176612f6c616e672f537472696e673b294c6a6176612f7574696c2f636f6e63757272656e742f546872656164466163746f72793b07002f01001b6a6176612f7574696c2f66756e6374696f6e2f46756e6374696f6e010004436f646501000f4c696e654e756d6265725461626c650100124c6f63616c5661726961626c655461626c65010004746869730100294c6f72672f7265646b616c652f7574696c2f416e6f6e796d6f7573546872656164466163746f72793b0100104d6574686f64506172616d6574657273010001720100144c6a6176612f6c616e672f52756e6e61626c653b010001740100124c6a6176612f6c616e672f5468726561643b01000d537461636b4d61705461626c65010026284c6a6176612f6c616e672f4f626a6563743b294c6a6176612f6c616e672f4f626a6563743b0100095369676e617475726501008b4c6a6176612f6c616e672f4f626a6563743b4c6a6176612f7574696c2f636f6e63757272656e742f546872656164466163746f72793b4c6a6176612f7574696c2f66756e6374696f6e2f46756e6374696f6e3c4c6a6176612f6c616e672f537472696e673b4c6a6176612f7574696c2f636f6e63757272656e742f546872656164466163746f72793b3e3b01000a536f7572636546696c6501001b416e6f6e796d6f7573546872656164466163746f72792e6a61766101000c496e6e6572436c61737365730700420100186a6176612f6c616e672f546872656164244275696c6465720100074275696c6465720100094f665669727475616c00210014000200020020002e000200120011001700000012001a001b0000000400010005001e000200300000005600020002000000162ab700012ab80007b9000d0100b500132a2bb50018b10000000200310000001200040000001500040011001000160015001700320000001600020000001600330034000000000016001a001b000100350000000501001a00000001002c002d000200300000003d0003000200000009bb0014592bb7001cb00000000200310000000600010000001b00320000001600020000000900330034000000000009001a001b000100350000000501001a00000001002300240002003000000074000200030000001c2ab400132bb9001f02004d2ab40018c6000b2c2ab40018b600252cb000000003003100000012000400000020000b002100120022001a002400320000002000030000001c0033003400000000001c003600370001000b0011003800390002003a000000080001fc001a07000800350000000501003600001041002c003b000200300000003300020002000000092a2bc00028b6002ab00000000200310000000600010000000f00320000000c00010000000900330034000000350000000501001a10000003003c00000002003d003e00000002003f00400000001200020041000800430609000e004100440609";
private static final Function<String, ThreadFactory> virtualThreadFactoryFunction;
// org.redkale.util.AnonymousVirtualPoolFunction
private static final String functionVirtualPoolBinary =
"cafebabe0000004100610a000200030700040c000500060100106a6176612f6c616e672f4f626a6563740100063c696e69743e0100032829560a0008000907000a0c000b000c0100106a6176612f6c616e672f5468726561640100096f665669727475616c01002628294c6a6176612f6c616e672f546872656164244275696c646572244f665669727475616c3b0b000e000f0700100c001100120100226a6176612f6c616e672f546872656164244275696c646572244f665669727475616c010007666163746f727901002628294c6a6176612f7574696c2f636f6e63757272656e742f546872656164466163746f72793b0800140100075669727475616c0a001600170700180c0019001a0100106a6176612f6c616e672f537472696e67010006666f726d6174010039284c6a6176612f6c616e672f537472696e673b5b4c6a6176612f6c616e672f4f626a6563743b294c6a6176612f6c616e672f537472696e673b120000001c0c001d001e0100096e657754687265616401005c284c6a6176612f7574696c2f636f6e63757272656e742f546872656164466163746f72793b4c6a6176612f6c616e672f537472696e673b294c6a6176612f7574696c2f636f6e63757272656e742f546872656164466163746f72793b0a002000210700220c0023002401001e6a6176612f7574696c2f636f6e63757272656e742f4578656375746f72730100186e65775468726561645065725461736b4578656375746f7201004c284c6a6176612f7574696c2f636f6e63757272656e742f546872656164466163746f72793b294c6a6176612f7574696c2f636f6e63757272656e742f4578656375746f72536572766963653b0a002600270700280c0029002a01002d6f72672f7265646b616c652f7574696c2f416e6f6e796d6f75735669727475616c506f6f6c46756e6374696f6e0100056170706c7901003a284c6a6176612f6c616e672f537472696e673b294c6a6176612f7574696c2f636f6e63757272656e742f4578656375746f72536572766963653b0b002c002d07002e0c001d002f0100226a6176612f7574696c2f636f6e63757272656e742f546872656164466163746f7279010028284c6a6176612f6c616e672f52756e6e61626c653b294c6a6176612f6c616e672f5468726561643b0a000800310c003200330100077365744e616d65010015284c6a6176612f6c616e672f537472696e673b295607003501001b6a6176612f7574696c2f66756e6374696f6e2f46756e6374696f6e010004436f646501000f4c696e654e756d6265725461626c650100124c6f63616c5661726961626c655461626c650100047468697301002f4c6f72672f7265646b616c652f7574696c2f416e6f6e796d6f75735669727475616c506f6f6c46756e6374696f6e3b0100107468726561644e616d65466f726d61740100124c6a6176612f6c616e672f537472696e673b0100244c6a6176612f7574696c2f636f6e63757272656e742f546872656164466163746f72793b01000a7468726561644e616d650100104d6574686f64506172616d6574657273010026284c6a6176612f6c616e672f4f626a6563743b294c6a6176612f6c616e672f4f626a6563743b01000e6c616d626461246170706c79243001005e284c6a6176612f7574696c2f636f6e63757272656e742f546872656164466163746f72793b4c6a6176612f6c616e672f537472696e673b4c6a6176612f6c616e672f52756e6e61626c653b294c6a6176612f6c616e672f5468726561643b010001720100144c6a6176612f6c616e672f52756e6e61626c653b010001740100124c6a6176612f6c616e672f5468726561643b0100095369676e61747572650100694c6a6176612f6c616e672f4f626a6563743b4c6a6176612f7574696c2f66756e6374696f6e2f46756e6374696f6e3c4c6a6176612f6c616e672f537472696e673b4c6a6176612f7574696c2f636f6e63757272656e742f4578656375746f72536572766963653b3e3b01000a536f7572636546696c65010021416e6f6e796d6f75735669727475616c506f6f6c46756e6374696f6e2e6a617661010010426f6f7473747261704d6574686f647310002f0f06004e0a0026004f0c004100420f0600510a005200530700540c005500560100226a6176612f6c616e672f696e766f6b652f4c616d6264614d657461666163746f727901000b6d657461666163746f72790100cc284c6a6176612f6c616e672f696e766f6b652f4d6574686f6448616e646c6573244c6f6f6b75703b4c6a6176612f6c616e672f537472696e673b4c6a6176612f6c616e672f696e766f6b652f4d6574686f64547970653b4c6a6176612f6c616e672f696e766f6b652f4d6574686f64547970653b4c6a6176612f6c616e672f696e766f6b652f4d6574686f6448616e646c653b4c6a6176612f6c616e672f696e766f6b652f4d6574686f64547970653b294c6a6176612f6c616e672f696e766f6b652f43616c6c536974653b01000c496e6e6572436c61737365730700590100186a6176612f6c616e672f546872656164244275696c6465720100074275696c6465720100094f665669727475616c07005d0100256a6176612f6c616e672f696e766f6b652f4d6574686f6448616e646c6573244c6f6f6b757007005f01001e6a6176612f6c616e672f696e766f6b652f4d6574686f6448616e646c65730100064c6f6f6b75700021002600020001003400000004000100050006000100360000002f00010001000000052ab70001b10000000200370000000600010000000f00380000000c0001000000050039003a000000010029002a00020036000000720005000400000022b80007b9000d01004d2b04bd00025903121353b800154e2c2dba001b0000b8001fb00000000200370000000e000300000013000900140017001500380000002a0004000000220039003a000000000022003b003c0001000900190011003d00020017000b003e003c0003003f0000000501003b0000104100290040000200360000003300020002000000092a2bc00016b60025b00000000200370000000600010000000f00380000000c0001000000090039003a0000003f0000000501003b1000100a00410042000100360000005f000200040000000f2a2cb9002b02004e2d2bb600302db00000000200370000000e00030000001600080017000d001800380000002a00040000000f0011003d00000000000f003e003c00010000000f0043004400020008000700450046000300040047000000020048004900000002004a004b0000000c000100500003004c004d004c00570000001a000300580008005a0609000e0058005b0609005c005e00600019";
private static final Function<String, ExecutorService> virtualPoolFunction;
// org.redkale.util.AnonymousVirtualExecutor
private static final String consumerVirtualExecutorBinary =
"cafebabe00000041002e0a000200030700040c000500060100106a6176612f6c616e672f4f626a6563740100063c696e69743e0100032829560a0008000907000a0c000b000c0100106a6176612f6c616e672f5468726561640100096f665669727475616c01002628294c6a6176612f6c616e672f546872656164244275696c646572244f665669727475616c3b08000e0100155265646b616c652d5669727475616c5468726561640b001000110700120c001300140100226a6176612f6c616e672f546872656164244275696c646572244f665669727475616c0100046e616d65010038284c6a6176612f6c616e672f537472696e673b294c6a6176612f6c616e672f546872656164244275696c646572244f665669727475616c3b0b001000160c001700180100057374617274010028284c6a6176612f6c616e672f52756e6e61626c653b294c6a6176612f6c616e672f5468726561643b07001a0100296f72672f7265646b616c652f7574696c2f416e6f6e796d6f75735669727475616c4578656375746f7207001c01001d6a6176612f7574696c2f636f6e63757272656e742f4578656375746f72010004436f646501000f4c696e654e756d6265725461626c650100124c6f63616c5661726961626c655461626c650100047468697301002b4c6f72672f7265646b616c652f7574696c2f416e6f6e796d6f75735669727475616c4578656375746f723b01000765786563757465010017284c6a6176612f6c616e672f52756e6e61626c653b2956010001740100144c6a6176612f6c616e672f52756e6e61626c653b0100104d6574686f64506172616d657465727301000a536f7572636546696c6501001d416e6f6e796d6f75735669727475616c4578656375746f722e6a61766101000c496e6e6572436c617373657307002b0100186a6176612f6c616e672f546872656164244275696c6465720100074275696c6465720100094f665669727475616c0021001900020001001b000000020001000500060001001d0000002f00010001000000052ab70001b100000002001e0000000600010000000e001f0000000c0001000000050020002100000001002200230002001d0000004a0002000200000012b80007120db9000f02002bb90015020057b100000002001e0000000a00020000001200110013001f00000016000200000012002000210000000000120024002500010026000000050100240000000200270000000200280029000000120002002a0008002c06090010002a002d0609";
private static final Executor virtualExecutorConsumer;
// org.redkale.util.SignalShutDown
private static final String consumerSignalShutdownBinary =
"cafebabe00000037006b0a0019003a090018003b07003c08003d08003e08003f0800400800410800420800430800440800450700460a000d00470a000d004807004907004a0a000d004b0a000d004c12000000500b001600510700520a0018005307005407005507005601001073687574646f776e436f6e73756d657201001d4c6a6176612f7574696c2f66756e6374696f6e2f436f6e73756d65723b0100095369676e61747572650100314c6a6176612f7574696c2f66756e6374696f6e2f436f6e73756d65723c4c6a6176612f6c616e672f537472696e673b3e3b0100063c696e69743e010003282956010004436f646501000f4c696e654e756d6265725461626c650100124c6f63616c5661726961626c655461626c65010004746869730100214c6f72672f7265646b616c652f7574696c2f5369676e616c53687574446f776e3b010006616363657074010020284c6a6176612f7574696c2f66756e6374696f6e2f436f6e73756d65723b29560100037369670100124c6a6176612f6c616e672f537472696e673b010004736967730100135b4c6a6176612f6c616e672f537472696e673b010008636f6e73756d65720100164c6f63616c5661726961626c65547970655461626c6501000d537461636b4d61705461626c6507002b0100104d6574686f64506172616d6574657273010034284c6a6176612f7574696c2f66756e6374696f6e2f436f6e73756d65723c4c6a6176612f6c616e672f537472696e673b3e3b295601000668616e646c65010014284c73756e2f6d6973632f5369676e616c3b29560100114c73756e2f6d6973632f5369676e616c3b010006736967737472010015284c6a6176612f6c616e672f4f626a6563743b295601007a4c6a6176612f6c616e672f4f626a6563743b4c6a6176612f7574696c2f66756e6374696f6e2f436f6e73756d65723c4c6a6176612f7574696c2f66756e6374696f6e2f436f6e73756d65723c4c6a6176612f6c616e672f537472696e673b3e3b3e3b4c73756e2f6d6973632f5369676e616c48616e646c65723b01000a536f7572636546696c650100135369676e616c53687574446f776e2e6a6176610c001f00200c001b001c0100106a6176612f6c616e672f537472696e670100034855500100045445524d010003494e54010004515549540100044b494c4c01000454535450010004555352310100045553523201000453544f5001000f73756e2f6d6973632f5369676e616c0c001f00570c003200580100136a6176612f6c616e672f457863657074696f6e0100136a6176612f6c616e672f5468726f7761626c650c0059005a0c005b005c010010426f6f7473747261704d6574686f64730f06005d08005e0c005f00600c0026003601001b6a6176612f7574696c2f66756e6374696f6e2f436f6e73756d65720c0026002701001f6f72672f7265646b616c652f7574696c2f5369676e616c53687574446f776e0100106a6176612f6c616e672f4f626a65637401001673756e2f6d6973632f5369676e616c48616e646c6572010015284c6a6176612f6c616e672f537472696e673b2956010043284c73756e2f6d6973632f5369676e616c3b4c73756e2f6d6973632f5369676e616c48616e646c65723b294c73756e2f6d6973632f5369676e616c48616e646c65723b0100076765744e616d6501001428294c6a6176612f6c616e672f537472696e673b0100096765744e756d6265720100032829490a00610062010005012c012c010100176d616b65436f6e63617457697468436f6e7374616e7473010038284c73756e2f6d6973632f5369676e616c3b4c6a6176612f6c616e672f537472696e673b49294c6a6176612f6c616e672f537472696e673b0700630c005f00670100246a6176612f6c616e672f696e766f6b652f537472696e67436f6e636174466163746f72790700690100064c6f6f6b757001000c496e6e6572436c6173736573010098284c6a6176612f6c616e672f696e766f6b652f4d6574686f6448616e646c6573244c6f6f6b75703b4c6a6176612f6c616e672f537472696e673b4c6a6176612f6c616e672f696e766f6b652f4d6574686f64547970653b4c6a6176612f6c616e672f537472696e673b5b4c6a6176612f6c616e672f4f626a6563743b294c6a6176612f6c616e672f696e766f6b652f43616c6c536974653b07006a0100256a6176612f6c616e672f696e766f6b652f4d6574686f6448616e646c6573244c6f6f6b757001001e6a6176612f6c616e672f696e766f6b652f4d6574686f6448616e646c657300210018001900020016001a00010002001b001c0001001d00000002001e00040001001f0020000100210000002f00010001000000052ab70001b10000000200220000000600010000000c00230000000c000100000005002400250000000100260027000300210000014a000400080000006f2a2bb500021009bd0003590312045359041205535905120653590612075359071208535908120953591006120a53591007120b53591008120c534d2c4e2dbe360403360515051504a200222d1505323a06bb000d591906b7000e2ab8000f57a700053a07840501a7ffdda700044db100020051005f006200100005006a006d0011000400220000002a000a0000001200050014003b001500510017005f00190062001800640015006a001c006d001b006e001d00230000002a000400510013002800290006003b002f002a002b00020000006f0024002500000000006f002c001c0001002d0000000c00010000006f002c001e0001002e000000470006ff0044000607001807001607002f07002f01010000ff001d000707001807001607002f07002f01010700030001070010fa0001ff000500020700180700160000420700110000300000000501002c0000001d0000000200310021003200330002002100000060000300030000001a2b2bb600122bb60013ba001400004d2ab400022cb900150200b10000000200220000000e000300000021000f00220019002300230000002000030000001a0024002500000000001a002800340001000f000b0035002900020030000000050100280000104100260036000200210000003300020002000000092a2bc00016b60017b10000000200220000000600010000000c00230000000c00010000000900240025000000300000000501002c10000004001d000000020037003800000002003900660000000a00010064006800650019004d000000080001004e0001004f";
private static final Consumer<Consumer<String>> signalShutdownConsumer;
// org.redkale.util.AnonymousUnsafe
private static final String funcAnonymousUnsafeBinary =
"cafebabe0000003701710a000200030700040c000500060100106a6176612f6c616e672f4f626a6563740100063c696e69743e01000328295607000801000f73756e2f6d6973632f556e7361666509000a000b07000c0c000d000e0100206f72672f7265646b616c652f7574696c2f416e6f6e796d6f7573556e73616665010006756e736166650100114c73756e2f6d6973632f556e736166653b0a000700100c00110012010006676574496e74010016284c6a6176612f6c616e672f4f626a6563743b4a29490a000700140c00150016010006707574496e74010017284c6a6176612f6c616e672f4f626a6563743b4a4929560a000700180c0019001a0100096765744f626a656374010027284c6a6176612f6c616e672f4f626a6563743b4a294c6a6176612f6c616e672f4f626a6563743b0a0007001c0c001d001e0100097075744f626a656374010028284c6a6176612f6c616e672f4f626a6563743b4a4c6a6176612f6c616e672f4f626a6563743b29560a000700200c0021002201000a676574426f6f6c65616e010016284c6a6176612f6c616e672f4f626a6563743b4a295a0a000700240c0025002601000a707574426f6f6c65616e010017284c6a6176612f6c616e672f4f626a6563743b4a5a29560a000700280c0029002a01000767657442797465010016284c6a6176612f6c616e672f4f626a6563743b4a29420a0007002c0c002d002e01000770757442797465010017284c6a6176612f6c616e672f4f626a6563743b4a4229560a000700300c0031003201000867657453686f7274010016284c6a6176612f6c616e672f4f626a6563743b4a29530a000700340c0035003601000870757453686f7274010017284c6a6176612f6c616e672f4f626a6563743b4a5329560a000700380c0039003a01000767657443686172010016284c6a6176612f6c616e672f4f626a6563743b4a29430a0007003c0c003d003e01000770757443686172010017284c6a6176612f6c616e672f4f626a6563743b4a4329560a000700400c004100420100076765744c6f6e67010016284c6a6176612f6c616e672f4f626a6563743b4a294a0a000700440c004500460100077075744c6f6e67010017284c6a6176612f6c616e672f4f626a6563743b4a4a29560a000700480c0049004a010008676574466c6f6174010016284c6a6176612f6c616e672f4f626a6563743b4a29460a0007004c0c004d004e010008707574466c6f6174010017284c6a6176612f6c616e672f4f626a6563743b4a4629560a000700500c00510052010009676574446f75626c65010016284c6a6176612f6c616e672f4f626a6563743b4a29440a000700540c00550056010009707574446f75626c65010017284c6a6176612f6c616e672f4f626a6563743b4a4429560a000700580c00290059010004284a29420a0007005b0c002d005c010005284a4229560a0007005e0c0031005f010004284a29530a000700610c00350062010005284a5329560a000700640c00390065010004284a29430a000700670c003d0068010005284a4329560a0007006a0c0011006b010004284a29490a0007006d0c0015006e010005284a4929560a000700700c00410071010004284a294a0a000700730c00450074010005284a4a29560a000700760c00490077010004284a29460a000700790c004d007a010005284a4629560a0007007c0c0051007d010004284a29440a0007007f0c00550080010005284a4429560a000700820c0083007101000a676574416464726573730a000700850c0086007401000a707574416464726573730a000700880c0089007101000e616c6c6f636174654d656d6f72790a0007008b0c008c008d0100107265616c6c6f636174654d656d6f7279010005284a4a294a0a0007008f0c009000910100097365744d656d6f7279010018284c6a6176612f6c616e672f4f626a6563743b4a4a4229560a000700930c00900094010006284a4a4229560a000700960c0097009801000a636f70794d656d6f727901002a284c6a6176612f6c616e672f4f626a6563743b4a4c6a6176612f6c616e672f4f626a6563743b4a4a29560a0007009a0c0097009b010006284a4a4a29560a0007009d0c009e009f01000a667265654d656d6f7279010004284a29560a000700a10c00a200a30100116f626a6563744669656c644f666673657401001c284c6a6176612f6c616e672f7265666c6563742f4669656c643b294a0a000700a50c00a600a30100117374617469634669656c644f66667365740a000700a80c00a900aa01000f7374617469634669656c644261736501002d284c6a6176612f6c616e672f7265666c6563742f4669656c643b294c6a6176612f6c616e672f4f626a6563743b0a000700ac0c00ad00ae01000f6172726179426173654f6666736574010014284c6a6176612f6c616e672f436c6173733b29490a000700b00c00b100ae01000f6172726179496e6465785363616c650a000700b30c00b400b501000b6164647265737353697a650100032829490a000700b70c00b800b50100087061676553697a650a000700ba0c00bb00bc010010616c6c6f63617465496e7374616e6365010025284c6a6176612f6c616e672f436c6173733b294c6a6176612f6c616e672f4f626a6563743b0a000700be0c00bf00c001000e7468726f77457863657074696f6e010018284c6a6176612f6c616e672f5468726f7761626c653b29560a000700c20c00c300c4010014636f6d70617265416e64537761704f626a65637401003a284c6a6176612f6c616e672f4f626a6563743b4a4c6a6176612f6c616e672f4f626a6563743b4c6a6176612f6c616e672f4f626a6563743b295a0a000700c60c00c700c8010011636f6d70617265416e6453776170496e74010018284c6a6176612f6c616e672f4f626a6563743b4a4949295a0a000700ca0c00cb00cc010012636f6d70617265416e64537761704c6f6e67010018284c6a6176612f6c616e672f4f626a6563743b4a4a4a295a0a000700ce0c00cf001a0100116765744f626a656374566f6c6174696c650a000700d10c00d2001e0100117075744f626a656374566f6c6174696c650a000700d40c00d5001201000e676574496e74566f6c6174696c650a000700d70c00d8001601000e707574496e74566f6c6174696c650a000700da0c00db0022010012676574426f6f6c65616e566f6c6174696c650a000700dd0c00de0026010012707574426f6f6c65616e566f6c6174696c650a000700e00c00e1002a01000f67657442797465566f6c6174696c650a000700e30c00e4002e01000f70757442797465566f6c6174696c650a000700e60c00e7003201001067657453686f7274566f6c6174696c650a000700e90c00ea003601001070757453686f7274566f6c6174696c650a000700ec0c00ed003a01000f67657443686172566f6c6174696c650a000700ef0c00f0003e01000f70757443686172566f6c6174696c650a000700f20c00f3004201000f6765744c6f6e67566f6c6174696c650a000700f50c00f6004601000f7075744c6f6e67566f6c6174696c650a000700f80c00f9004a010010676574466c6f6174566f6c6174696c650a000700fb0c00fc004e010010707574466c6f6174566f6c6174696c650a000700fe0c00ff0052010011676574446f75626c65566f6c6174696c650a000701010c01020056010011707574446f75626c65566f6c6174696c650a000701040c0105001e0100107075744f7264657265644f626a6563740a000701070c0108001601000d7075744f726465726564496e740a0007010a0c010b004601000e7075744f7264657265644c6f6e670a0007010d0c010e010f010006756e7061726b010015284c6a6176612f6c616e672f4f626a6563743b29560a000701110c011201130100047061726b010005285a4a29560a000701150c0116011701000e6765744c6f616441766572616765010006285b444929490a000701190c011a011b01000c676574416e64416464496e74010017284c6a6176612f6c616e672f4f626a6563743b4a4929490a0007011d0c011e011f01000d676574416e644164644c6f6e67010017284c6a6176612f6c616e672f4f626a6563743b4a4a294a0a000701210c0122011b01000c676574416e64536574496e740a000701240c0125011f01000d676574416e645365744c6f6e670a000701270c0128012901000f676574416e645365744f626a656374010039284c6a6176612f6c616e672f4f626a6563743b4a4c6a6176612f6c616e672f4f626a6563743b294c6a6176612f6c616e672f4f626a6563743b0a0007012b0c012c00060100096c6f616446656e63650a0007012e0c012f000601000a73746f726546656e63650a000701310c0132000601000966756c6c46656e63650a000701340c0135013601000d696e766f6b65436c65616e6572010018284c6a6176612f6e696f2f427974654275666665723b29560701380100176f72672f7265646b616c652f7574696c2f556e73616665010004436f646501000f4c696e654e756d6265725461626c650100124c6f63616c5661726961626c655461626c65010004746869730100224c6f72672f7265646b616c652f7574696c2f416e6f6e796d6f7573556e736166653b0100036f626a0100124c6a6176612f6c616e672f4f626a6563743b0100104d6574686f64506172616d65746572730100016f0100066f66667365740100014a01000178010001490100015a010001420100015301000143010001460100014401000761646472657373010005627974657301000576616c7565010007737263426173650100097372634f6666736574010008646573744261736501000a646573744f666673657401000a7372634164647265737301000b6465737441646472657373010001660100194c6a6176612f6c616e672f7265666c6563742f4669656c643b01000a6172726179436c6173730100114c6a6176612f6c616e672f436c6173733b0100164c6f63616c5661726961626c65547970655461626c650100144c6a6176612f6c616e672f436c6173733c2a3e3b0100095369676e6174757265010017284c6a6176612f6c616e672f436c6173733c2a3e3b2949010003636c7301000a457863657074696f6e730701600100206a6176612f6c616e672f496e7374616e74696174696f6e457863657074696f6e010028284c6a6176612f6c616e672f436c6173733c2a3e3b294c6a6176612f6c616e672f4f626a6563743b01000265650100154c6a6176612f6c616e672f5468726f7761626c653b010008657870656374656401000674687265616401000a69734162736f6c75746501000474696d650100076c6f61646176670100025b440100066e656c656d7301000564656c74610100086e657756616c756501000c6469726563744275666665720100154c6a6176612f6e696f2f427974654275666665723b01000a536f7572636546696c65010014416e6f6e796d6f7573556e736166652e6a6176610021000a00020001013700010012000d000e0000005700010005010f0002013900000049000200020000000d2ab700012a2bc00007b50009b100000002013a0000000e00030000000a0004000b000c000c013b0000001600020000000d013c013d00000000000d013e013f000101400000000501013e00000001001100120002013900000048000400040000000a2ab400092b20b6000fac00000002013a00000006000100000010013b0000002000030000000a013c013d00000000000a0141013f00010000000a0142014300020140000000090201410000014200000001001500160002013900000058000500050000000c2ab400092b201504b60013b100000002013a0000000a000200000015000b0016013b0000002a00040000000c013c013d00000000000c0141013f00010000000c0142014300020000000c01440145000401400000000d0301410000014200000144000000010019001a0002013900000048000400040000000a2ab400092b20b60017b000000002013a0000000600010000001a013b0000002000030000000a013c013d00000000000a0141013f00010000000a0142014300020140000000090201410000014200000001001d001e0002013900000058000500050000000c2ab400092b201904b6001bb100000002013a0000000a00020000001f000b0020013b0000002a00040000000c013c013d00000000000c0141013f00010000000c0142014300020000000c0144013f000401400000000d030141000001420000014400000001002100220002013900000048000400040000000a2ab400092b20b6001fac00000002013a00000006000100000024013b0000002000030000000a013c013d00000000000a0141013f00010000000a0142014300020140000000090201410000014200000001002500260002013900000058000500050000000c2ab400092b201504b60023b100000002013a0000000a000200000029000b002a013b0000002a00040000000c013c013d00000000000c0141013f00010000000c0142014300020000000c01440146000401400000000d0301410000014200000144000000010029002a0002013900000048000400040000000a2ab400092b20b60027ac00000002013a0000000600010000002e013b0000002000030000000a013c013d00000000000a0141013f00010000000a0142014300020140000000090201410000014200000001002d002e0002013900000058000500050000000c2ab400092b201504b6002bb100000002013a0000000a000200000033000b0034013b0000002a00040000000c013c013d00000000000c0141013f00010000000c0142014300020000000c01440147000401400000000d030141000001420000014400000001003100320002013900000048000400040000000a2ab400092b20b6002fac00000002013a00000006000100000038013b0000002000030000000a013c013d00000000000a0141013f00010000000a0142014300020140000000090201410000014200000001003500360002013900000058000500050000000c2ab400092b201504b60033b100000002013a0000000a00020000003d000b003e013b0000002a00040000000c013c013d00000000000c0141013f00010000000c0142014300020000000c01440148000401400000000d0301410000014200000144000000010039003a0002013900000048000400040000000a2ab400092b20b60037ac00000002013a00000006000100000042013b0000002000030000000a013c013d00000000000a0141013f00010000000a0142014300020140000000090201410000014200000001003d003e0002013900000058000500050000000c2ab400092b201504b6003bb100000002013a0000000a000200000047000b0048013b0000002a00040000000c013c013d00000000000c0141013f00010000000c0142014300020000000c01440149000401400000000d030141000001420000014400000001004100420002013900000048000400040000000a2ab400092b20b6003fad00000002013a0000000600010000004c013b0000002000030000000a013c013d00000000000a0141013f00010000000a0142014300020140000000090201410000014200000001004500460002013900000058000600060000000c2ab400092b201604b60043b100000002013a0000000a000200000051000b0052013b0000002a00040000000c013c013d00000000000c0141013f00010000000c0142014300020000000c01440143000401400000000d0301410000014200000144000000010049004a0002013900000048000400040000000a2ab400092b20b60047ae00000002013a00000006000100000056013b0000002000030000000a013c013d00000000000a0141013f00010000000a0142014300020140000000090201410000014200000001004d004e0002013900000058000500050000000c2ab400092b201704b6004bb100000002013a0000000a00020000005b000b005c013b0000002a00040000000c013c013d00000000000c0141013f00010000000c0142014300020000000c0144014a000401400000000d030141000001420000014400000001005100520002013900000048000400040000000a2ab400092b20b6004faf00000002013a00000006000100000060013b0000002000030000000a013c013d00000000000a0141013f00010000000a0142014300020140000000090201410000014200000001005500560002013900000058000600060000000c2ab400092b201804b60053b100000002013a0000000a000200000065000b0066013b0000002a00040000000c013c013d00000000000c0141013f00010000000c0142014300020000000c0144014b000401400000000d03014100000142000001440000000100290059000201390000003d00030003000000092ab400091fb60057ac00000002013a0000000600010000006a013b00000016000200000009013c013d000000000009014c0143000101400000000501014c00000001002d005c000201390000004c000400040000000a2ab400091f1db6005ab100000002013a0000000a00020000006f00090070013b0000002000030000000a013c013d00000000000a014c014300010000000a01440147000301400000000902014c00000144000000010031005f000201390000003d00030003000000092ab400091fb6005dac00000002013a00000006000100000074013b00000016000200000009013c013d000000000009014c0143000101400000000501014c0000000100350062000201390000004c000400040000000a2ab400091f1db60060b100000002013a0000000a0002000000790009007a013b0000002000030000000a013c013d00000000000a014c014300010000000a01440148000301400000000902014c000001440000000100390065000201390000003d00030003000000092ab400091fb60063ac00000002013a0000000600010000007e013b00000016000200000009013c013d000000000009014c0143000101400000000501014c00000001003d0068000201390000004c000400040000000a2ab400091f1db60066b100000002013a0000000a00020000008300090084013b0000002000030000000a013c013d00000000000a014c014300010000000a01440149000301400000000902014c00000144000000010011006b000201390000003d00030003000000092ab400091fb60069ac00000002013a00000006000100000088013b00000016000200000009013c013d000000000009014c0143000101400000000501014c000000010015006e000201390000004c000400040000000a2ab400091f1db6006cb100000002013a0000000a00020000008d0009008e013b0000002000030000000a013c013d00000000000a014c014300010000000a01440145000301400000000902014c000001440000000100410071000201390000003d00030003000000092ab400091fb6006fad00000002013a00000006000100000092013b00000016000200000009013c013d000000000009014c0143000101400000000501014c0000000100450074000201390000004c000500050000000a2ab400091f21b60072b100000002013a0000000a00020000009700090098013b0000002000030000000a013c013d00000000000a014c014300010000000a01440143000301400000000902014c000001440000000100490077000201390000003d00030003000000092ab400091fb60075ae00000002013a0000000600010000009c013b00000016000200000009013c013d000000000009014c0143000101400000000501014c00000001004d007a000201390000004c000400040000000a2ab400091f25b60078b100000002013a0000000a0002000000a1000900a2013b0000002000030000000a013c013d00000000000a014c014300010000000a0144014a000301400000000902014c00000144000000010051007d000201390000003d00030003000000092ab400091fb6007baf00000002013a000000060001000000a6013b00000016000200000009013c013d000000000009014c0143000101400000000501014c0000000100550080000201390000004c000500050000000a2ab400091f29b6007eb100000002013a0000000a0002000000ab000900ac013b0000002000030000000a013c013d00000000000a014c014300010000000a0144014b000301400000000902014c000001440000000100830071000201390000003d00030003000000092ab400091fb60081ad00000002013a000000060001000000b0013b00000016000200000009013c013d000000000009014c0143000101400000000501014c0000000100860074000201390000004c000500050000000a2ab400091f21b60084b100000002013a0000000a0002000000b5000900b6013b0000002000030000000a013c013d00000000000a014c014300010000000a01440143000301400000000902014c000001440000000100890071000201390000003d00030003000000092ab400091fb60087ad00000002013a000000060001000000ba013b00000016000200000009013c013d000000000009014d0143000101400000000501014d00000001008c008d0002013900000048000500050000000a2ab400091f21b6008aad00000002013a000000060001000000bf013b0000002000030000000a013c013d00000000000a014c014300010000000a014d0143000301400000000902014c0000014d00000001009000910002013900000064000700070000000e2ab400092b2016041506b6008eb100000002013a0000000a0002000000c4000d00c5013b0000003400050000000e013c013d00000000000e0141013f00010000000e0142014300020000000e014d014300040000000e014e01470006014000000011040141000001420000014d0000014e00000001009000940002013900000058000600060000000c2ab400091f211505b60092b100000002013a0000000a0002000000c9000b00ca013b0000002a00040000000c013c013d00000000000c014c014300010000000c014d014300030000000c014e0147000501400000000d03014c0000014d0000014e0000000100970098000201390000007000090009000000102ab400092b20190416051607b60095b100000002013a0000000a0002000000ce000f00cf013b0000003e000600000010013c013d000000000010014f013f000100000010015001430002000000100151013f00040000001001520143000500000010014d0143000701400000001505014f0000015000000151000001520000014d000000010097009b0002013900000058000700070000000c2ab400091f211605b60099b100000002013a0000000a0002000000d3000b00d4013b0000002a00040000000c013c013d00000000000c0153014300010000000c0154014300030000000c014d0143000501400000000d030153000001540000014d00000001009e009f000201390000004100030003000000092ab400091fb6009cb100000002013a0000000a0002000000d8000800d9013b00000016000200000009013c013d000000000009014c0143000101400000000501014c0000000100a200a3000201390000003d00020002000000092ab400092bb600a0ad00000002013a000000060001000000dd013b00000016000200000009013c013d0000000000090155015600010140000000050101550000000100a600a3000201390000003d00020002000000092ab400092bb600a4ad00000002013a000000060001000000e2013b00000016000200000009013c013d0000000000090155015600010140000000050101550000000100a900aa000201390000003d00020002000000092ab400092bb600a7b000000002013a000000060001000000e7013b00000016000200000009013c013d0000000000090155015600010140000000050101550000000100ad00ae000301390000004f00020002000000092ab400092bb600abac00000003013a000000060001000000ec013b00000016000200000009013c013d00000000000901570158000101590000000c0001000000090157015a00010140000000050101570000015b00000002015c000100b100ae000301390000004f00020002000000092ab400092bb600afac00000003013a000000060001000000f1013b00000016000200000009013c013d00000000000901570158000101590000000c0001000000090157015a00010140000000050101570000015b00000002015c000100b400b5000101390000003200010001000000082ab40009b600b2ac00000002013a000000060001000000f6013b0000000c000100000008013c013d0000000100b800b5000101390000003200010001000000082ab40009b600b6ac00000002013a000000060001000000fb013b0000000c000100000008013c013d0000000100bb00bc000401390000004f00020002000000092ab400092bb600b9b000000003013a00000006000100000100013b00000016000200000009013c013d000000000009015d0158000101590000000c000100000009015d015a0001015e000000040001015f01400000000501015d0000015b000000020161000100bf00c0000201390000004100020002000000092ab400092bb600bdb100000002013a0000000a00020000010500080106013b00000016000200000009013c013d0000000000090162016300010140000000050101620000000100c300c40002013900000060000600060000000e2ab400092b2019041905b600c1ac00000002013a0000000600010000010a013b0000003400050000000e013c013d00000000000e0141013f00010000000e0142014300020000000e0164013f00040000000e0144013f00050140000000110401410000014200000164000001440000000100c700c80002013900000060000600060000000e2ab400092b2015041505b600c5ac00000002013a0000000600010000010f013b0000003400050000000e013c013d00000000000e0141013f00010000000e0142014300020000000e0164014500040000000e0144014500050140000000110401410000014200000164000001440000000100cb00cc0002013900000060000800080000000e2ab400092b2016041606b600c9ac00000002013a00000006000100000114013b0000003400050000000e013c013d00000000000e0141013f00010000000e0142014300020000000e0164014300040000000e0144014300060140000000110401410000014200000164000001440000000100cf001a0002013900000048000400040000000a2ab400092b20b600cdb000000002013a00000006000100000119013b0000002000030000000a013c013d00000000000a0141013f00010000000a014201430002014000000009020141000001420000000100d2001e0002013900000058000500050000000c2ab400092b201904b600d0b100000002013a0000000a00020000011e000b011f013b0000002a00040000000c013c013d00000000000c0141013f00010000000c0142014300020000000c0144013f000401400000000d03014100000142000001440000000100d500120002013900000048000400040000000a2ab400092b20b600d3ac00000002013a00000006000100000123013b0000002000030000000a013c013d00000000000a0141013f00010000000a014201430002014000000009020141000001420000000100d800160002013900000058000500050000000c2ab400092b201504b600d6b100000002013a0000000a000200000128000b0129013b0000002a00040000000c013c013d00000000000c0141013f00010000000c0142014300020000000c01440145000401400000000d03014100000142000001440000000100db00220002013900000048000400040000000a2ab400092b20b600d9ac00000002013a0000000600010000012d013b0000002000030000000a013c013d00000000000a0141013f00010000000a014201430002014000000009020141000001420000000100de00260002013900000058000500050000000c2ab400092b201504b600dcb100000002013a0000000a000200000132000b0133013b0000002a00040000000c013c013d00000000000c0141013f00010000000c0142014300020000000c01440146000401400000000d03014100000142000001440000000100e1002a0002013900000048000400040000000a2ab400092b20b600dfac00000002013a00000006000100000137013b0000002000030000000a013c013d00000000000a0141013f00010000000a014201430002014000000009020141000001420000000100e4002e0002013900000058000500050000000c2ab400092b201504b600e2b100000002013a0000000a00020000013c000b013d013b0000002a00040000000c013c013d00000000000c0141013f00010000000c0142014300020000000c01440147000401400000000d03014100000142000001440000000100e700320002013900000048000400040000000a2ab400092b20b600e5ac00000002013a00000006000100000141013b0000002000030000000a013c013d00000000000a0141013f00010000000a014201430002014000000009020141000001420000000100ea00360002013900000058000500050000000c2ab400092b201504b600e8b100000002013a0000000a000200000146000b0147013b0000002a00040000000c013c013d00000000000c0141013f00010000000c0142014300020000000c01440148000401400000000d03014100000142000001440000000100ed003a0002013900000048000400040000000a2ab400092b20b600ebac00000002013a0000000600010000014b013b0000002000030000000a013c013d00000000000a0141013f00010000000a014201430002014000000009020141000001420000000100f0003e0002013900000058000500050000000c2ab400092b201504b600eeb100000002013a0000000a000200000150000b0151013b0000002a00040000000c013c013d00000000000c0141013f00010000000c0142014300020000000c01440149000401400000000d03014100000142000001440000000100f300420002013900000048000400040000000a2ab400092b20b600f1ad00000002013a00000006000100000155013b0000002000030000000a013c013d00000000000a0141013f00010000000a014201430002014000000009020141000001420000000100f600460002013900000058000600060000000c2ab400092b201604b600f4b100000002013a0000000a00020000015a000b015b013b0000002a00040000000c013c013d00000000000c0141013f00010000000c0142014300020000000c01440143000401400000000d03014100000142000001440000000100f9004a0002013900000048000400040000000a2ab400092b20b600f7ae00000002013a0000000600010000015f013b0000002000030000000a013c013d00000000000a0141013f00010000000a014201430002014000000009020141000001420000000100fc004e0002013900000058000500050000000c2ab400092b201704b600fab100000002013a0000000a000200000164000b0165013b0000002a00040000000c013c013d00000000000c0141013f00010000000c0142014300020000000c0144014a000401400000000d03014100000142000001440000000100ff00520002013900000048000400040000000a2ab400092b20b600fdaf00000002013a00000006000100000169013b0000002000030000000a013c013d00000000000a0141013f00010000000a0142014300020140000000090201410000014200000001010200560002013900000058000600060000000c2ab400092b201804b60100b100000002013a0000000a00020000016e000b016f013b0000002a00040000000c013c013d00000000000c0141013f00010000000c0142014300020000000c0144014b000401400000000d0301410000014200000144000000010105001e0002013900000058000500050000000c2ab400092b201904b60103b100000002013a0000000a000200000173000b0174013b0000002a00040000000c013c013d00000000000c0141013f00010000000c0142014300020000000c0144013f000401400000000d030141000001420000014400000001010800160002013900000058000500050000000c2ab400092b201504b60106b100000002013a0000000a000200000178000b0179013b0000002a00040000000c013c013d00000000000c0141013f00010000000c0142014300020000000c01440145000401400000000d030141000001420000014400000001010b00460002013900000058000600060000000c2ab400092b201604b60109b100000002013a0000000a00020000017d000b017e013b0000002a00040000000c013c013d00000000000c0141013f00010000000c0142014300020000000c01440143000401400000000d030141000001420000014400000001010e010f000201390000004100020002000000092ab400092bb6010cb100000002013a0000000a00020000018200080183013b00000016000200000009013c013d0000000000090165013f00010140000000050101650000000101120113000201390000004c000400040000000a2ab400091b20b60110b100000002013a0000000a00020000018700090188013b0000002000030000000a013c013d00000000000a0166014600010000000a0167014300020140000000090201660000016700000001011601170002013900000048000300030000000a2ab400092b1cb60114ac00000002013a0000000600010000018c013b0000002000030000000a013c013d00000000000a0168016900010000000a016a014500020140000000090201680000016a00000001011a011b0002013900000054000500050000000c2ab400092b201504b60118ac00000002013a00000006000100000191013b0000002a00040000000c013c013d00000000000c0141013f00010000000c0142014300020000000c016b0145000401400000000d030141000001420000016b00000001011e011f0002013900000054000600060000000c2ab400092b201604b6011cad00000002013a00000006000100000196013b0000002a00040000000c013c013d00000000000c0141013f00010000000c0142014300020000000c016b0143000401400000000d030141000001420000016b000000010122011b0002013900000054000500050000000c2ab400092b201504b60120ac00000002013a0000000600010000019b013b0000002a00040000000c013c013d00000000000c0141013f00010000000c0142014300020000000c016c0145000401400000000d030141000001420000016c000000010125011f0002013900000054000600060000000c2ab400092b201604b60123ad00000002013a000000060001000001a0013b0000002a00040000000c013c013d00000000000c0141013f00010000000c0142014300020000000c016c0143000401400000000d030141000001420000016c00000001012801290002013900000054000500050000000c2ab400092b201904b60126b000000002013a000000060001000001a5013b0000002a00040000000c013c013d00000000000c0141013f00010000000c0142014300020000000c016c013f000401400000000d030141000001420000016c00000001012c0006000101390000003600010001000000082ab40009b6012ab100000002013a0000000a0002000001aa000701ab013b0000000c000100000008013c013d00000001012f0006000101390000003600010001000000082ab40009b6012db100000002013a0000000a0002000001af000701b0013b0000000c000100000008013c013d0000000101320006000101390000003600010001000000082ab40009b60130b100000002013a0000000a0002000001b4000701b5013b0000000c000100000008013c013d0000000101350136000201390000004100020002000000092ab400092bb60133b100000002013a0000000a0002000001b9000801ba013b00000016000200000009013c013d000000000009016d016e000101400000000501016d00000001016f000000020170";
private static final Unsafe unsafeInstance;
// -------------------------------------------------------------------------------
private static final Function<String, byte[]> strByteFunction;
private static final Function<StringBuilder, byte[]> sbByteFunction;
private static final Predicate<Object> strLatin1Function;
private static final ToLongFunction<Object> bufferAddrFunction;
private static final ReentrantLock clientLock = new ReentrantLock();
// 是否native-image运行环境
private static final boolean NATIVE_IMAGE_ENV =
"executable".equals(System.getProperty("org.graalvm.nativeimage.kind"));
private static HttpClient httpClient;
private static final ScheduledThreadPoolExecutor delayer;
// private static final javax.net.ssl.SSLContext DEFAULTSSL_CONTEXT;
// private static final javax.net.ssl.HostnameVerifier defaultVerifier = (s, ss) -> true;
static {
System.setProperty("jdk.httpclient.allowRestrictedHeaders", "host");
(delayer = new ScheduledThreadPoolExecutor(1, r -> {
Thread t = new Thread(r);
t.setDaemon(true);
t.setName("RedkaleFutureDelayScheduler");
return t;
}))
.setRemoveOnCancelPolicy(true);
Unsafe unsafe0 = null;
Function<String, byte[]> strByteFunction0 = null;
Function<StringBuilder, byte[]> sbByteFunction0 = null;
Predicate<Object> strLatin1Function0 = null;
ToLongFunction<Object> bufferAddrFunction0 = null;
Consumer<Consumer<String>> signalShutdownConsumer0 = null;
Function<Supplier, ThreadLocal> virtualThreadLocalFunction0 = null;
Function<String, ThreadFactory> virtualThreadFactoryFunction0 = null;
Function<String, ExecutorService> virtualPoolFunction0 = null;
Executor virtualExecutorConsumer0 = null;
if (!NATIVE_IMAGE_ENV) { // not native-image
try {
final ClassLoader loader = Thread.currentThread().getContextClassLoader();
{ // virtualThreadLocalFunction
Class<Function<Supplier, ThreadLocal>> virtualClazz = null;
try {
virtualClazz = (Class) loader.loadClass("org.redkale.util.AnonymousThreadLocal");
} catch (Throwable t) {
// do nothing
}
if (virtualClazz == null) {
try {
byte[] classBytes = hexToBin(functionThreadLocalBinary);
virtualClazz = (Class<Function<Supplier, ThreadLocal>>)
new ClassLoader(loader) {
public final Class<?> loadClass(String name, byte[] b) {
return defineClass(name, b, 0, b.length);
}
}.loadClass("org.redkale.util.AnonymousThreadLocal", classBytes);
RedkaleClassLoader.putDynClass(virtualClazz.getName(), classBytes, virtualClazz);
} catch (Throwable t) {
// do nothing
}
}
if (virtualClazz != null) {
try {
RedkaleClassLoader.putReflectionDeclaredConstructors(virtualClazz, virtualClazz.getName());
Supplier supplier = () -> null;
virtualThreadLocalFunction0 =
virtualClazz.getConstructor(Supplier.class).newInstance(supplier);
} catch (Throwable t) {
// do nothing
}
}
}
{ // virtualThreadFactoryFunction
Class<Function<String, ThreadFactory>> virtualClazz = null;
try {
virtualClazz = (Class) loader.loadClass("org.redkale.util.AnonymousThreadFactory");
} catch (Throwable t) {
// do nothing
}
if (virtualClazz == null) {
try {
byte[] classBytes = hexToBin(functionThreadFactoryBinary);
virtualClazz = (Class<Function<String, ThreadFactory>>)
new ClassLoader(loader) {
public final Class<?> loadClass(String name, byte[] b) {
return defineClass(name, b, 0, b.length);
}
}.loadClass("org.redkale.util.AnonymousThreadFactory", classBytes);
RedkaleClassLoader.putDynClass(virtualClazz.getName(), classBytes, virtualClazz);
} catch (Throwable t) {
// do nothing
}
}
if (virtualClazz != null) {
try {
RedkaleClassLoader.putReflectionDeclaredConstructors(virtualClazz, virtualClazz.getName());
Object[] initargs = new Object[] {null};
virtualThreadFactoryFunction0 =
virtualClazz.getConstructor(String.class).newInstance(initargs);
} catch (Throwable t) {
// do nothing
}
}
}
{ // virtualPoolFunction
Class<Function<String, ExecutorService>> virtualClazz = null;
try {
virtualClazz = (Class) loader.loadClass("org.redkale.util.AnonymousVirtualPoolFunction");
} catch (Throwable t) {
// do nothing
}
if (virtualClazz == null) {
try {
byte[] classBytes = hexToBin(functionVirtualPoolBinary);
virtualClazz = (Class<Function<String, ExecutorService>>)
new ClassLoader(loader) {
public final Class<?> loadClass(String name, byte[] b) {
return defineClass(name, b, 0, b.length);
}
}.loadClass("org.redkale.util.AnonymousVirtualPoolFunction", classBytes);
RedkaleClassLoader.putDynClass(virtualClazz.getName(), classBytes, virtualClazz);
} catch (Throwable t) {
// do nothing
}
}
if (virtualClazz != null) {
try {
RedkaleClassLoader.putReflectionDeclaredConstructors(virtualClazz, virtualClazz.getName());
virtualPoolFunction0 = virtualClazz.getConstructor().newInstance();
} catch (Throwable t) {
// do nothing
}
}
}
{ // virtualExecutorConsumer
Class<Executor> virtualClazz = null;
try {
virtualClazz = (Class) loader.loadClass("org.redkale.util.AnonymousVirtualExecutor");
} catch (Throwable t) {
// do nothing
}
if (virtualClazz == null) {
try {
byte[] classBytes = hexToBin(consumerVirtualExecutorBinary);
virtualClazz = (Class<Executor>)
new ClassLoader(loader) {
public final Class<?> loadClass(String name, byte[] b) {
return defineClass(name, b, 0, b.length);
}
}.loadClass("org.redkale.util.AnonymousVirtualExecutor", classBytes);
RedkaleClassLoader.putDynClass(virtualClazz.getName(), classBytes, virtualClazz);
} catch (Throwable t) {
// do nothing
}
}
if (virtualClazz != null) {
try {
RedkaleClassLoader.putReflectionDeclaredConstructors(virtualClazz, virtualClazz.getName());
virtualExecutorConsumer0 =
virtualClazz.getConstructor().newInstance();
} catch (Throwable t) {
// do nothing
}
}
}
{ // unsafe
Field f = String.class.getDeclaredField("value");
final Class unsafeClass = loader.loadClass("sun.misc.Unsafe");
final Field safeField = unsafeClass.getDeclaredField("theUnsafe");
RedkaleClassLoader.putReflectionField("sun.misc.Unsafe", safeField);
safeField.setAccessible(true);
final Object usafe = safeField.get(null);
Class<Unsafe> unsafeClazz1 = null;
try {
unsafeClazz1 = (Class) loader.loadClass("org.redkale.util.AnonymousUnsafe");
} catch (Throwable t) {
// do nothing
}
if (unsafeClazz1 == null) {
byte[] classBytes = hexToBin(funcAnonymousUnsafeBinary);
unsafeClazz1 = (Class<Unsafe>)
new ClassLoader(loader) {
public final Class<?> loadClass(String name, byte[] b) {
return defineClass(name, b, 0, b.length);
}
}.loadClass("org.redkale.util.AnonymousUnsafe", classBytes);
RedkaleClassLoader.putDynClass(unsafeClazz1.getName(), classBytes, unsafeClazz1);
}
RedkaleClassLoader.putReflectionDeclaredConstructors(
unsafeClazz1, unsafeClazz1.getName(), Object.class);
unsafe0 = unsafeClazz1.getConstructor(Object.class).newInstance(usafe);
final Unsafe unsafe = unsafe0;
final long fd1 = unsafe0.objectFieldOffset(f);
final long fd2 = unsafe0.objectFieldOffset(
StringBuilder.class.getSuperclass().getDeclaredField("value"));
final long fd3 = unsafe0.objectFieldOffset(String.class.getDeclaredField("coder"));
final long fd4 = unsafe0.objectFieldOffset(Buffer.class.getDeclaredField("address"));
Field cf = String.class.getDeclaredField("COMPACT_STRINGS");
strByteFunction0 = (String t) -> (byte[]) unsafe.getObject(t, fd1);
sbByteFunction0 = (StringBuilder t) -> (byte[]) unsafe.getObject(t, fd2);
final boolean compact = unsafe.getBoolean(String.class, unsafe0.staticFieldOffset(cf));
// LATIN1:0 UTF16:1
strLatin1Function0 = compact ? (Object t) -> unsafe.getByte(t, fd3) == 0 : (Object t) -> false;
bufferAddrFunction0 = (Object t) -> unsafe.getLong(t, fd4);
}
{ // signalShutdown
Class<Consumer<Consumer<String>>> shutdownClazz1 = null;
try {
shutdownClazz1 = (Class) loader.loadClass("org.redkale.util.SignalShutDown");
} catch (Throwable t) {
// do nothing
}
if (shutdownClazz1 == null) {
byte[] classBytes = hexToBin(consumerSignalShutdownBinary);
shutdownClazz1 = (Class<Consumer<Consumer<String>>>)
new ClassLoader(loader) {
public final Class<?> loadClass(String name, byte[] b) {
return defineClass(name, b, 0, b.length);
}
}.loadClass("org.redkale.util.SignalShutDown", classBytes);
RedkaleClassLoader.putDynClass(shutdownClazz1.getName(), classBytes, shutdownClazz1);
RedkaleClassLoader.putReflectionDeclaredConstructors(shutdownClazz1, shutdownClazz1.getName());
signalShutdownConsumer0 =
shutdownClazz1.getConstructor().newInstance();
}
}
} catch (Throwable e) { // 不会发生
// do nothing
}
}
unsafeInstance = unsafe0;
strByteFunction = strByteFunction0;
sbByteFunction = sbByteFunction0;
strLatin1Function = strLatin1Function0;
bufferAddrFunction = bufferAddrFunction0;
signalShutdownConsumer = signalShutdownConsumer0;
virtualPoolFunction = virtualPoolFunction0;
virtualThreadLocalFunction = virtualThreadLocalFunction0;
virtualThreadFactoryFunction = virtualThreadFactoryFunction0;
virtualExecutorConsumer = virtualExecutorConsumer0;
// try {
// DEFAULTSSL_CONTEXT = javax.net.ssl.SSLContext.getInstance("SSL");
// DEFAULTSSL_CONTEXT.init(null, new javax.net.ssl.TrustManager[]{new
// javax.net.ssl.X509TrustManager() {
// @Override
// public java.security.cert.X509Certificate[] getAcceptedIssuers() {
// return null;
// }
//
// @Override
// public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType)
// throws java.security.cert.CertificateException {
// }
//
// @Override
// public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType)
// throws java.security.cert.CertificateException {
// }
// }}, null);
// } catch (Exception e) {
// throw new RedkaleException(e); //不会发生
// }
}
private Utility() {}
public static Unsafe unsafe() {
return unsafeInstance;
}
public static int cpus() {
return CPUS;
}
public static boolean inNativeImage() {
return NATIVE_IMAGE_ENV;
}
public static Function<String, ExecutorService> virtualExecutorFunction() {
return virtualPoolFunction;
}
public static <T> ThreadLocal<T> withInitialThreadLocal(Supplier<T> supplier) {
return virtualThreadLocalFunction == null
? ThreadLocal.withInitial(supplier)
: virtualThreadLocalFunction.apply(supplier);
}
public static Function<String, ThreadFactory> virtualFactoryFunction() {
return virtualThreadFactoryFunction;
}
public static ThreadFactory newThreadFactory(final String name) {
if (virtualThreadFactoryFunction == null) {
if (isEmpty(name) || !name.contains("%s")) {
return (Runnable r) -> {
final Thread t = isEmpty(name) ? new Thread(r) : new Thread(r, name);
t.setDaemon(true);
return t;
};
} else {
AtomicInteger counter = new AtomicInteger();
return (Runnable r) -> {
final Thread t = new Thread(r, String.format(name, counter.incrementAndGet()));
t.setDaemon(true);
return t;
};
}
} else { // 虚拟线程工厂
return virtualThreadFactoryFunction.apply(
isEmpty(name)
? null
: (name.contains("%s") ? String.format(name, "Virtual") : (name + "-Virtual")));
}
}
public static ScheduledThreadPoolExecutor newScheduledExecutor(int corePoolSize) {
ScheduledThreadPoolExecutor scheduler = new ScheduledThreadPoolExecutor(corePoolSize, newThreadFactory(null));
scheduler.setRemoveOnCancelPolicy(true);
return scheduler;
}
public static ScheduledThreadPoolExecutor newScheduledExecutor(int corePoolSize, String name) {
ScheduledThreadPoolExecutor scheduler = new ScheduledThreadPoolExecutor(corePoolSize, newThreadFactory(name));
scheduler.setRemoveOnCancelPolicy(true);
return scheduler;
}
public static ScheduledThreadPoolExecutor newScheduledExecutor(
int corePoolSize, String name, RejectedExecutionHandler handler) {
ScheduledThreadPoolExecutor scheduler =
new ScheduledThreadPoolExecutor(corePoolSize, newThreadFactory(name), handler);
scheduler.setRemoveOnCancelPolicy(true);
return scheduler;
}
public static Consumer<Consumer<String>> signalShutdownConsumer() {
return signalShutdownConsumer;
}
public static IntFunction<Serializable[]> serialArrayFunc() {
return serialArrayFunc;
}
public static IntFunction<CompletableFuture[]> futureArrayFunc() {
return futureArrayFunc;
}
public static Executor defaultExecutor() {
return virtualExecutorConsumer == null ? defaultExecutorConsumer : virtualExecutorConsumer;
}
/**
* 构建method的唯一key用于遍历类及父类的所有方法key过滤重载方法
*
* @param method 方法
* @return key
*/
public static String methodKey(Method method) {
StringBuilder sb = new StringBuilder();
sb.append(method.getName());
sb.append('-').append(method.getParameterCount());
for (Class c : method.getParameterTypes()) {
sb.append('-').append(c.getName());
}
return sb.toString();
}
/**
* 返回第一个不为null的对象
*
* @param <T> 泛型
* @param val1 对象1
* @param val2 对象2
* @return 可用对象可能返回null
*/
public static <T> T orElse(T val1, T val2) {
return val1 == null ? val2 : val1;
}
/**
* 返回第一个不为null的对象
*
* @param <T> 泛型
* @param vals 对象集合
* @return 可用对象可能返回null
*/
public static <T> T orElse(T... vals) {
for (T t : vals) {
if (t != null) {
return t;
}
}
return null;
}
public static void execute(Runnable task) {
if (virtualExecutorConsumer != null) {
virtualExecutorConsumer.execute(task);
} else {
task.run();
}
}
public static void sleep(long millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
}
}
public static boolean isAbstractOrInterface(Class clazz) {
return clazz.isInterface() || Modifier.isAbstract(clazz.getModifiers());
}
public static String readFieldName(LambdaFunction func) {
return readLambdaFieldName(func);
}
public static String readFieldName(LambdaBiConsumer consumer) {
return readLambdaFieldName(consumer);
}
public static Class readClassName(LambdaBiConsumer consumer) {
return readLambdaClassName(consumer);
}
public static String readFieldName(LambdaSupplier func) {
return readLambdaFieldName(func);
}
public static Class readClassName(LambdaSupplier func) {
return readLambdaClassName(func);
}
private static String readLambdaFieldName(Serializable func) {
if (!func.getClass().isSynthetic()) { // 必须是Lambda表达式的合成类
throw new RedkaleException("Not a synthetic lambda class");
}
return lambdaFieldNameCache.computeIfAbsent(func.getClass(), clazz -> {
try {
MethodHandles.Lookup lookup = MethodHandles.privateLookupIn(func.getClass(), MethodHandles.lookup());
MethodHandle mh =
lookup.findVirtual(func.getClass(), "writeReplace", MethodType.methodType(Object.class));
String methodName = ((java.lang.invoke.SerializedLambda) mh.invoke(func)).getImplMethodName();
return readFieldName(methodName);
} catch (Throwable e) {
return readLambdaFieldNameFromBytes(func);
}
});
}
private static String readLambdaFieldNameFromBytes(Serializable func) {
try {
ObjectWriteStream out = new ObjectWriteStream(new ByteArrayOutputStream());
out.writeObject(func);
out.close();
String methodName = out.methodNameReference.get();
if (methodName != null) {
return readFieldName(methodName);
} else {
// native-image环境下获取不到methodName
throw new RedkaleException("cannot found method-name from lambda " + func);
}
} catch (IOException e) {
throw new RedkaleException(e);
}
}
private static Class readLambdaClassName(Serializable func) {
if (!func.getClass().isSynthetic()) { // 必须是Lambda表达式的合成类
throw new RedkaleException("Not a synthetic lambda class");
}
return lambdaClassNameCache.computeIfAbsent(func.getClass(), clazz -> {
try {
MethodHandles.Lookup lookup = MethodHandles.privateLookupIn(func.getClass(), MethodHandles.lookup());
MethodHandle mh =
lookup.findVirtual(func.getClass(), "writeReplace", MethodType.methodType(Object.class));
String methodName = ((java.lang.invoke.SerializedLambda) mh.invoke(func)).getImplMethodName();
String className = methodName.contains("lambda$")
? org.redkale.asm.Type.getReturnType(((java.lang.invoke.SerializedLambda) mh.invoke(func))
.getInstantiatedMethodType())
.getClassName()
: ((java.lang.invoke.SerializedLambda) mh.invoke(func))
.getImplClass()
.replace('/', '.');
return (Class) Thread.currentThread().getContextClassLoader().loadClass(className);
} catch (ClassNotFoundException ex) {
throw new RedkaleException(ex);
} catch (Throwable e) {
return readLambdaClassNameFromBytes(func);
}
});
}
private static Class readLambdaClassNameFromBytes(Serializable func) {
try {
ObjectWriteStream out = new ObjectWriteStream(new ByteArrayOutputStream());
out.writeObject(func);
out.close();
String className = out.classNameReference.get();
if (className != null) {
return (Class) Thread.currentThread().getContextClassLoader().loadClass(className);
} else {
// native-image环境下获取不到methodName
throw new RedkaleException("cannot found method-name from lambda " + func);
}
} catch (Exception e) {
throw new RedkaleException(e);
}
}
static String readFieldName(String methodName) {
String name;
if (methodName.startsWith("is")) {
name = methodName.substring(2);
} else if (methodName.startsWith("get") || methodName.startsWith("set")) {
name = methodName.substring(3);
} else {
name = methodName;
}
if (name.length() < 2) {
return name.toLowerCase(Locale.ENGLISH);
} else if (Character.isUpperCase(name.charAt(1))) {
return name;
} else {
return name.substring(0, 1).toLowerCase(Locale.ENGLISH) + name.substring(1);
}
}
static class ObjectWriteStream extends ObjectOutputStream {
public final ObjectRef<String> methodNameReference = new ObjectRef<>();
public final ObjectRef<String> classNameReference = new ObjectRef<>();
public ObjectWriteStream(OutputStream out) throws IOException {
super(out);
}
@Override
protected Object replaceObject(Object obj) throws IOException {
if (obj instanceof java.lang.invoke.SerializedLambda) {
String methodName = ((java.lang.invoke.SerializedLambda) obj).getImplMethodName();
methodNameReference.set(methodName);
java.lang.invoke.SerializedLambda sl = (java.lang.invoke.SerializedLambda) obj;
String className = methodName.contains("lambda$")
? org.redkale.asm.Type.getReturnType(sl.getInstantiatedMethodType())
.getClassName()
: sl.getImplClass().replace('/', '.');
classNameReference.set(className);
}
return super.replaceObject(obj);
}
@Override
public boolean enableReplaceObject(boolean enable) throws SecurityException {
return super.enableReplaceObject(enable);
}
}
/**
* @param value from which next positive power of two will be found.
* @return the next positive power of 2, this value if it is a power of 2. Negative values are mapped to 1.
* @throws IllegalArgumentException is value is more than MAX_POW2 or less than 0
*/
public static int roundToPowerOfTwo(final int value) {
if (value > MAX_POW2) {
throw new IllegalArgumentException(
"There is no larger power of 2 int for value:" + value + " since it exceeds 2^31.");
}
if (value < 0) {
throw new IllegalArgumentException("Given value:" + value + ". Expecting value >= 0.");
}
return 1 << (32 - Integer.numberOfLeadingZeros(value - 1));
}
public static boolean isRecordGetter(Method method) {
return isRecordGetter(method.getDeclaringClass(), method);
}
public static boolean isRecordGetter(Class clazz, Method method) {
if (JAVA_RECORD_CLASS == null) {
return false;
}
if (method.getReturnType() == void.class) {
return false;
}
if (method.getParameterCount() != 0) {
return false;
}
if (method.getName().equals("getClass")) {
return false;
}
Class clz = (clazz == null ? method.getDeclaringClass() : clazz);
if (!JAVA_RECORD_CLASS.isAssignableFrom(clz)) {
return false;
}
try {
return clz.getDeclaredField(method.getName()).getType() == method.getReturnType();
} catch (Throwable t) {
return false;
}
}
public static <T> CompletableFuture<T> orTimeout(
CompletableFuture future, Supplier<String> errMsgFunc, Duration timeout) {
return orTimeout(future, errMsgFunc, timeout.toMillis(), TimeUnit.MILLISECONDS);
}
public static <T> CompletableFuture<T> orTimeout(
CompletableFuture future, Supplier<String> errMsgFunc, long timeout, TimeUnit unit) {
if (future == null) {
return future;
}
final ScheduledFuture<?> sf = delayer.schedule(
() -> {
if (!future.isDone()) {
String msg = errMsgFunc == null ? null : errMsgFunc.get();
future.completeExceptionally(msg == null ? new TimeoutException(msg) : new TimeoutException());
}
},
timeout,
unit);
return future.whenComplete((v, t) -> {
if (t == null && !sf.isDone()) {
sf.cancel(false);
}
});
}
public static <T> CompletableFuture<T> completeOnTimeout(CompletableFuture future, T value, Duration timeout) {
return completeOnTimeout(future, value, timeout.toMillis(), TimeUnit.MILLISECONDS);
}
public static <T> CompletableFuture<T> completeOnTimeout(
CompletableFuture future, T value, long timeout, TimeUnit unit) {
return future.completeOnTimeout(value, timeout, unit);
}
public static <T> CompletableFuture<T[]> allOfFutures(List<CompletableFuture<T>> list, IntFunction<T[]> func) {
CompletableFuture<T>[] futures = list.toArray(futureArrayFunc);
return CompletableFuture.allOf(futures).thenApply(v -> {
int size = futures.length;
T[] array = func.apply(size);
for (int i = 0; i < size; i++) {
array[i] = futures[i].join();
}
return array;
});
}
public static <T> CompletableFuture<T[]> allOfFutures(Stream<CompletableFuture<T>> stream, IntFunction<T[]> func) {
CompletableFuture<T>[] futures = stream.toArray(futureArrayFunc);
return CompletableFuture.allOf(futures).thenApply(v -> {
int size = futures.length;
T[] array = func.apply(size);
for (int i = 0; i < size; i++) {
array[i] = futures[i].join();
}
return array;
});
}
public static <T> CompletableFuture<T[]> allOfFutures(CompletableFuture<T>[] futures, IntFunction<T[]> func) {
return CompletableFuture.allOf(futures).thenApply(v -> {
int size = futures.length;
T[] array = func.apply(size);
for (int i = 0; i < size; i++) {
array[i] = futures[i].join();
}
return array;
});
}
public static <T> CompletableFuture<T[]> allOfFutures(
List<CompletableFuture<T>> list, IntFunction<T[]> func, BiConsumer<Integer, T> consumer) {
CompletableFuture<T>[] futures = list.toArray(futureArrayFunc);
return CompletableFuture.allOf(futures).thenApply(v -> {
int size = futures.length;
T[] array = func.apply(size);
for (int i = 0; i < size; i++) {
T val = futures[i].join();
consumer.accept(i, val);
array[i] = val;
}
return array;
});
}
public static <T> CompletableFuture<T[]> allOfFutures(
Stream<CompletableFuture<T>> stream, IntFunction<T[]> func, BiConsumer<Integer, T> consumer) {
CompletableFuture<T>[] futures = stream.toArray(futureArrayFunc);
return CompletableFuture.allOf(futures).thenApply(v -> {
int size = futures.length;
T[] array = func.apply(size);
for (int i = 0; i < size; i++) {
T val = futures[i].join();
consumer.accept(i, val);
array[i] = val;
}
return array;
});
}
public static <T> CompletableFuture<T[]> allOfFutures(
CompletableFuture<T>[] futures, IntFunction<T[]> func, BiConsumer<Integer, T> consumer) {
return CompletableFuture.allOf(futures).thenApply(v -> {
int size = futures.length;
T[] array = func.apply(size);
for (int i = 0; i < size; i++) {
T val = futures[i].join();
consumer.accept(i, val);
array[i] = val;
}
return array;
});
}
public static <T> CompletableFuture<List<T>> allOfFutures(List<CompletableFuture<T>> list) {
CompletableFuture<T>[] futures = list.toArray(futureArrayFunc);
return CompletableFuture.allOf(futures).thenApply(v -> {
int size = futures.length;
List<T> rs = new ArrayList<>(size);
for (int i = 0; i < size; i++) {
rs.add(futures[i].join());
}
return rs;
});
}
public static <T> CompletableFuture<List<T>> allOfFutures(Stream<CompletableFuture<T>> stream) {
CompletableFuture<T>[] futures = stream.toArray(futureArrayFunc);
return CompletableFuture.allOf(futures).thenApply(v -> {
int size = futures.length;
List<T> rs = new ArrayList<>(size);
for (int i = 0; i < size; i++) {
rs.add(futures[i].join());
}
return rs;
});
}
public static <T> CompletableFuture<List<T>> allOfFutures(CompletableFuture<T>[] futures) {
if (futures.length == 1) {
return futures[0].thenApply(v -> {
List<T> rs = new ArrayList<>(1);
rs.add(v);
return rs;
});
}
return CompletableFuture.allOf(futures).thenApply(v -> {
int size = futures.length;
List<T> rs = new ArrayList<>(size);
for (int i = 0; i < size; i++) {
rs.add(futures[i].join());
}
return rs;
});
}
public static <T> CompletableFuture<List<T>> allOfFutures(
List<CompletableFuture<T>> list, BiConsumer<Integer, T> consumer) {
CompletableFuture<T>[] futures = list.toArray(futureArrayFunc);
return CompletableFuture.allOf(futures).thenApply(v -> {
int size = futures.length;
List<T> rs = new ArrayList<>(size);
for (int i = 0; i < size; i++) {
T val = futures[i].join();
consumer.accept(i, val);
rs.add(val);
}
return rs;
});
}
public static <T> CompletableFuture<List<T>> allOfFutures(
Stream<CompletableFuture<T>> stream, BiConsumer<Integer, T> consumer) {
CompletableFuture<T>[] futures = stream.toArray(futureArrayFunc);
return CompletableFuture.allOf(futures).thenApply(v -> {
int size = futures.length;
List<T> rs = new ArrayList<>(size);
for (int i = 0; i < size; i++) {
T val = futures[i].join();
consumer.accept(i, val);
rs.add(val);
}
return rs;
});
}
public static <T> CompletableFuture<List<T>> allOfFutures(
CompletableFuture<T>[] futures, BiConsumer<Integer, T> consumer) {
if (futures.length == 1) {
return futures[0].thenApply(v -> {
List<T> rs = new ArrayList<>(1);
consumer.accept(0, v);
rs.add(v);
return rs;
});
}
return CompletableFuture.allOf(futures).thenApply(v -> {
int size = futures.length;
List<T> rs = new ArrayList<>(size);
for (int i = 0; i < size; i++) {
T val = futures[i].join();
consumer.accept(i, val);
rs.add(val);
}
return rs;
});
}
/**
* 是否为数字字符串
*
* @param str 字符串
* @return 是否为数字字符串
*/
public static boolean isNumeric(String str) {
if (str == null || str.isEmpty()) {
return false;
}
int size = str.length();
for (int i = 0; i < size; i++) {
if (!Character.isDigit(str.charAt(i))) {
return false;
}
}
return true;
}
/**
* 是否为空白
*
* @param str 字符串
* @return 是否为空白
*/
public static boolean isBlank(String str) {
return str == null || str.isEmpty() || str.isBlank();
}
/**
* 是否为空白
*
* @param str 字符串
* @param fromIndex 起始位置
* @param toIndex 结束位置
* @return 是否为空白
*/
public static boolean isBlank(String str, int fromIndex, int toIndex) {
if (str == null || str.isEmpty()) {
return true;
}
for (int i = fromIndex; i < toIndex; i++) {
char ch = str.charAt(i);
if (ch != ' ' && ch != '\t' && !Character.isWhitespace(ch)) {
return false;
}
}
return true;
}
/**
* 字符串是否至少一个为空白
*
* @param strs 字符串集合
* @return 是否为空白
*/
public static boolean isAnyBlank(String... strs) {
if (strs == null || strs.length == 0) {
return false;
}
for (String str : strs) {
if (isBlank(str)) {
return true;
}
}
return false;
}
/**
* 是否不为空白
*
* @param str 字符串
* @return 是否不为空白
*/
public static boolean isNotBlank(String str) {
return str != null && !str.isEmpty() && !str.isBlank();
}
/**
* 是否不为空白
*
* @param str 字符串
* @param fromIndex 起始位置
* @param toIndex 结束位置
* @return 是否为空白
*/
public static boolean isNotBlank(String str, int fromIndex, int toIndex) {
if (str == null || str.isEmpty()) {
return false;
}
for (int i = fromIndex; i < toIndex; i++) {
char ch = str.charAt(i);
if (ch != ' ' && ch != '\t' && !Character.isWhitespace(ch)) {
return true;
}
}
return false;
}
/**
* 是否为空
*
* @param str 字符串
* @return 是否为空
*/
public static boolean isEmpty(CharSequence str) {
return str == null || str.length() == 0;
}
/**
* 字符串是否至少一个为空
*
* @param strs 字符串集合
* @return 是否为空
*/
public static boolean isAnyEmpty(CharSequence... strs) {
if (strs == null || strs.length == 0) {
return false;
}
for (CharSequence str : strs) {
if (isEmpty(str)) {
return true;
}
}
return false;
}
/**
* 是否不为空
*
* @param str 字符串
* @return 是否不为空
*/
public static boolean isNotEmpty(CharSequence str) {
return str != null && str.length() > 0;
}
/**
* 是否为空
*
* @param map Map
* @return 是否为空
*/
public static boolean isEmpty(Map map) {
return map == null || map.isEmpty();
}
/**
* 是否不为空
*
* @param map Map
* @return 是否不为空
*/
public static boolean isNotEmpty(Map map) {
return map != null && !map.isEmpty();
}
/**
* 是否为空
*
* @param collection Collection
* @return 是否为空
*/
public static boolean isEmpty(Collection collection) {
return collection == null || collection.isEmpty();
}
/**
* 是否不为空
*
* @param collection Collection
* @return 是否不为空
*/
public static boolean isNotEmpty(Collection collection) {
return collection != null && !collection.isEmpty();
}
/**
* 是否为空
*
* @param <T> 泛型
* @param array 数组
* @return 是否为空
*/
public static <T> boolean isEmpty(T[] array) {
return array == null || array.length == 0;
}
/**
* 是否不为空
*
* @param <T> 泛型
* @param array 数组
* @return 是否不为空
*/
public static <T> boolean isNotEmpty(T[] array) {
return array != null && array.length > 0;
}
/**
* 是否为空
*
* @param array 数组
* @return 是否为空
*/
public static boolean isEmpty(byte[] array) {
return array == null || array.length == 0;
}
/**
* 是否不为空
*
* @param array 数组
* @return 是否不为空
*/
public static boolean isNotEmpty(byte[] array) {
return array != null && array.length > 0;
}
/**
* 是否为空
*
* @param array 数组
* @return 是否为空
*/
public static boolean isEmpty(short[] array) {
return array == null || array.length == 0;
}
/**
* 是否不为空
*
* @param array 数组
* @return 是否不为空
*/
public static boolean isNotEmpty(short[] array) {
return array != null && array.length > 0;
}
/**
* 是否为空
*
* @param array 数组
* @return 是否为空
*/
public static boolean isEmpty(int[] array) {
return array == null || array.length == 0;
}
/**
* 是否不为空
*
* @param array 数组
* @return 是否不为空
*/
public static boolean isNotEmpty(int[] array) {
return array != null && array.length > 0;
}
/**
* 是否为空
*
* @param array 数组
* @return 是否为空
*/
public static boolean isEmpty(long[] array) {
return array == null || array.length == 0;
}
/**
* 是否不为空
*
* @param array 数组
* @return 是否不为空
*/
public static boolean isNotEmpty(long[] array) {
return array != null && array.length > 0;
}
/**
* 是否为空
*
* @param array ByteArray
* @return 是否为空
*/
public static boolean isEmpty(ByteArray array) {
return array == null || array.isEmpty();
}
/**
* 是否不为空
*
* @param array ByteArray
* @return 是否不为空
*/
public static boolean isNotEmpty(ByteArray array) {
return array != null && !array.isEmpty();
}
/**
* 将字符串首字母大写
*
* @param str 字符串
* @return 首字母大写
*/
public static String firstCharUpperCase(String str) {
if (str == null || str.isEmpty()) {
return str;
}
if (Character.isUpperCase(str.charAt(0))) {
return str;
}
char[] chs = str.toCharArray();
chs[0] = Character.toUpperCase(chs[0]);
return new String(chs);
}
/**
* 将字符串首字母小写
*
* @param str 字符串
* @return 首字母小写
*/
public static String firstCharLowerCase(String str) {
if (str == null || str.isEmpty()) {
return str;
}
if (Character.isLowerCase(str.charAt(0))) {
return str;
}
char[] chs = str.toCharArray();
chs[0] = Character.toLowerCase(chs[0]);
return new String(chs);
}
public static boolean[] box(Boolean[] array) {
if (array == null) {
return null;
}
boolean[] rs = new boolean[array.length];
for (int i = 0; i < rs.length; i++) {
rs[i] = array[i] != null && array[i];
}
return rs;
}
public static Boolean[] box(boolean[] array) {
if (array == null) {
return null;
}
Boolean[] rs = new Boolean[array.length];
for (int i = 0; i < rs.length; i++) {
rs[i] = array[i];
}
return rs;
}
public static byte[] box(Byte[] array) {
if (array == null) {
return null;
}
byte[] rs = new byte[array.length];
for (int i = 0; i < rs.length; i++) {
rs[i] = array[i] == null ? 0 : array[i];
}
return rs;
}
public static Byte[] box(byte[] array) {
if (array == null) {
return null;
}
Byte[] rs = new Byte[array.length];
for (int i = 0; i < rs.length; i++) {
rs[i] = array[i];
}
return rs;
}
public static char[] box(Character[] array) {
if (array == null) {
return null;
}
char[] rs = new char[array.length];
for (int i = 0; i < rs.length; i++) {
rs[i] = array[i] == null ? 0 : array[i];
}
return rs;
}
public static Character[] box(char[] array) {
if (array == null) {
return null;
}
Character[] rs = new Character[array.length];
for (int i = 0; i < rs.length; i++) {
rs[i] = array[i];
}
return rs;
}
public static short[] box(Short[] array) {
if (array == null) {
return null;
}
short[] rs = new short[array.length];
for (int i = 0; i < rs.length; i++) {
rs[i] = array[i] == null ? 0 : array[i];
}
return rs;
}
public static Short[] box(short[] array) {
if (array == null) {
return null;
}
Short[] rs = new Short[array.length];
for (int i = 0; i < rs.length; i++) {
rs[i] = array[i];
}
return rs;
}
public static int[] box(Integer[] array) {
if (array == null) {
return null;
}
int[] rs = new int[array.length];
for (int i = 0; i < rs.length; i++) {
rs[i] = array[i] == null ? 0 : array[i];
}
return rs;
}
public static Integer[] box(int[] array) {
if (array == null) {
return null;
}
Integer[] rs = new Integer[array.length];
for (int i = 0; i < rs.length; i++) {
rs[i] = array[i];
}
return rs;
}
public static long[] box(Long[] array) {
if (array == null) {
return null;
}
long[] rs = new long[array.length];
for (int i = 0; i < rs.length; i++) {
rs[i] = array[i] == null ? 0 : array[i];
}
return rs;
}
public static Long[] box(long[] array) {
if (array == null) {
return null;
}
Long[] rs = new Long[array.length];
for (int i = 0; i < rs.length; i++) {
rs[i] = array[i];
}
return rs;
}
public static float[] box(Float[] array) {
if (array == null) {
return null;
}
float[] rs = new float[array.length];
for (int i = 0; i < rs.length; i++) {
rs[i] = array[i] == null ? 0 : array[i];
}
return rs;
}
public static Float[] box(float[] array) {
if (array == null) {
return null;
}
Float[] rs = new Float[array.length];
for (int i = 0; i < rs.length; i++) {
rs[i] = array[i];
}
return rs;
}
public static double[] box(Double[] array) {
if (array == null) {
return null;
}
double[] rs = new double[array.length];
for (int i = 0; i < rs.length; i++) {
rs[i] = array[i] == null ? 0 : array[i];
}
return rs;
}
public static Double[] box(double[] array) {
if (array == null) {
return null;
}
Double[] rs = new Double[array.length];
for (int i = 0; i < rs.length; i++) {
rs[i] = array[i];
}
return rs;
}
public static <T> boolean[] reverse(boolean[] array) {
if (array == null) {
return array;
}
boolean[] arr = array;
int start = 0;
int end = arr.length - 1;
while (start < end) {
boolean temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
start++;
end--;
}
return arr;
}
public static <T> byte[] reverse(byte[] array) {
if (array == null) {
return array;
}
byte[] arr = array;
int start = 0;
int end = arr.length - 1;
while (start < end) {
byte temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
start++;
end--;
}
return arr;
}
public static <T> char[] reverse(char[] array) {
if (array == null) {
return array;
}
char[] arr = array;
int start = 0;
int end = arr.length - 1;
while (start < end) {
char temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
start++;
end--;
}
return arr;
}
public static <T> short[] reverse(short[] array) {
if (array == null) {
return array;
}
short[] arr = array;
int start = 0;
int end = arr.length - 1;
while (start < end) {
short temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
start++;
end--;
}
return arr;
}
public static <T> int[] reverse(int[] array) {
if (array == null) {
return array;
}
int[] arr = array;
int start = 0;
int end = arr.length - 1;
while (start < end) {
int temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
start++;
end--;
}
return arr;
}
public static <T> long[] reverse(long[] array) {
if (array == null) {
return array;
}
long[] arr = array;
int start = 0;
int end = arr.length - 1;
while (start < end) {
long temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
start++;
end--;
}
return arr;
}
public static <T> float[] reverse(float[] array) {
if (array == null) {
return array;
}
float[] arr = array;
int start = 0;
int end = arr.length - 1;
while (start < end) {
float temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
start++;
end--;
}
return arr;
}
public static <T> double[] reverse(double[] array) {
if (array == null) {
return array;
}
double[] arr = array;
int start = 0;
int end = arr.length - 1;
while (start < end) {
double temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
start++;
end--;
}
return arr;
}
public static <T> T[] reverse(T[] array) {
if (array == null) {
return array;
}
T[] arr = array;
int start = 0;
int end = arr.length - 1;
while (start < end) {
T temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
start++;
end--;
}
return arr;
}
public static <T> List<T> reverse(List<T> list) {
if (list != null) {
Collections.reverse(list);
}
return list;
}
/**
* 将多个key:value对应值组合成一个Mapitems长度必须是偶数, 参数个数若是奇数的话,最后一个会被忽略 类似 JDK9中的 Map.of 方法
*
* @param <K> 泛型
* @param <V> 泛型
* @param items 键值对
* @return Map
*/
@ClassDepends
public static <K, V> HashMap<K, V> ofMap(Object... items) {
HashMap<K, V> map = new LinkedHashMap<>(Math.max(1, items.length / 2));
int len = items.length / 2;
for (int i = 0; i < len; i++) {
map.put((K) items[i * 2], (V) items[i * 2 + 1]);
}
return map;
}
/**
* 将多个Map合并到第一个Map中
*
* @param <K> 泛型
* @param <V> 泛型
* @param maps Map
* @return Map
*/
public static <K, V> Map<K, V> merge(Map<K, V>... maps) {
Map<K, V> map = null;
for (Map<K, V> m : maps) {
if (map == null) {
map = m;
} else if (m != null) {
map.putAll(m);
}
}
return map;
}
/**
* 将多个元素组合成一个Set
*
* @param <T> 泛型
* @param items 元素
* @return Set
*/
public static <T> Set<T> ofSet(T... items) {
Set<T> set = new LinkedHashSet<>(items.length);
for (T item : items) set.add(item);
return set;
}
/**
* 将多个元素组合成一个List <br>
* 类似 JDK9中的 List.of 方法
*
* @param <T> 泛型
* @param items 元素
* @return List
*/
public static <T> List<T> ofList(T... items) {
List<T> list = new ArrayList<>(items.length);
for (T item : items) list.add(item);
return list;
}
/**
* 将多个元素组合成一个Array
*
* @param <T> 泛型
* @param items 元素
* @return Array
*/
public static <T> T[] ofArray(T... items) {
return items;
}
/**
* 裁剪List使其size不超过limit大小 <br>
*
* @param <T> 泛型
* @param list 集合
* @param limit 大小
* @return List
*/
public static <T> List<T> limit(List<T> list, int limit) {
if (list == null || list.isEmpty() || list.size() <= limit) {
return list;
}
return list.subList(0, limit);
}
/**
* 获取不带"-"的UUID值
*
* @return 不带"-"UUID值
*/
public static String uuid() {
return UUID.randomUUID().toString().replace("-", "");
}
/**
* 比较两个版本号的大小ver1小于ver2返回 -1
*
* @param version1 版本号
* @param version2 版本号
* @return 版本大小
*/
public static int compareVersion(String version1, String version2) {
if (isEmpty(version1)) {
return isEmpty(version2) ? 0 : -1;
}
if (isEmpty(version2)) {
return 1;
}
String[] ver1 = version1.split("\\.");
String[] ver2 = version2.split("\\.");
int len = Math.min(ver1.length, ver2.length);
for (int i = 0; i < len; i++) {
if (ver1[i].length() > ver2[i].length()) {
return 1;
}
if (ver1[i].length() < ver2[i].length()) {
return -1;
}
int v = Integer.parseInt(ver1[i]) - Integer.parseInt(ver2[i]);
if (v != 0) {
return v > 0 ? 1 : -1;
}
}
return 0;
}
/**
* 排序, 值大排前面
* @param <P> 泛型
* @param list 集合
* @return 排序后的集合
*/
public static <P> List<P> sortPriority(List<P> list) {
Collections.sort(list, (a, b) -> {
Priority p1 = a == null ? null : a.getClass().getAnnotation(Priority.class);
Priority p2 = b == null ? null : b.getClass().getAnnotation(Priority.class);
return (p2 == null ? 0 : p2.value()) - (p1 == null ? 0 : p1.value());
});
return list;
}
/**
* 将一个或多个新元素添加到数组开始,数组中的元素自动后移
*
* @param <T> 泛型
* @param array 原数组
* @param objs 待追加数据
* @return 新数组
*/
public static <T> T[] unshift(final T[] array, final T... objs) {
if (array == null || array.length == 0) {
return objs;
}
final T[] news = (T[]) Creator.newArray(array.getClass().getComponentType(), array.length + objs.length);
System.arraycopy(objs, 0, news, 0, objs.length);
System.arraycopy(array, 0, news, objs.length, array.length);
return news;
}
/**
* 将一个或多个新元素添加到数组开始,数组中的元素自动后移
*
* @param <T> 泛型
* @param array 原数组
* @param objs 待追加数据
* @return 新数组
*/
public static <T> T[] unshift(final T[] array, final Collection<T> objs) {
if (objs == null || objs.isEmpty()) {
return array;
}
if (array == null) {
T one = null;
for (T t : objs) {
if (t != null) {
one = t;
}
break;
}
if (one == null) {
return array;
}
T[] news = (T[]) Creator.newArray(one.getClass(), objs.size());
return objs.toArray(news);
}
T[] news = (T[]) Creator.newArray(array.getClass().getComponentType(), array.length + objs.size());
int index = -1;
for (T t : objs) {
news[(++index)] = t;
}
System.arraycopy(array, 0, news, objs.size(), array.length);
return news;
}
/**
* 获取int数组之和, 空数组返回0
*
* @param array 数组
* @return int
*/
public static int sum(final int... array) {
return sum(false, array);
}
/**
* 获取int数组之和
*
* @param check 是否检测空
* @param array 数组
* @return int
*/
public static int sum(boolean check, final int... array) {
if (array == null || array.length == 0) {
if (!check) {
return 0;
}
throw new NullPointerException("array is null or empty");
}
int sum = 0;
for (int i : array) {
sum += i;
}
return sum;
}
/**
* 获取long数组之和, 空数组返回0
*
* @param array 数组
* @return long
*/
public static long sum(final long... array) {
return sum(false, array);
}
/**
* 获取long数组之和
*
* @param check 是否检测空
* @param array 数组
* @return long
*/
public static long sum(boolean check, final long... array) {
if (array == null || array.length == 0) {
if (!check) {
return 0;
}
throw new NullPointerException("array is null or empty");
}
long sum = 0L;
for (long i : array) {
sum += i;
}
return sum;
}
/**
* 获取int数组最大值
*
* @param array 数组
* @return int
*/
public static int max(final int... array) {
if (array == null || array.length == 0) {
throw new NullPointerException("array is null or empty");
}
int max = array[0];
for (int i : array) {
if (i > max) {
i = max;
}
}
return max;
}
/**
* 获取long数组最大值
*
* @param array 数组
* @return long
*/
public static long max(final long... array) {
if (array == null || array.length == 0) {
throw new NullPointerException("array is null or empty");
}
long max = array[0];
for (long i : array) {
if (i > max) {
i = max;
}
}
return max;
}
/**
* 获取int数组最小值
*
* @param array 数组
* @return int
*/
public static long min(final int... array) {
if (array == null || array.length == 0) {
throw new NullPointerException("array is null or empty");
}
int min = array[0];
for (int i : array) {
if (i < min) {
i = min;
}
}
return min;
}
/**
* 获取long数组最小值
*
* @param array 数组
* @return long
*/
public static long min(final long... array) {
if (array == null || array.length == 0) {
throw new NullPointerException("array is null or empty");
}
long min = array[0];
for (long i : array) {
if (i < min) {
i = min;
}
}
return min;
}
/**
* 将char数组用分隔符拼接成字符串
*
* @param array 数组
* @param delimiter 分隔符
* @return String
*/
public static String joining(final char[] array, final String delimiter) {
if (array == null || array.length == 0) {
return "";
}
StringBuilder sb = new StringBuilder();
for (char i : array) {
if (sb.length() > 0) {
sb.append(delimiter);
}
sb.append(i);
}
return sb.toString();
}
/**
* 将int数组用分隔符拼接成字符串
*
* @param array 数组
* @param delimiter 分隔符
* @return String
*/
public static String joining(final int[] array, final String delimiter) {
if (array == null || array.length == 0) {
return "";
}
StringBuilder sb = new StringBuilder();
for (int i : array) {
if (sb.length() > 0) {
sb.append(delimiter);
}
sb.append(i);
}
return sb.toString();
}
/**
* 将long数组用分隔符拼接成字符串
*
* @param array 数组
* @param delimiter 分隔符
* @return String
*/
public static String joining(final long[] array, final String delimiter) {
if (array == null || array.length == 0) {
return "";
}
StringBuilder sb = new StringBuilder();
for (long i : array) {
if (sb.length() > 0) {
sb.append(delimiter);
}
sb.append(i);
}
return sb.toString();
}
/**
* 将对象数组用分隔符拼接成字符串
*
* @param <T> 泛型
* @param array 数组
* @param delimiter 分隔符
* @return String
*/
public static <T> String joining(final T[] array, final String delimiter) {
if (array == null || array.length == 0) {
return "";
}
StringBuilder sb = new StringBuilder();
for (T i : array) {
if (sb.length() > 0) {
sb.append(delimiter);
}
sb.append(i);
}
return sb.toString();
}
/**
* 将对象集合用分隔符拼接成字符串
*
* @param <T> 泛型
* @param stream 集合
* @param delimiter 分隔符
* @return String
*/
public static <T> String joining(final Stream<T> stream, final String delimiter) {
if (stream == null) {
return "";
}
StringBuilder sb = new StringBuilder();
stream.forEach(i -> {
if (sb.length() > 0) {
sb.append(delimiter);
}
sb.append(i);
});
return sb.toString();
}
/**
* 将对象数组用分隔符拼接成字符串
*
* @param <T> 泛型
* @param array 数组
* @param delimiter 分隔符
* @return String
*/
public static <T> String joining(final String[] array, final char delimiter) {
if (array == null || array.length == 0) {
return "";
}
StringBuilder sb = new StringBuilder();
for (String i : array) {
if (sb.length() > 0) {
sb.append(delimiter);
}
sb.append(i);
}
return sb.toString();
}
/**
* 将对象数组用分隔符拼接成字符串
*
* @param <T> 泛型
* @param array 数组
* @param delimiter 分隔符
* @return String
*/
public static <T> String joiningHex(final byte[] array, final char delimiter) {
if (array == null || array.length == 0) {
return "";
}
StringBuilder sb = new StringBuilder();
for (byte i : array) {
if (sb.length() > 0) {
sb.append(delimiter);
}
String s = Integer.toHexString(i & 0xff);
sb.append(s.length() > 1 ? "0x" : "0x0").append(s);
}
return sb.toString();
}
/**
* 将对象数组用分隔符拼接成字符串
*
* @param <T> 泛型
* @param array 数组
* @param offset 偏移量
* @param length 长度
* @param delimiter 分隔符
* @return String
*/
public static <T> String joiningHex(final byte[] array, int offset, int length, final char delimiter) {
if (array == null || array.length == 0) {
return "";
}
StringBuilder sb = new StringBuilder();
int len = offset + length;
for (int i = offset; i < len; i++) {
if (sb.length() > 0) {
sb.append(delimiter);
}
String s = Integer.toHexString(array[i] & 0xff);
sb.append(s.length() > 1 ? "0x" : "0x0").append(s);
}
return sb.toString();
}
/**
* 将一个或多个byte新元素添加到byte数组结尾
*
* @param array 原数组
* @param objs 待追加数据
* @return 新数组
*/
public static byte[] append(final byte[] array, final byte... objs) {
if (array == null || array.length == 0) {
return objs;
}
if (objs == null || objs.length == 0) {
return array;
}
final byte[] news = new byte[array.length + objs.length];
System.arraycopy(array, 0, news, 0, array.length);
System.arraycopy(objs, 0, news, array.length, objs.length);
return news;
}
/**
* 将一个或多个byte新元素添加到byte数组结尾
*
* @param array 原数组
* @param objs 待追加数据
* @param offset 待追加数据偏移量
* @param length 待追加数据的长度
* @return 新数组
*/
public static byte[] append(final byte[] array, final byte[] objs, int offset, int length) {
if (array == null || array.length == 0) {
if (objs != null && offset == 0 && objs.length == length) {
return objs;
}
final byte[] news = new byte[length];
System.arraycopy(objs, 0, news, 0, length);
return news;
}
if (objs == null || length == 0) {
return array;
}
final byte[] news = new byte[array.length + length];
System.arraycopy(array, 0, news, 0, array.length);
System.arraycopy(objs, offset, news, array.length, length);
return news;
}
/**
* 将一个或多个short新元素添加到short数组结尾
*
* @param array 原数组
* @param objs 待追加数据
* @return 新数组
*/
public static short[] append(final short[] array, final short... objs) {
if (array == null || array.length == 0) {
return objs;
}
if (objs == null || objs.length == 0) {
return array;
}
final short[] news = new short[array.length + objs.length];
System.arraycopy(array, 0, news, 0, array.length);
System.arraycopy(objs, 0, news, array.length, objs.length);
return news;
}
/**
* 将一个或多个char新元素添加到char数组结尾
*
* @param array 原数组
* @param objs 待追加数据
* @return 新数组
*/
public static char[] append(final char[] array, final char... objs) {
if (array == null || array.length == 0) {
return objs;
}
if (objs == null || objs.length == 0) {
return array;
}
final char[] news = new char[array.length + objs.length];
System.arraycopy(array, 0, news, 0, array.length);
System.arraycopy(objs, 0, news, array.length, objs.length);
return news;
}
/**
* 将一个或多个int新元素添加到int数组结尾
*
* @param array 原数组
* @param objs 待追加数据
* @return 新数组
*/
public static int[] append(final int[] array, final int... objs) {
if (array == null || array.length == 0) {
return objs;
}
if (objs == null || objs.length == 0) {
return array;
}
final int[] news = new int[array.length + objs.length];
System.arraycopy(array, 0, news, 0, array.length);
System.arraycopy(objs, 0, news, array.length, objs.length);
return news;
}
/**
* 将一个或多个long新元素添加到long数组结尾
*
* @param array 原数组
* @param objs 待追加数据
* @return 新数组
*/
public static long[] append(final long[] array, final long... objs) {
if (array == null || array.length == 0) {
return objs;
}
if (objs == null || objs.length == 0) {
return array;
}
final long[] news = new long[array.length + objs.length];
System.arraycopy(array, 0, news, 0, array.length);
System.arraycopy(objs, 0, news, array.length, objs.length);
return news;
}
/**
* 将一个或多个新元素添加到数组结尾
*
* @param array 原数组
* @param objs 待追加数据
* @return 新数组
*/
public static String[] append(final String[] array, final String... objs) {
if (array == null || array.length == 0) {
return objs;
}
if (objs == null || objs.length == 0) {
return array;
}
final String[] news = new String[array.length + objs.length];
System.arraycopy(array, 0, news, 0, array.length);
System.arraycopy(objs, 0, news, array.length, objs.length);
return news;
}
/**
* 将一个或多个新元素添加到数组结尾
*
* @param one 单个对象
* @param objs 待追加数据
* @return 新数组
*/
public static String[] append(final String one, final String... objs) {
if (one == null) {
return objs;
}
final String[] news = new String[1 + objs.length];
news[0] = one;
System.arraycopy(objs, 0, news, 1, objs.length);
return news;
}
/**
* 将一个或多个新元素添加到数组结尾
*
* @param one 单个对象
* @param two 单个对象
* @param objs 待追加数据
* @return 新数组
*/
public static String[] append(final String one, String two, final String... objs) {
final String[] news = new String[2 + objs.length];
news[0] = one;
news[1] = two;
System.arraycopy(objs, 0, news, 2, objs.length);
return news;
}
/**
* 将一个或多个新元素添加到数组结尾
*
* @param <T> 泛型
* @param array 原数组
* @param objs 待追加数据
* @return 新数组
*/
public static <T> T[] append(final T[] array, final T... objs) {
if (array == null || array.length == 0) {
return objs;
}
if (objs == null || objs.length == 0) {
return array;
}
final T[] news = (T[]) Creator.newArray(array.getClass().getComponentType(), array.length + objs.length);
System.arraycopy(array, 0, news, 0, array.length);
System.arraycopy(objs, 0, news, array.length, objs.length);
return news;
}
/**
* 将一个或多个新元素添加到数组结尾
*
* @param <T> 泛型
* @param array 原数组
* @param objs 待追加数据
* @return 新数组
*/
public static <T> Object[][] append(final Object[][] array, final Object[]... objs) {
if (array == null || array.length == 0) {
return objs;
}
if (objs == null || objs.length == 0) {
return array;
}
final Object[][] news = new Object[array.length + objs.length][];
System.arraycopy(array, 0, news, 0, array.length);
System.arraycopy(objs, 0, news, array.length, objs.length);
return news;
}
/**
* 将一个或多个新元素添加到数组结尾
*
* @param <T> 泛型
* @param array 原数组
* @param objs 待追加数据
* @return 新数组
*/
public static <T> T[] append(final T[] array, final Collection<T> objs) {
if (objs == null || objs.isEmpty()) {
return array;
}
if (array == null) {
T one = null;
for (T t : objs) {
if (t != null) {
one = t;
}
break;
}
if (one == null) {
return array;
}
T[] news = (T[]) Creator.newArray(one.getClass(), objs.size());
return objs.toArray(news);
}
T[] news = (T[]) Creator.newArray(array.getClass().getComponentType(), array.length + objs.size());
System.arraycopy(array, 0, news, 0, array.length);
int index = -1;
for (T t : objs) {
news[array.length + (++index)] = t;
}
return news;
}
/**
* 将元素从数组中删除
*
* @param <T> 泛型
* @param array 原数组
* @param item 元素
* @return 新数组
*/
public static <T> T[] remove(final T[] array, final T item) {
return remove(array, (i) -> Objects.equals(i, item));
}
/**
* 将符合条件的元素从数组中删除
*
* @param <T> 泛型
* @param array 原数组
* @param filter Predicate
* @return 新数组
*/
public static <T> T[] remove(final T[] array, final Predicate filter) {
if (array == null || array.length == 0 || filter == null) {
return array;
}
final T[] news = (T[]) Creator.newArray(array.getClass().getComponentType(), array.length);
int index = 0;
for (int i = 0; i < news.length; i++) {
if (!filter.test(array[i])) {
news[index++] = array[i];
}
}
if (index == array.length) {
return array;
}
final T[] rs = (T[]) Creator.newArray(array.getClass().getComponentType(), index);
System.arraycopy(news, 0, rs, 0, index);
return rs;
}
/**
* 将符合条件的元素从数组中删除
*
* @param array 原数组
* @param item 元素
* @return 新数组
*/
public static String[] remove(final String[] array, final String item) {
if (array == null || array.length == 0) {
return array;
}
final String[] news = new String[array.length];
int index = 0;
for (int i = 0; i < news.length; i++) {
if (item != null && !item.equals(array[i])) {
news[index++] = array[i];
} else if (item == null && array[i] != null) {
news[index++] = array[i];
}
}
if (index == array.length) {
return array;
}
final String[] rs = new String[index];
System.arraycopy(news, 0, rs, 0, index);
return rs;
}
/**
* 将指定的long元素从数组中删除, 相同的元素会根据items里重复次数来执行删除 <br>
* 例如: <br>
* remove(new short[]{1, 1, 1, 2, 2, 3, 3, 3}, false, 1, 1, 2, 3, 3) = [1,2,3]<br>
*
* @param array 原数组
* @param items short[]
* @return 新数组
*/
public static short[] removeMatch(final short[] array, final short... items) {
return remove(array, false, items);
}
/**
* 将指定的int元素从数组中删除, repeat=true时相同的元素会根据items里重复次数来执行删除 <br>
* 例如: <br>
* remove(new short[]{1, 1, 1, 2, 2, 3, 3, 3}, true, 1, 1, 2, 3, 3) = [] <br>
* remove(new short[]{1, 1, 1, 2, 2, 3, 3, 3}, false, 1, 1, 2, 3, 3) = [1,2,3]
*
* @param array 原数组
* @param repeat 是否重复删除相同的元素
* @param items short[]
* @return 新数组
*/
public static short[] remove(final short[] array, boolean repeat, final short... items) {
if (array == null || array.length == 0 || items == null || items.length == 0) {
return array;
}
final short[] news = new short[array.length];
short[] subs = items;
int index = 0;
for (int i = 0; i < news.length; i++) {
if (subs.length > 0 && contains(subs, array[i])) {
if (!repeat) {
short[] newsubs = new short[subs.length - 1];
int k = 0;
boolean done = false;
for (short v : subs) {
if (done) {
newsubs[k++] = v;
} else if (v == array[i]) {
done = true;
} else {
newsubs[k++] = v;
}
}
subs = newsubs;
}
} else {
news[index++] = array[i];
}
}
if (index == array.length) {
return array;
}
final short[] rs = new short[index];
System.arraycopy(news, 0, rs, 0, index);
return rs;
}
/**
* 将指定的long元素从数组中删除, 相同的元素会根据items里重复次数来执行删除 <br>
* 例如: <br>
* remove(new int[]{1, 1, 1, 2, 2, 3, 3, 3}, false, 1, 1, 2, 3, 3) = [1,2,3]<br>
*
* @param array 原数组
* @param items int[]
* @return 新数组
*/
public static int[] removeMatch(final int[] array, final int... items) {
return remove(array, false, items);
}
/**
* 将指定的int元素从数组中删除, repeat=false时相同的元素会根据items里重复次数来执行删除 <br>
* 例如: <br>
* remove(new int[]{1, 1, 1, 2, 2, 3, 3, 3}, true, 1, 1, 2, 3, 3) = [] <br>
* remove(new int[]{1, 1, 1, 2, 2, 3, 3, 3}, false, 1, 1, 2, 3, 3) = [1,2,3]
*
* @param array 原数组
* @param repeat 是否重复删除相同的元素
* @param items int[]
* @return 新数组
*/
public static int[] remove(final int[] array, boolean repeat, final int... items) {
if (array == null || array.length == 0 || items == null || items.length == 0) {
return array;
}
final int[] news = new int[array.length];
int[] subs = items;
int index = 0;
for (int i = 0; i < news.length; i++) {
if (subs.length > 0 && contains(subs, array[i])) {
if (!repeat) {
int[] newsubs = new int[subs.length - 1];
int k = 0;
boolean done = false;
for (int v : subs) {
if (done) {
newsubs[k++] = v;
} else if (v == array[i]) {
done = true;
} else {
newsubs[k++] = v;
}
}
subs = newsubs;
}
} else {
news[index++] = array[i];
}
}
if (index == array.length) {
return array;
}
final int[] rs = new int[index];
System.arraycopy(news, 0, rs, 0, index);
return rs;
}
/**
* 将指定的long元素从数组中删除, 相同的元素会根据items里重复次数来执行删除 <br>
* 例如: <br>
* remove(new long[]{1, 1, 1, 2, 2, 3, 3, 3}, false, 1, 1, 2, 3, 3) = [1,2,3]<br>
*
* @param array 原数组
* @param items long[]
* @return 新数组
*/
public static long[] removeMatch(final long[] array, final long... items) {
return remove(array, false, items);
}
/**
* 将指定的long元素从数组中删除, repeat=false时相同的元素会根据items里重复次数来执行删除 <br>
* 例如: <br>
* remove(new long[]{1, 1, 1, 2, 2, 3, 3, 3}, true, 1, 1, 2, 3, 3) = [] <br>
* remove(new long[]{1, 1, 1, 2, 2, 3, 3, 3}, false, 1, 1, 2, 3, 3) = [1,2,3]<br>
*
* @param array 原数组
* @param repeat 是否重复删除相同的元素
* @param items long[]
* @return 新数组
*/
public static long[] remove(final long[] array, boolean repeat, final long... items) {
if (array == null || array.length == 0 || items == null || items.length == 0) {
return array;
}
final long[] news = new long[array.length];
long[] subs = items;
int index = 0;
for (int i = 0; i < news.length; i++) {
if (subs.length > 0 && contains(subs, array[i])) {
if (!repeat) {
long[] newsubs = new long[subs.length - 1];
int k = 0;
boolean done = false;
for (long v : subs) {
if (done) {
newsubs[k++] = v;
} else if (v == array[i]) {
done = true;
} else {
newsubs[k++] = v;
}
}
subs = newsubs;
}
} else {
news[index++] = array[i];
}
}
if (index == array.length) {
return array;
}
final long[] rs = new long[index];
System.arraycopy(news, 0, rs, 0, index);
return rs;
}
/**
* 将符合条件的元素从集合中删除
*
* @param <T> 泛型
* @param objs 原集合
* @param filter Predicate
* @return 新集合
*/
public static <T> Collection<T> remove(final Collection<T> objs, Predicate filter) {
if (objs == null || filter == null) {
return objs;
}
List<T> list = new ArrayList<>();
for (T t : objs) {
if (filter.test(t)) {
list.add(t);
}
}
if (!list.isEmpty()) {
objs.removeAll(list);
}
return objs;
}
/**
* 判断字符串是否包含指定的字符包含返回true
*
* @param string 字符串
* @param values 字符集合
* @return boolean
*/
public static boolean contains(String string, char... values) {
if (string == null) {
return false;
}
for (char ch : Utility.charArray(string)) {
for (char ch2 : values) {
if (ch == ch2) {
return true;
}
}
}
return false;
}
/**
* 比较两集合元素是否一样, 顺序不要求一样
*
* @param <T> 泛型
* @param array1 集合
* @param array2 集合
* @return 元素是否完全相同
*/
public static <T> boolean equalsElement(T[] array1, T[] array2) {
if (array1 == null && array2 == null) {
return true;
}
if (array1 == null || array2 == null) {
return false;
}
if (array1.length != array2.length) {
return false;
}
return equalsElement(ofList(array1), ofList(array2));
}
/**
* 比较两集合元素是否一样, 顺序不要求一样
*
* @param <T> 泛型
* @param col1 集合
* @param col2 集合
* @return 元素是否完全相同
*/
public static <T> boolean equalsElement(Collection<T> col1, Collection<T> col2) {
if (col1 == null && col2 == null) {
return true;
}
if (col1 == null || col2 == null) {
return false;
}
if (col1.size() != col2.size()) {
return false;
}
// {1,2,2}, {1,1,2}
List<T> list = new ArrayList<>(col2);
for (T item : col1) {
if (!list.remove(item)) {
return false;
}
}
return list.isEmpty();
}
/**
* 比较两集合元素是否一样, 顺序不要求一样
*
* @param <K> 泛型
* @param <V> 泛型
* @param map1 集合
* @param map2 集合
* @return 元素是否完全相同
*/
public static <K, V> boolean equalsElement(Map<K, V> map1, Map<K, V> map2) {
if (map1 == null && map2 == null) {
return true;
}
if (map1 == null || map2 == null) {
return false;
}
if (map1.size() != map2.size()) {
return false;
}
for (Map.Entry<K, V> en : map1.entrySet()) {
if (!Objects.equals(en.getValue(), map2.get(en.getKey()))) {
return false;
}
}
return true;
}
/**
* 判断指定值是否包含指定的数组中包含返回true
*
* @param values 集合
* @param value 单值
* @return boolean
*/
public static boolean contains(char[] values, char value) {
if (values == null) {
return false;
}
for (char v : values) {
if (v == value) {
return true;
}
}
return false;
}
/**
* 判断指定值是否包含指定的数组中包含返回true
*
* @param values 集合
* @param value 单值
* @return boolean
*/
public static boolean contains(short[] values, short value) {
if (values == null) {
return false;
}
for (short v : values) {
if (v == value) {
return true;
}
}
return false;
}
/**
* 判断指定值(不要包含相同的元素)是否包含指定的数组中包含返回true
*
* @param values 集合
* @param items 多值
* @return boolean
*/
public static boolean contains(short[] values, short... items) {
if (values == null) {
return false;
}
for (short item : items) {
if (!contains(values, item)) {
return false;
}
}
return true;
}
/**
* 判断指定值是否包含指定的数组中包含返回true
*
* @param values 集合
* @param value 单值
* @return boolean
*/
public static boolean contains(int[] values, int value) {
if (values == null) {
return false;
}
for (int v : values) {
if (v == value) {
return true;
}
}
return false;
}
/**
* 判断指定值(不要包含相同的元素)是否包含指定的数组中包含返回true
*
* @param values 集合
* @param items 多值
* @return boolean
*/
public static boolean contains(int[] values, int... items) {
if (values == null) {
return false;
}
for (int item : items) {
if (!contains(values, item)) {
return false;
}
}
return true;
}
/**
* 判断指定值是否包含指定的数组中包含返回true
*
* @param values 集合
* @param value 单值
* @return boolean
*/
public static boolean contains(long[] values, long value) {
if (values == null) {
return false;
}
for (long v : values) {
if (v == value) {
return true;
}
}
return false;
}
/**
* 判断指定值(不要包含相同的元素)是否包含指定的数组中包含返回true
*
* @param values 集合
* @param items 多值
* @return boolean
*/
public static boolean contains(long[] values, long... items) {
if (values == null) {
return false;
}
for (long item : items) {
if (!contains(values, item)) {
return false;
}
}
return true;
}
/**
* 判断指定值是否包含指定的数组中包含返回true
*
* @param <T> 泛型
* @param values 集合
* @param value 单值
* @return boolean
*/
public static <T> boolean contains(T[] values, T value) {
if (values == null) {
return false;
}
for (T v : values) {
if (Objects.equals(v, value)) {
return true;
}
}
return false;
}
/**
* 判断指定值是否包含指定的数组中包含返回true
*
* @param <T> 泛型
* @param values 集合
* @param predicate 过滤条件
* @return boolean
*/
public static <T> boolean contains(T[] values, Predicate<T> predicate) {
if (values == null) {
return false;
}
for (T v : values) {
if (predicate.test(v)) {
return true;
}
}
return false;
}
/**
* 判断指定值是否包含指定的数组中包含返回true
*
* @param <T> 泛型
* @param values 集合
* @param predicate 过滤条件
* @return boolean
*/
public static <T> boolean contains(Collection<T> values, Predicate<T> predicate) {
if (values == null) {
return false;
}
for (T v : values) {
if (predicate.test(v)) {
return true;
}
}
return false;
}
/**
* 将指定的short元素是否数组中完全包含重复元素的次数也要相同 <br>
* 例如: <br>
* containsMatch(new short[]{1, 2, 2, 3, 3, 3}, 1, 2, 3, 3) = true <br>
* containsMatch(new short[]{1, 2, 2, 3, 3, 3}, 1, 1, 2, 3, 3) = false <br>
*
* @param array 原数组
* @param items short[]
* @return 是否完全包含
*/
public static boolean containsMatch(final short[] array, final short... items) {
if (array == null) {
return false;
}
if (items == null || items.length == 0) {
return true;
}
if (array.length == 0 && items.length == 0) {
return true;
}
if (array.length < items.length) {
return false;
}
short[] subs = array;
for (short item : items) {
if (!contains(subs, item)) {
return false;
}
short[] newsubs = new short[subs.length - 1];
int k = 0;
boolean done = false;
for (short v : subs) {
if (done) {
newsubs[k++] = v;
} else if (v == item) {
done = true;
} else {
newsubs[k++] = v;
}
}
subs = newsubs;
}
return true;
}
/**
* 将指定的int元素是否数组中完全包含重复元素的次数也要相同 <br>
* 例如: <br>
* containsMatch(new int[]{1, 2, 2, 3, 3, 3}, 1, 2, 3, 3) = true <br>
* containsMatch(new int[]{1, 2, 2, 3, 3, 3}, 1, 1, 2, 3, 3) = false <br>
*
* @param array 原数组
* @param items int[]
* @return 是否完全包含
*/
public static boolean containsMatch(final int[] array, final int... items) {
if (array == null) {
return false;
}
if (items == null || items.length == 0) {
return true;
}
if (array.length == 0 && items.length == 0) {
return true;
}
if (array.length < items.length) {
return false;
}
int[] subs = array;
for (int item : items) {
if (!contains(subs, item)) {
return false;
}
int[] newsubs = new int[subs.length - 1];
int k = 0;
boolean done = false;
for (int v : subs) {
if (done) {
newsubs[k++] = v;
} else if (v == item) {
done = true;
} else {
newsubs[k++] = v;
}
}
subs = newsubs;
}
return true;
}
/**
* 将指定的long元素是否数组中完全包含重复元素的次数也要相同 <br>
* 例如: <br>
* containsMatch(new long[]{1, 2, 2, 3, 3, 3}, 1, 2, 3, 3) = true <br>
* containsMatch(new long[]{1, 2, 2, 3, 3, 3}, 1, 1, 2, 3, 3) = false <br>
*
* @param array 原数组
* @param items long[]
* @return 是否完全包含
*/
public static boolean containsMatch(final long[] array, final long... items) {
if (array == null) {
return false;
}
if (items == null || items.length == 0) {
return true;
}
if (array.length == 0 && items.length == 0) {
return true;
}
if (array.length < items.length) {
return false;
}
long[] subs = array;
for (long item : items) {
if (!contains(subs, item)) {
return false;
}
long[] newsubs = new long[subs.length - 1];
int k = 0;
boolean done = false;
for (long v : subs) {
if (done) {
newsubs[k++] = v;
} else if (v == item) {
done = true;
} else {
newsubs[k++] = v;
}
}
subs = newsubs;
}
return true;
}
/**
* 删除掉字符串数组中包含指定的字符串
*
* @param columns 待删除数组
* @param cols 需排除的字符串
* @return 新字符串数组
*/
public static String[] exclude(final String[] columns, final String... cols) {
if (columns == null || columns.length == 0 || cols == null || cols.length == 0) {
return columns;
}
int count = 0;
for (String column : columns) {
boolean flag = false;
for (String col : cols) {
if (column != null && column.equals(col)) {
flag = true;
break;
}
}
if (flag) {
count++;
}
}
if (count == 0) {
return columns;
}
if (count == columns.length) {
return new String[0];
}
final String[] newcols = new String[columns.length - count];
count = 0;
for (String column : columns) {
boolean flag = false;
for (String col : cols) {
if (column != null && column.equals(col)) {
flag = true;
break;
}
}
if (!flag) {
newcols[count++] = column;
}
}
return newcols;
}
/**
* 查询指定对象, 没有返回null
*
* @param <T> 泛型
* @param array 数组
* @param predicate 查找器
* @return 对象
*/
public static <T> T find(final T[] array, final Predicate<T> predicate) {
if (array == null) {
return null;
}
for (T item : array) {
if (item != null && predicate.test(item)) {
return item;
}
}
return null;
}
/**
* 查询指定对象, 没有返回null
*
* @param <T> 泛型
* @param array 数组
* @param predicate 查找器
* @return 对象
*/
public static <T> T find(final Collection<T> array, final Predicate<T> predicate) {
if (array == null) {
return null;
}
for (T item : array) {
if (item != null && predicate.test(item)) {
return item;
}
}
return null;
}
/**
* 查询指定对象位置, 没有返回-1
*
* @param <T> 泛型
* @param array 数组
* @param predicate 查找器
* @return 位置
*/
public static <T> int indexOf(final T[] array, final Predicate<T> predicate) {
if (array == null) {
return -1;
}
int index = -1;
for (T item : array) {
++index;
if (item != null && predicate.test(item)) {
return index;
}
}
return -1;
}
/**
* 查询指定对象位置, 没有返回-1
*
* @param <T> 泛型
* @param array 数组
* @param predicate 查找器
* @return 位置
*/
public static <T> int indexOf(final Collection<T> array, final Predicate<T> predicate) {
if (array == null) {
return -1;
}
int index = -1;
for (T item : array) {
++index;
if (item != null && predicate.test(item)) {
return index;
}
}
return -1;
}
/**
* 查询指定值位置, 没有返回-1
*
* @param array 数组
* @param element 指定值
* @return 位置
*/
public static int indexOf(final byte[] array, final byte element) {
if (array == null) {
return -1;
}
for (int i = 0; i < array.length; ++i) {
if (array[i] == element) {
return i;
}
}
return -1;
}
/**
* 查询指定值位置, 没有返回-1
*
* @param array 数组
* @param fromIndex 起始位置从0开始
* @param element 指定值
* @return 位置
*/
public static int indexOf(final byte[] array, int fromIndex, final byte element) {
if (array == null) {
return -1;
}
for (int i = fromIndex; i < array.length; ++i) {
if (array[i] == element) {
return i;
}
}
return -1;
}
/**
* 查询指定值位置, 没有返回-1
*
* @param array 数组
* @param element 指定值
* @return 位置
*/
public static int indexOf(final short[] array, final short element) {
return indexOf(array, 0, element);
}
/**
* 查询指定值位置, 没有返回-1
*
* @param array 数组
* @param fromIndex 起始位置从0开始
* @param element 指定值
* @return 位置
*/
public static int indexOf(final short[] array, int fromIndex, final short element) {
if (array == null) {
return -1;
}
for (int i = fromIndex; i < array.length; ++i) {
if (array[i] == element) {
return i;
}
}
return -1;
}
/**
* 查询指定值位置, 没有返回-1
*
* @param array 数组
* @param element 指定值
* @return 位置
*/
public static int indexOf(final char[] array, final char element) {
return indexOf(array, 0, element);
}
/**
* 查询指定值位置, 没有返回-1
*
* @param array 数组
* @param fromIndex 起始位置从0开始
* @param element 指定值
* @return 位置
*/
public static int indexOf(final char[] array, int fromIndex, final char element) {
if (array == null) {
return -1;
}
for (int i = fromIndex; i < array.length; ++i) {
if (array[i] == element) {
return i;
}
}
return -1;
}
/**
* 查询指定值位置, 没有返回-1
*
* @param array 数组
* @param element 指定值
* @return 位置
*/
public static int indexOf(final int[] array, final int element) {
return indexOf(array, 0, element);
}
/**
* 查询指定值位置, 没有返回-1
*
* @param array 数组
* @param fromIndex 起始位置从0开始
* @param element 指定值
* @return 位置
*/
public static int indexOf(final int[] array, int fromIndex, final int element) {
if (array == null) {
return -1;
}
for (int i = fromIndex; i < array.length; ++i) {
if (array[i] == element) {
return i;
}
}
return -1;
}
/**
* 查询指定值位置, 没有返回-1
*
* @param array 数组
* @param element 指定值
* @return 位置
*/
public static int indexOf(final long[] array, final long element) {
return indexOf(array, 0, element);
}
/**
* 查询指定值位置, 没有返回-1
*
* @param array 数组
* @param fromIndex 起始位置从0开始
* @param element 指定值
* @return 位置
*/
public static int indexOf(final long[] array, int fromIndex, final long element) {
if (array == null) {
return -1;
}
for (int i = fromIndex; i < array.length; ++i) {
if (array[i] == element) {
return i;
}
}
return -1;
}
/**
* 查询指定值位置, 没有返回-1
*
* @param array 数组
* @param element 指定值
* @return 位置
*/
public static int indexOf(final float[] array, final float element) {
return indexOf(array, 0, element);
}
/**
* 查询指定值位置, 没有返回-1
*
* @param array 数组
* @param fromIndex 起始位置从0开始
* @param element 指定值
* @return 位置
*/
public static int indexOf(final float[] array, int fromIndex, final float element) {
if (array == null) {
return -1;
}
for (int i = fromIndex; i < array.length; ++i) {
if (array[i] == element) {
return i;
}
}
return -1;
}
/**
* 查询指定值位置, 没有返回-1
*
* @param array 数组
* @param element 指定值
* @return 位置
*/
public static int indexOf(final double[] array, final double element) {
return indexOf(array, 0, element);
}
/**
* 查询指定值位置, 没有返回-1
*
* @param array 数组
* @param fromIndex 起始位置从0开始
* @param element 指定值
* @return 位置
*/
public static int indexOf(final double[] array, int fromIndex, final double element) {
if (array == null) {
return -1;
}
for (int i = fromIndex; i < array.length; ++i) {
if (array[i] == element) {
return i;
}
}
return -1;
}
/**
* 将源对象转换成目标类型
*
* @param <T> 泛型
* @param type 目标类型
* @param value 源对象
* @return 对象
*/
@ClassDepends(Copier.class)
public static <T> T convertValue(Type type, Object value) {
if (type == null) {
return (T) value;
}
final Class typeClazz = TypeToken.typeToClass(type);
if (value == null) {
if (typeClazz == boolean.class) {
return (T) Boolean.FALSE;
} else if (typeClazz == byte.class) {
return (T) (Byte) (byte) 0;
} else if (typeClazz == char.class) {
return (T) (Character) (char) 0;
} else if (typeClazz == short.class) {
return (T) (Short) (short) 0;
} else if (typeClazz == int.class) {
return (T) (Integer) 0;
} else if (typeClazz == long.class) {
return (T) (Long) 0L;
} else if (typeClazz == float.class) {
return (T) (Float) 0F;
} else if (typeClazz == double.class) {
return (T) (Double) 0D;
}
return (T) value;
}
final Class valClazz = value.getClass();
if (typeClazz == valClazz || typeClazz.isAssignableFrom(valClazz)) {
return (T) value;
} else if (typeClazz == String.class) {
return (T) value.toString();
} else if (typeClazz == double.class || typeClazz == Double.class) {
if (value instanceof Number) {
return (T) (Number) ((Number) value).doubleValue();
} else if (valClazz == String.class) {
return (T) (Number) Double.parseDouble(value.toString());
}
} else if (typeClazz == float.class || typeClazz == Float.class) {
if (value instanceof Number) {
return (T) (Number) ((Number) value).floatValue();
} else if (valClazz == String.class) {
return (T) (Number) Float.parseFloat(value.toString());
}
} else if (typeClazz == long.class || typeClazz == Long.class) {
if (value instanceof Number) {
return (T) (Number) ((Number) value).longValue();
} else if (valClazz == String.class) {
return (T) (Number) Long.parseLong(value.toString());
}
} else if (typeClazz == int.class || typeClazz == Integer.class) {
if (value instanceof Number) {
return (T) (Number) ((Number) value).intValue();
} else if (valClazz == String.class) {
return (T) (Number) Integer.parseInt(value.toString());
}
} else if (typeClazz == short.class || typeClazz == Short.class) {
if (value instanceof Number) {
return (T) (Number) ((Number) value).shortValue();
} else if (valClazz == String.class) {
return (T) (Number) Short.parseShort(value.toString());
}
} else if (typeClazz == char.class || typeClazz == Character.class) {
if (value instanceof Number) {
char ch = (char) ((Number) value).intValue();
return (T) (Object) ch;
}
} else if (typeClazz == byte.class || typeClazz == Byte.class) {
if (value instanceof Number) {
return (T) (Number) ((Number) value).byteValue();
}
} else if (typeClazz == boolean.class || typeClazz == Boolean.class) {
if (value instanceof Number) {
return (T) (Object) (((Number) value).intValue() > 0);
}
} else if (typeClazz == BigInteger.class && valClazz == String.class) {
return (T) new BigInteger(value.toString());
} else if (typeClazz == BigDecimal.class && valClazz == String.class) {
return (T) new BigDecimal(value.toString());
}
JsonConvert convert = JsonConvert.root();
if (CharSequence.class.isAssignableFrom(valClazz)) {
return convert.convertFrom(type, value.toString());
} else {
return convert.convertFrom(type, convert.convertToBytes(value));
}
}
/**
* 将buffer的内容转换成字符串, string参数不为空时会追加在buffer内容字符串之前
*
* @param string 字符串前缀
* @param buffer ByteBuffer
* @return 字符串
*/
public static String toString(String string, ByteBuffer buffer) {
if (buffer == null || !buffer.hasRemaining()) {
return string;
}
int pos = buffer.position();
int limit = buffer.limit();
byte[] bytes = new byte[buffer.remaining()];
buffer.get(bytes);
buffer.position(pos);
buffer.limit(limit);
if (string == null) {
return new String(bytes, UTF_8);
}
return string + new String(bytes, UTF_8);
}
/**
* 将buffer的内容转换成字符串并打印到控制台, string参数不为空时会追加在buffer内容字符串之前
*
* @param string 字符串前缀
* @param buffer ByteBuffer
*/
public static void println(String string, ByteBuffer buffer) {
if (buffer == null || !buffer.hasRemaining()) {
return;
}
int pos = buffer.position();
int limit = buffer.limit();
byte[] bytes = new byte[buffer.remaining()];
buffer.get(bytes);
buffer.position(pos);
buffer.limit(limit);
println(string, bytes);
}
/**
* 将字节数组的内容转换成字符串并打印到控制台, string参数不为空时会追加在字节数组内容字符串之前
*
* @param string 字符串前缀
* @param bytes 字节数组
*/
public static void println(String string, byte... bytes) {
if (bytes == null) {
return;
}
StringBuilder sb = new StringBuilder();
if (string != null) {
sb.append(string);
}
sb.append(bytes.length).append(".[");
boolean last = false;
for (byte b : bytes) {
if (last) {
sb.append(',');
}
int v = b & 0xff;
sb.append("0x");
if (v < 16) {
sb.append('0');
}
sb.append(Integer.toHexString(v));
last = true;
}
sb.append(']');
(System.out).println(sb);
}
/**
* 返回本机的第一个内网IPv4地址 没有则返回null
*
* @return IPv4地址
*/
public static InetAddress localInetAddress() {
InetAddress back = null;
try {
Enumeration<NetworkInterface> nifs = NetworkInterface.getNetworkInterfaces();
while (nifs.hasMoreElements()) {
NetworkInterface nif = nifs.nextElement();
if (!nif.isUp()) {
continue;
}
Enumeration<InetAddress> eis = nif.getInetAddresses();
while (eis.hasMoreElements()) {
InetAddress ia = eis.nextElement();
if (ia.isLoopbackAddress() && ia instanceof Inet4Address) {
back = ia;
}
if (ia.isSiteLocalAddress() && ia instanceof Inet4Address) {
return ia;
}
}
}
} catch (Exception e) {
// do nothing
}
return back;
}
/**
* 创建 CompletionHandler 对象
*
* @param <V> 结果对象的泛型
* @param <A> 附件对象的泛型
* @param success 成功的回调函数
* @param fail 失败的回调函数
* @return CompletionHandler
*/
public static <V, A> CompletionHandler<V, A> createAsyncHandler(
final BiConsumer<V, A> success, final BiConsumer<Throwable, A> fail) {
return new CompletionHandler<V, A>() {
@Override
public void completed(V result, A attachment) {
if (success != null) {
success.accept(result, attachment);
}
}
@Override
public void failed(Throwable exc, A attachment) {
if (fail != null) {
fail.accept(exc, attachment);
}
}
};
}
/**
* 创建没有返回结果的 CompletionHandler 对象
*
* @param <A> 附件对象的泛型
* @param success 成功的回调函数
* @param fail 失败的回调函数
* @return CompletionHandler
*/
public static <A> CompletionHandler<Void, A> createAsyncHandler(
final Consumer<A> success, final BiConsumer<Throwable, A> fail) {
return new CompletionHandler<Void, A>() {
@Override
public void completed(Void result, A attachment) {
if (success != null) {
success.accept(attachment);
}
}
@Override
public void failed(Throwable exc, A attachment) {
if (fail != null) {
fail.accept(exc, attachment);
}
}
};
}
/**
* 创建没有附件对象的 CompletionHandler 对象
*
* @param <V> 结果对象的泛型
* @param success 成功的回调函数
* @param fail 失败的回调函数
* @return CompletionHandler
*/
public static <V> CompletionHandler<V, Void> createAsyncHandler(
final Consumer<V> success, final Consumer<Throwable> fail) {
return new CompletionHandler<V, Void>() {
@Override
public void completed(V result, Void attachment) {
if (success != null) {
success.accept(result);
}
}
@Override
public void failed(Throwable exc, Void attachment) {
if (fail != null) {
fail.accept(exc);
}
}
};
}
/**
* 获取格式为yyyy-MM-dd HH:mm:ss的当前时间
*
* @return 格式为yyyy-MM-dd HH:mm:ss的时间值
*/
@Deprecated(since = "2.8.0")
public static String now() {
return Times.now();
}
/**
* 获取格式为yyyy-MM-dd HH:mm:ss.fff的当前时间
*
* @return 格式为yyyy-MM-dd HH:mm:ss.fff的时间值
*/
@Deprecated(since = "2.8.0")
public static String nowMillis() {
return Times.nowMillis();
}
/**
* 将指定时间格式化为 yyyy-MM-dd HH:mm:ss
*
* @param time 待格式化的时间
* @return 格式为yyyy-MM-dd HH:mm:ss的时间值
*/
@Deprecated(since = "2.8.0")
public static String formatTime(long time) {
return Times.formatTime(time);
}
/**
* 将时间值转换为长度为9的36进制值
*
* @param time 时间值
* @return 36进制时间值
*/
@Deprecated(since = "2.8.0")
public static String format36time(long time) {
return Times.format36time(time);
}
/**
* 获取当天凌晨零点的格林时间
*
* @return 毫秒数
*/
@Deprecated(since = "2.8.0")
public static long midnight() {
return Times.midnight();
}
/**
* 获取指定时间当天凌晨零点的格林时间
*
* @param time 指定时间
* @return 毫秒数
*/
@Deprecated(since = "2.8.0")
public static long midnight(long time) {
return Times.midnight(time);
}
/**
* 获取当天20151231格式的int值
*
* @return 20151231格式的int值
*/
@Deprecated(since = "2.8.0")
public static int today() {
return Times.today();
}
/**
* 获取当天151231格式的int值
*
* @return 151231格式的int值
*/
@Deprecated(since = "2.8.0")
public static int todayYYMMDD() {
return Times.todayYYMMDD();
}
/**
* 获取当天1512312359格式的int值
*
* @return 1512312359格式的int值
*/
@Deprecated(since = "2.8.0")
public static int todayYYMMDDHHmm() {
return Times.todayYYMMDDHHmm();
}
/**
* 获取当天20151231235959格式的int值
*
* @return 20151231235959格式的int值
*/
@Deprecated(since = "2.8.0")
public static long todayYYYYMMDDHHmmss() {
return Times.todayYYYYMMDDHHmmss();
}
/**
* 获取当天151231235959格式的int值
*
* @return 151231235959格式的int值
*/
@Deprecated(since = "2.8.0")
public static long todayYYMMDDHHmmss() {
return Times.todayYYMMDDHHmmss();
}
/**
* 获取明天20151230格式的int值
*
* @return 20151230格式的int值
*/
@Deprecated(since = "2.8.0")
public static int tomorrow() {
return Times.tomorrow();
}
/**
* 获取明天151230格式的int值
*
* @return 151230格式的int值
*/
@Deprecated(since = "2.8.0")
public static int tomorrowYYMMDD() {
return Times.tomorrowYYMMDD();
}
/**
* 获取昨天20151230格式的int值
*
* @return 20151230格式的int值
*/
@Deprecated(since = "2.8.0")
public static int yesterday() {
return Times.yesterday();
}
/**
* 获取昨天151230格式的int值
*
* @return 151230格式的int值
*/
@Deprecated(since = "2.8.0")
public static int yesterdayYYMMDD() {
return Times.yesterdayYYMMDD();
}
/**
* 获取指定时间的20160202格式的int值
*
* @param time 指定时间
* @return 毫秒数
*/
@Deprecated(since = "2.8.0")
public static int yyyyMMdd(long time) {
return Times.yyyyMMdd(time);
}
/**
* 获取指定时间的160202格式的int值
*
* @param time 指定时间
* @return 毫秒数
*/
@Deprecated(since = "2.8.0")
public static int yyMMdd(long time) {
return Times.yyMMdd(time);
}
/**
* 获取当天16020223格式的int值
*
* @param time 指定时间
* @return 16020223格式的int值
*/
@Deprecated(since = "2.8.0")
public static int yyMMDDHHmm(long time) {
return Times.yyMMDDHHmm(time);
}
/**
* 获取时间点所在星期的周一
*
* @param time 指定时间
* @return 毫秒数
*/
@Deprecated(since = "2.8.0")
public static long monday(long time) {
return Times.monday(time);
}
/**
* 获取时间点所在星期的周日
*
* @param time 指定时间
* @return 毫秒数
*/
@Deprecated(since = "2.8.0")
public static long sunday(long time) {
return Times.sunday(time);
}
/**
* 获取时间点所在月份的1号
*
* @param time 指定时间
* @return 毫秒数
*/
@Deprecated(since = "2.8.0")
public static long monthFirstDay(long time) {
return Times.monthFirstDay(time);
}
/**
* 获取时间点所在月份的最后一天
*
* @param time 指定时间
* @return 毫秒数
*/
@Deprecated(since = "2.8.0")
public static long monthLastDay(long time) {
return Times.monthLastDay(time);
}
/**
* 将时间格式化, 支持%1$ty 和 %ty两种格式
*
* @param format 格式
* @param size 带%t的个数值小于0则需要计算
* @param time 时间
* @since 2.7.0
* @return 时间格式化
*/
@Deprecated(since = "2.8.0")
public static String formatTime(String format, int size, Object time) {
return Times.formatTime(format, size, time);
}
/**
* 将int[]强制转换成byte[]
*
* @param value int[]
* @return byte[]
*/
public static byte[] intsToBytes(int[] value) {
if (value == null) {
return null;
}
byte[] bs = new byte[value.length];
for (int i = 0; i < bs.length; i++) {
bs[i] = (byte) value[i];
}
return bs;
}
/**
* MD5加密
*
* @param str 待加密数据
* @return md5值
*/
public static String md5Hex(String str) {
return binToHexString(md5(str));
}
/**
* MD5加密
*
* @param input 待加密数据
* @return md5值
*/
public static String md5Hex(byte[] input) {
return binToHexString(md5(input));
}
/**
* MD5加密
*
* @param str 待加密数据
* @return md5值
*/
public static byte[] md5(String str) {
if (str == null) {
return null;
}
MessageDigest md5;
try {
md5 = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException ex) {
throw new RedkaleException("Couldn't find a MD5 provider", ex);
}
return md5.digest(str.getBytes(StandardCharsets.UTF_8));
}
/**
* MD5加密
*
* @param input 待加密数据
* @return md5值
*/
public static byte[] md5(byte[] input) {
if (input == null) {
return null;
}
MessageDigest md5;
try {
md5 = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException ex) {
throw new RedkaleException("Couldn't find a MD5 provider", ex);
}
return md5.digest(input);
}
/**
* MD5加密
*
* @param input 待加密数据
* @param offset 偏移量
* @param len 长度
* @return md5值
*/
public static byte[] md5(byte[] input, int offset, int len) {
if (input == null) {
return null;
}
MessageDigest md5;
try {
md5 = MessageDigest.getInstance("MD5");
md5.update(input, offset, len);
return md5.digest();
} catch (NoSuchAlgorithmException ex) {
throw new RedkaleException("Couldn't find a MD5 provider", ex);
}
}
/**
* SHA-256
*
* @param str 待hash数据
* @return hash值
*/
public static String sha256Hex(String str) {
return binToHexString(sha256(str));
}
/**
* SHA-256
*
* @param input 待hash数据
* @return hash值
*/
public static String sha256Hex(byte[] input) {
return binToHexString(sha256(input));
}
/**
* SHA-256
*
* @param input 待hash数据
* @param offset 偏移量
* @param len 长度
* @return hash值
*/
public static String sha256Hex(byte[] input, int offset, int len) {
return binToHexString(sha256(input, offset, len));
}
/**
* 以0x开头的 SHA-256
*
* @param input 待hash数据
* @return hash值
*/
public static String sha256Hex0x(byte[] input) {
return binTo0xHexString(sha256(input));
}
/**
* 以0x开头的 SHA-256
*
* @param input 待hash数据
* @param offset 偏移量
* @param len 长度
* @return hash值
*/
public static String sha256Hex0x(byte[] input, int offset, int len) {
return binTo0xHexString(sha256(input, offset, len));
}
/**
* SHA-256
*
* @param str 待hash数据
* @return hash值
*/
public static byte[] sha256(String str) {
if (str == null) {
return null;
}
MessageDigest digester;
try {
digester = MessageDigest.getInstance("SHA-256");
} catch (NoSuchAlgorithmException ex) {
throw new RedkaleException("Couldn't find a SHA-256 provider", ex);
}
return digester.digest(str.getBytes(StandardCharsets.UTF_8));
}
/**
* SHA-256
*
* @param input 待hash数据
* @return hash值
*/
public static byte[] sha256(byte[] input) {
if (input == null) {
return null;
}
MessageDigest digester;
try {
digester = MessageDigest.getInstance("SHA-256");
} catch (NoSuchAlgorithmException ex) {
throw new RedkaleException(ex);
}
return digester.digest(input);
}
/**
* SHA-256
*
* @param input 待hash数据
* @param offset 偏移量
* @param len 长度
* @return hash值
*/
public static byte[] sha256(byte[] input, int offset, int len) {
if (input == null) {
return null;
}
MessageDigest digester;
try {
digester = MessageDigest.getInstance("SHA-256");
digester.update(input, offset, len);
return digester.digest();
} catch (Exception ex) {
throw new RedkaleException(ex);
}
}
/**
* HmacSHA1
*
* @param key 密钥
* @param input 待hash数据
* @return hash值
*/
public static String hmacSha1Base64(String key, String input) {
return Base64.getEncoder().encodeToString(hmacSha1(key.getBytes(UTF_8), input.getBytes(UTF_8)));
}
/**
* HmacSHA1
*
* @param key 密钥
* @param input 待hash数据
* @return hash值
*/
public static String hmacSha1Base64(byte[] key, byte[] input) {
return Base64.getEncoder().encodeToString(hmacSha1(key, input));
}
/**
* HmacSHA1
*
* @param key 密钥
* @param input 待hash数据
* @param offset 偏移量
* @param len 长度
* @return hash值
*/
public static String hmacSha1Base64(byte[] key, byte[] input, int offset, int len) {
return Base64.getEncoder().encodeToString(hmacSha1(key, input, offset, len));
}
/**
* HmacSHA1
*
* @param key 密钥
* @param input 待hash数据
* @return hash值
*/
public static String hmacSha1Hex(byte[] key, byte[] input) {
return binToHexString(hmacSha1(key, input));
}
/**
* HmacSHA1
*
* @param key 密钥
* @param input 待hash数据
* @param offset 偏移量
* @param len 长度
* @return hash值
*/
public static String hmacSha1Hex(byte[] key, byte[] input, int offset, int len) {
return binToHexString(hmacSha1(key, input, offset, len));
}
/**
* 以0x开头的 HmacSHA1
*
* @param key 密钥
* @param input 待hash数据
* @return hash值
*/
public static String hmacSha1Hex0x(byte[] key, byte[] input) {
return binTo0xHexString(hmacSha1(key, input));
}
/**
* 以0x开头的 HmacSHA1
*
* @param key 密钥
* @param input 待hash数据
* @param offset 偏移量
* @param len 长度
* @return hash值
*/
public static String hmacSha1Hex0x(byte[] key, byte[] input, int offset, int len) {
return binTo0xHexString(hmacSha1(key, input, offset, len));
}
/**
* HmacSHA1
*
* @param key 密钥
* @param input 待hash数据
* @return hash值
*/
public static byte[] hmacSha1(byte[] key, byte[] input) {
if (input == null) {
return null;
}
try {
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(new SecretKeySpec(key, "HmacSHA1"));
return mac.doFinal(input);
} catch (InvalidKeyException | NoSuchAlgorithmException ex) {
throw new RedkaleException(ex);
}
}
/**
* HmacSHA1
*
* @param key 密钥
* @param input 待hash数据
* @param offset 偏移量
* @param len 长度
* @return hash值
*/
public static byte[] hmacSha1(byte[] key, byte[] input, int offset, int len) {
if (input == null) {
return null;
}
try {
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(new SecretKeySpec(key, "HmacSHA1"));
mac.update(input, offset, len);
return mac.doFinal();
} catch (InvalidKeyException | NoSuchAlgorithmException ex) {
throw new RedkaleException(ex);
}
}
/**
* HmacSHA256
*
* @param key 密钥
* @param input 待hash数据
* @return hash值
*/
public static String hmacSha256Base64(String key, String input) {
return Base64.getEncoder().encodeToString(hmacSha256(key.getBytes(UTF_8), input.getBytes(UTF_8)));
}
/**
* HmacSHA256
*
* @param key 密钥
* @param input 待hash数据
* @return hash值
*/
public static String hmacSha256Base64(byte[] key, byte[] input) {
return Base64.getEncoder().encodeToString(hmacSha256(key, input));
}
/**
* HmacSHA256
*
* @param key 密钥
* @param input 待hash数据
* @param offset 偏移量
* @param len 长度
* @return hash值
*/
public static String hmacSha256Base64(byte[] key, byte[] input, int offset, int len) {
return Base64.getEncoder().encodeToString(hmacSha256(key, input, offset, len));
}
/**
* HmacSHA256
*
* @param key 密钥
* @param input 待hash数据
* @return hash值
*/
public static String hmacSha256Hex(byte[] key, byte[] input) {
return binToHexString(hmacSha256(key, input));
}
/**
* HmacSHA256
*
* @param key 密钥
* @param input 待hash数据
* @param offset 偏移量
* @param len 长度
* @return hash值
*/
public static String hmacSha256Hex(byte[] key, byte[] input, int offset, int len) {
return binToHexString(hmacSha256(key, input, offset, len));
}
/**
* 以0x开头的 HmacSHA256
*
* @param key 密钥
* @param input 待hash数据
* @return hash值
*/
public static String hmacSha256Hex0x(byte[] key, byte[] input) {
return binTo0xHexString(hmacSha256(key, input));
}
/**
* 以0x开头的 HmacSHA256
*
* @param key 密钥
* @param input 待hash数据
* @param offset 偏移量
* @param len 长度
* @return hash值
*/
public static String hmacSha256Hex0x(byte[] key, byte[] input, int offset, int len) {
return binTo0xHexString(hmacSha256(key, input, offset, len));
}
/**
* HmacSHA256
*
* @param key 密钥
* @param input 待hash数据
* @return hash值
*/
public static byte[] hmacSha256(byte[] key, byte[] input) {
if (input == null) {
return null;
}
try {
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(key, "HmacSHA256"));
return mac.doFinal(input);
} catch (InvalidKeyException | NoSuchAlgorithmException ex) {
throw new RedkaleException(ex);
}
}
/**
* HmacSHA256
*
* @param key 密钥
* @param input 待hash数据
* @param offset 偏移量
* @param len 长度
* @return hash值
*/
public static byte[] hmacSha256(byte[] key, byte[] input, int offset, int len) {
if (input == null) {
return null;
}
try {
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(key, "HmacSHA256"));
mac.update(input, offset, len);
return mac.doFinal();
} catch (InvalidKeyException | NoSuchAlgorithmException ex) {
throw new RedkaleException(ex);
}
}
/**
* HmacSHA512
*
* @param key 密钥
* @param input 待hash数据
* @return hash值
*/
public static String hmacSha512Base64(String key, String input) {
return Base64.getEncoder().encodeToString(hmacSha512(key.getBytes(UTF_8), input.getBytes(UTF_8)));
}
/**
* HmacSHA512
*
* @param key 密钥
* @param input 待hash数据
* @return hash值
*/
public static String hmacSha512Base64(byte[] key, byte[] input) {
return Base64.getEncoder().encodeToString(hmacSha512(key, input));
}
/**
* HmacSHA512
*
* @param key 密钥
* @param input 待hash数据
* @param offset 偏移量
* @param len 长度
* @return hash值
*/
public static String hmacSha512Base64(byte[] key, byte[] input, int offset, int len) {
return Base64.getEncoder().encodeToString(hmacSha512(key, input, offset, len));
}
/**
* HmacSHA512
*
* @param key 密钥
* @param input 待hash数据
* @return hash值
*/
public static String hmacSha512Hex(byte[] key, byte[] input) {
return binToHexString(hmacSha512(key, input));
}
/**
* HmacSHA512
*
* @param key 密钥
* @param input 待hash数据
* @param offset 偏移量
* @param len 长度
* @return hash值
*/
public static String hmacSha512Hex(byte[] key, byte[] input, int offset, int len) {
return binToHexString(hmacSha512(key, input, offset, len));
}
/**
* 以0x开头的 HmacSHA512
*
* @param key 密钥
* @param input 待hash数据
* @return hash值
*/
public static String hmacSha512Hex0x(byte[] key, byte[] input) {
return binTo0xHexString(hmacSha512(key, input));
}
/**
* 以0x开头的 HmacSHA512
*
* @param key 密钥
* @param input 待hash数据
* @param offset 偏移量
* @param len 长度
* @return hash值
*/
public static String hmacSha512Hex0x(byte[] key, byte[] input, int offset, int len) {
return binTo0xHexString(hmacSha512(key, input, offset, len));
}
/**
* HmacSHA512
*
* @param key 密钥
* @param input 待hash数据
* @return hash值
*/
public static byte[] hmacSha512(byte[] key, byte[] input) {
if (input == null) {
return null;
}
try {
SecretKey sk = new SecretKeySpec(key, "HmacSHA512");
Mac mac = Mac.getInstance("HmacSHA512");
mac.init(sk);
return mac.doFinal(input);
} catch (InvalidKeyException | NoSuchAlgorithmException ex) {
throw new RedkaleException(ex);
}
}
/**
* HmacSHA512
*
* @param key 密钥
* @param input 待hash数据
* @param offset 偏移量
* @param len 长度
* @return hash值
*/
public static byte[] hmacSha512(byte[] key, byte[] input, int offset, int len) {
if (input == null) {
return null;
}
try {
SecretKey sk = new SecretKeySpec(key, "HmacSHA512");
Mac mac = Mac.getInstance("HmacSHA512");
mac.init(sk);
mac.update(input, offset, len);
return mac.doFinal();
} catch (InvalidKeyException | NoSuchAlgorithmException ex) {
throw new RedkaleException(ex);
}
}
/**
* 根据指定算法进行hash
*
* @param algorithm 算法名
* @param input 待hash数据
* @return hash值
*/
public static byte[] hash(String algorithm, byte[] input) {
try {
MessageDigest digest = MessageDigest.getInstance(algorithm.toUpperCase());
return digest.digest(input);
} catch (NoSuchAlgorithmException ex) {
throw new RedkaleException("Couldn't find a " + algorithm + " provider", ex);
}
}
/**
* 根据指定算法进行hash
*
* @param algorithm 算法名
* @param input 待hash数据
* @param offset 偏移量
* @param length 长度
* @return hash值
*/
public static byte[] hash(String algorithm, byte[] input, int offset, int length) {
try {
MessageDigest digest = MessageDigest.getInstance(algorithm.toUpperCase());
digest.update(input, offset, length);
return digest.digest();
} catch (NoSuchAlgorithmException ex) {
throw new RedkaleException("Couldn't find a " + algorithm + " provider", ex);
}
}
/**
* 随机
*
* @return 随机
*/
public static SecureRandom secureRandom() {
return random;
}
/**
* 生成随机数
*
* @param size 随机数长度
* @return 随机数
*/
public static byte[] generateRandomBytes(int size) {
byte[] bytes = new byte[size];
random.nextBytes(bytes);
return bytes;
}
/**
* 将字节数组转换为以0x开头的16进制字符串
*
* @param bytes 字节数组
* @return 16进制字符串
*/
public static String binTo0xHexString(byte[] bytes) {
return "0x" + new String(binToHex(bytes));
}
/**
* 将字节数组转换为以0x开头的16进制字符串
*
* @param bytes 字节数组
* @param offset 偏移量
* @param len 长度
* @return 16进制字符串
*/
public static String binTo0xHexString(byte[] bytes, int offset, int len) {
return "0x" + new String(binToHex(bytes, offset, len));
}
/**
* 将字节数组转换为16进制字符串
*
* @param bytes 字节数组
* @return 16进制字符串
*/
public static String binToHexString(byte[] bytes) {
return new String(binToHex(bytes));
}
/**
* 将字节数组转换为16进制字符数组
*
* @param bytes 字节数组
* @return 16进制字符串的字符数组
*/
public static char[] binToHex(byte[] bytes) {
return binToHex(bytes, 0, bytes.length);
}
/**
* 将字节数组转换为16进制字符串
*
* @param bytes 字节数组
* @param offset 偏移量
* @param len 长度
* @return 16进制字符串
*/
public static String binToHexString(byte[] bytes, int offset, int len) {
return new String(binToHex(bytes, offset, len));
}
/**
* 将字节数组转换为16进制字符数组
*
* @param bytes 字节数组
* @param offset 偏移量
* @param len 长度
* @return 16进制字符串的字符数组
*/
public static char[] binToHex(byte[] bytes, int offset, int len) {
final char[] sb = new char[len * 2];
final int end = offset + len;
int index = 0;
final char[] hexs = hex;
for (int i = offset; i < end; i++) {
byte b = bytes[i];
sb[index++] = (hexs[((b >> 4) & 0xF)]);
sb[index++] = hexs[((b) & 0xF)];
}
return sb;
}
/**
* 将16进制字符串转换成字节数组
*
* @param src 16进制字符串
* @return 字节数组
*/
public static byte[] hexToBin(CharSequence src) {
return hexToBin(src, 0, src.length());
}
/**
* 将16进制字符串转换成字节数组
*
* @param src 16进制字符串
* @param offset 偏移量
* @param len 长度
* @return 字节数组
*/
public static byte[] hexToBin(CharSequence src, int offset, int len) {
if (offset == 0 && src.length() > 2 && src.charAt(0) == '0' && (src.charAt(1) == 'x' || src.charAt(1) == 'X')) {
offset += 2;
len -= 2;
}
final int size = (len + 1) / 2;
final byte[] bytes = new byte[size];
String digits = "0123456789abcdef";
for (int i = 0; i < size; i++) {
int ch1 = src.charAt(offset + i * 2);
if ('A' <= ch1 && 'F' >= ch1) {
ch1 = ch1 - 'A' + 'a';
}
int ch2 = src.charAt(offset + i * 2 + 1);
if ('A' <= ch2 && 'F' >= ch2) {
ch2 = ch2 - 'A' + 'a';
}
int pos1 = digits.indexOf(ch1);
if (pos1 < 0) {
throw new NumberFormatException();
}
int pos2 = digits.indexOf(ch2);
if (pos2 < 0) {
throw new NumberFormatException();
}
bytes[i] = (byte) (pos1 * 0x10 + pos2);
}
return bytes;
}
/**
* 将16进制字符串转换成字节数组
*
* @param str 16进制字符串
* @return 字节数组
*/
public static byte[] hexToBin(String str) {
return hexToBin(charArray(str));
}
/**
* 将16进制字符数组转换成字节数组
*
* @param src 16进制字符数组
* @return 字节数组
*/
public static byte[] hexToBin(char[] src) {
return hexToBin(src, 0, src.length);
}
/**
* 将16进制字符数组转换成字节数组
*
* @param src 16进制字符数组
* @param offset 偏移量
* @param len 长度
* @return 字节数组
*/
public static byte[] hexToBin(char[] src, int offset, int len) {
if (offset == 0 && src.length > 2 && src[0] == '0' && (src[1] == 'x' || src[1] == 'X')) {
offset += 2;
len -= 2;
}
final int size = (len + 1) / 2;
final byte[] bytes = new byte[size];
String digits = "0123456789abcdef";
for (int i = 0; i < size; i++) {
int ch1 = src[offset + i * 2];
if ('A' <= ch1 && 'F' >= ch1) {
ch1 = ch1 - 'A' + 'a';
}
int ch2 = src[offset + i * 2 + 1];
if ('A' <= ch2 && 'F' >= ch2) {
ch2 = ch2 - 'A' + 'a';
}
int pos1 = digits.indexOf(ch1);
if (pos1 < 0) {
throw new NumberFormatException();
}
int pos2 = digits.indexOf(ch2);
if (pos2 < 0) {
throw new NumberFormatException();
}
bytes[i] = (byte) (pos1 * 0x10 + pos2);
}
return bytes;
}
// -----------------------------------------------------------------------------
/**
* 使用UTF-8编码将byte[]转换成char[]
*
* @param array byte[]
* @return char[]
*/
public static char[] decodeUTF8(final byte[] array) {
return decodeUTF8(array, 0, array.length);
}
public static char[] decodeUTF8(final byte[] array, final int start, final int len) {
byte b;
int size = len;
final byte[] bytes = array;
final int limit = start + len;
for (int i = start; i < limit; i++) {
b = bytes[i];
if ((b >> 5) == -2) { // 2 bytes, 11 bits: 110xxxxx 10xxxxxx
size--;
} else if ((b >> 4) == -2) { // 3 bytes, 16 bits: 1110xxxx 10xxxxxx 10xxxxxx
size -= 2;
} else if ((b >> 3) == -2) { // 4 bytes, 21 bits: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
size -= 2;
}
}
final char[] text = new char[size];
size = 0;
for (int i = start; i < limit; ) {
b = bytes[i++];
if (b >= 0) { // 1 byte, 7 bits: 0xxxxxxx
text[size++] = (char) b;
} else if ((b >> 5) == -2) { // 2 bytes, 11 bits: 110xxxxx 10xxxxxx
text[size++] = (char) (((b << 6) ^ bytes[i++]) ^ (((byte) 0xC0 << 6) ^ ((byte) 0x80)));
} else if ((b >> 4) == -2) { // 3 bytes, 16 bits: 1110xxxx 10xxxxxx 10xxxxxx
text[size++] = (char) ((b << 12)
^ (bytes[i++] << 6)
^ (bytes[i++] ^ (((byte) 0xE0 << 12) ^ ((byte) 0x80 << 6) ^ ((byte) 0x80))));
} else if ((b >> 3) == -2) { // 4 bytes, 21 bits: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
int uc = ((b << 18)
^ (bytes[i++] << 12)
^ (bytes[i++] << 6)
^ (bytes[i++]
^ (((byte) 0xF0 << 18) ^ ((byte) 0x80 << 12) ^ ((byte) 0x80 << 6) ^ ((byte) 0x80))));
text[size++] = Character.highSurrogate(uc);
text[size++] = Character.lowSurrogate(uc);
// 测试代码 byte[] bs = {(byte)34, (byte)76, (byte)105, (byte)108, (byte)121, (byte)240, (byte)159,
// (byte)146, (byte)171, (byte)34};
}
}
return text;
}
public static byte[] encodeUTF8(final String value) {
if (value == null) {
return new byte[0];
}
return encodeUTF8(value.toCharArray());
}
public static byte[] encodeUTF8(final char[] array) {
return encodeUTF8(array, 0, array.length);
}
public static byte[] encodeUTF8(final char[] text, final int start, final int len) {
char c;
int size = 0;
final char[] chs = text;
final int limit = start + len;
for (int i = start; i < limit; i++) {
c = chs[i];
if (c < 0x80) {
size++;
} else if (c < 0x800) {
size += 2;
} else if (Character.isSurrogate(c)) {
size += 2;
} else {
size += 3;
}
}
final byte[] bytes = new byte[size];
size = 0;
for (int i = start; i < limit; i++) {
c = chs[i];
if (c < 0x80) {
bytes[size++] = (byte) c;
} else if (c < 0x800) {
bytes[size++] = (byte) (0xc0 | (c >> 6));
bytes[size++] = (byte) (0x80 | (c & 0x3f));
} else if (Character.isSurrogate(c)) { // 连取两个
int uc = Character.toCodePoint(c, chs[i + 1]);
bytes[size++] = (byte) (0xf0 | ((uc >> 18)));
bytes[size++] = (byte) (0x80 | ((uc >> 12) & 0x3f));
bytes[size++] = (byte) (0x80 | ((uc >> 6) & 0x3f));
bytes[size++] = (byte) (0x80 | (uc & 0x3f));
i++;
} else {
bytes[size++] = (byte) (0xe0 | ((c >> 12)));
bytes[size++] = (byte) (0x80 | ((c >> 6) & 0x3f));
bytes[size++] = (byte) (0x80 | (c & 0x3f));
}
}
return bytes;
}
public static long getAddress(ByteBuffer buffer) {
return bufferAddrFunction.applyAsLong(buffer);
}
public static boolean isLatin1(String value) {
if (value == null) {
return true;
}
if (strLatin1Function != null) {
return strLatin1Function.test(value); // LATIN1:0 UTF16:1
}
char[] chs = charArray(value);
for (char ch : chs) {
if (ch >= 0x80) {
return false;
}
}
return true;
}
public static byte[] byteUTF16Array(String value) {
if (value == null || strByteFunction == null) {
return null;
}
return strByteFunction.apply(value);
}
public static char[] charArray(String value) {
if (value == null) {
return null;
}
return value.toCharArray();
}
public static char[] charArray(StringBuilder value) {
if (value == null) {
return null;
}
return value.toString().toCharArray();
}
// 只能是单字节字符串
public static byte[] latin1ByteArray(String latin1Value) {
if (latin1Value == null) {
return null;
}
if (strByteFunction == null) {
return latin1Value.getBytes();
}
return strByteFunction.apply(latin1Value);
}
// 只能是单字节字符串
public static byte[] latin1ByteArray(StringBuilder latin1Value) {
if (latin1Value == null) {
return null;
}
if (sbByteFunction == null) {
return latin1Value.toString().getBytes();
}
return sbByteFunction.apply(latin1Value);
}
public static ByteBuffer encodeUTF8(final ByteBuffer buffer, final char[] array) {
return encodeUTF8(buffer, array, 0, array.length);
}
public static ByteBuffer encodeUTF8(final ByteBuffer buffer, int bytesLength, final char[] array) {
return encodeUTF8(buffer, bytesLength, array, 0, array.length);
}
public static int encodeUTF8Length(String value) {
if (value == null) {
return -1;
}
return encodeUTF8Length(value.toCharArray());
}
public static int encodeUTF8Length(final char[] text) {
return encodeUTF8Length(text, 0, text.length);
}
public static int encodeUTF8Length(final char[] text, final int start, final int len) {
char c;
int size = 0;
final char[] chs = text;
final int limit = start + len;
for (int i = start; i < limit; i++) {
c = chs[i];
if (c < 0x80) {
size++;
} else if (c < 0x800) {
size += 2;
} else if (Character.isSurrogate(c)) {
size += 2;
} else {
size += 3;
}
}
return size;
}
/**
* 将两个数字组装成一个long
*
* @param high 高位值
* @param low 低位值
* @return long值
*/
public static long merge(int high, int low) {
return (0L + high) << 32 | low;
}
public static ByteBuffer encodeUTF8(final ByteBuffer buffer, final char[] text, final int start, final int len) {
return encodeUTF8(buffer, encodeUTF8Length(text, start, len), text, start, len);
}
// 返回的ByteBuffer为扩展buffer为null表示参数中的buffer足够存储数据
public static ByteBuffer encodeUTF8(
final ByteBuffer buffer, int bytesLength, final char[] text, final int start, final int len) {
char c;
char[] chs = text;
final int limit = start + len;
int remain = buffer.remaining();
final ByteBuffer buffer2 =
remain >= bytesLength ? null : ByteBuffer.allocate(bytesLength - remain + 4); // 最差情况buffer最后两byte没有填充
ByteBuffer buf = buffer;
for (int i = start; i < limit; i++) {
c = chs[i];
if (c < 0x80) {
if (buf.remaining() < 1) {
buf = buffer2;
}
buf.put((byte) c);
} else if (c < 0x800) {
if (buf.remaining() < 2) {
buf = buffer2;
}
buf.put((byte) (0xc0 | (c >> 6)));
buf.put((byte) (0x80 | (c & 0x3f)));
} else if (Character.isSurrogate(c)) { // 连取两个
if (buf.remaining() < 4) {
buf = buffer2;
}
int uc = Character.toCodePoint(c, chs[i + 1]);
buf.put((byte) (0xf0 | ((uc >> 18))));
buf.put((byte) (0x80 | ((uc >> 12) & 0x3f)));
buf.put((byte) (0x80 | ((uc >> 6) & 0x3f)));
buf.put((byte) (0x80 | (uc & 0x3f)));
i++;
} else {
if (buf.remaining() < 3) {
buf = buffer2;
}
buf.put((byte) (0xe0 | ((c >> 12))));
buf.put((byte) (0x80 | ((c >> 6) & 0x3f)));
buf.put((byte) (0x80 | (c & 0x3f)));
}
}
if (buffer2 != null) {
buffer2.flip();
}
return buffer2; // 返回扩展buffer
}
public static String getTypeDescriptor(java.lang.reflect.Type type) {
if (type == null) {
return null;
}
if (type instanceof Class) {
Class d = (Class) type;
final StringBuilder sb = new StringBuilder();
while (true) {
if (d.isPrimitive()) {
char car;
if (d == Integer.TYPE) {
car = 'I';
} else if (d == Void.TYPE) {
car = 'V';
} else if (d == Boolean.TYPE) {
car = 'Z';
} else if (d == Byte.TYPE) {
car = 'B';
} else if (d == Character.TYPE) {
car = 'C';
} else if (d == Short.TYPE) {
car = 'S';
} else if (d == Double.TYPE) {
car = 'D';
} else if (d == Float.TYPE) {
car = 'F';
} else /* if (d == Long.TYPE) */ {
car = 'J';
}
return sb.append(car).toString();
} else if (d.isArray()) {
sb.append('[');
d = d.getComponentType();
} else {
sb.append('L');
String name = d.getName();
int len = name.length();
for (int i = 0; i < len; ++i) {
char car = name.charAt(i);
sb.append(car == '.' ? '/' : car);
}
return sb.append(';').toString();
}
}
}
if (type instanceof ParameterizedType) { // 例如: Map<String, Serializable>
ParameterizedType pt = (ParameterizedType) type;
final StringBuilder sb = new StringBuilder();
String raw = getTypeDescriptor(pt.getRawType());
sb.append(raw.substring(0, raw.length() - 1)).append('<');
for (java.lang.reflect.Type item : pt.getActualTypeArguments()) {
sb.append(getTypeDescriptor(item));
}
return sb.append(">;").toString();
}
if (type instanceof WildcardType) { // 例如: <? extends Serializable>
final WildcardType wt = (WildcardType) type;
final StringBuilder sb = new StringBuilder();
java.lang.reflect.Type[] us = wt.getUpperBounds();
java.lang.reflect.Type[] ls = wt.getLowerBounds();
if (isEmpty(ls)) {
if (us.length == 1 && us[0] == Object.class) {
sb.append('*');
} else {
for (java.lang.reflect.Type f : us) {
sb.append('+');
sb.append(getTypeDescriptor(f));
}
}
}
for (java.lang.reflect.Type f : ls) {
sb.append('-');
sb.append(getTypeDescriptor(f));
}
return sb.toString();
}
// TypeVariable 不支持
return null;
}
// -----------------------------------------------------------------------------
// public static javax.net.ssl.SSLContext getDefaultSSLContext() {
// return DEFAULTSSL_CONTEXT;
// }
//
// public static javax.net.ssl.HostnameVerifier getDefaultHostnameVerifier() {
// return defaultVerifier;
// }
//
// public static Socket createDefaultSSLSocket(InetSocketAddress address) throws IOException {
// return createDefaultSSLSocket(address.getAddress(), address.getPort());
// }
//
// public static Socket createDefaultSSLSocket(InetAddress host, int port) throws IOException {
// Socket socket = DEFAULTSSL_CONTEXT.getSocketFactory().createSocket(host, port);
// return socket;
// }
//
public static String postHttpContent(String url) throws IOException {
return remoteHttpContent("POST", url, 0, null, null).toString(StandardCharsets.UTF_8);
}
public static String postHttpContent(String url, int timeoutMs) throws IOException {
return remoteHttpContent("POST", url, timeoutMs, null, null).toString(StandardCharsets.UTF_8);
}
public static String postHttpContent(String url, String body) throws IOException {
return remoteHttpContent("POST", url, 0, null, body).toString(StandardCharsets.UTF_8);
}
public static String postHttpContent(String url, int timeoutMs, String body) throws IOException {
return remoteHttpContent("POST", url, timeoutMs, null, body).toString(StandardCharsets.UTF_8);
}
public static String postHttpContent(String url, Map<String, Serializable> headers, String body)
throws IOException {
return remoteHttpContent("POST", url, 0, headers, body).toString(StandardCharsets.UTF_8);
}
public static String postHttpContent(String url, int timeoutMs, Map<String, Serializable> headers, String body)
throws IOException {
return remoteHttpContent("POST", url, timeoutMs, headers, body).toString(StandardCharsets.UTF_8);
}
public static String postHttpContent(String url, Charset charset) throws IOException {
return remoteHttpContent("POST", url, 0, null, null).toString(charset.name());
}
public static String postHttpContent(String url, int timeoutMs, Charset charset) throws IOException {
return remoteHttpContent("POST", url, timeoutMs, null, null).toString(charset.name());
}
public static String postHttpContent(String url, Charset charset, String body) throws IOException {
return remoteHttpContent("POST", url, 0, null, body).toString(charset.name());
}
public static String postHttpContent(String url, int timeoutMs, Charset charset, String body) throws IOException {
return remoteHttpContent("POST", url, timeoutMs, null, body).toString(charset.name());
}
public static String postHttpContent(String url, Charset charset, Map<String, Serializable> headers, String body)
throws IOException {
return remoteHttpContent("POST", url, 0, headers, body).toString(charset.name());
}
public static String postHttpContent(
String url, int timeoutMs, Charset charset, Map<String, Serializable> headers, String body)
throws IOException {
return remoteHttpContent("POST", url, timeoutMs, headers, body).toString(charset.name());
}
public static byte[] postHttpBytesContent(String url) throws IOException {
return remoteHttpContent("POST", url, 0, null, null).toByteArray();
}
public static byte[] postHttpBytesContent(String url, int timeoutMs) throws IOException {
return remoteHttpContent("POST", url, timeoutMs, null, null).toByteArray();
}
public static byte[] postHttpBytesContent(String url, Map<String, Serializable> headers, String body)
throws IOException {
return remoteHttpContent("POST", url, 0, headers, body).toByteArray();
}
public static byte[] postHttpBytesContent(String url, int timeoutMs, Map<String, Serializable> headers, String body)
throws IOException {
return remoteHttpContent("POST", url, timeoutMs, headers, body).toByteArray();
}
public static String getHttpContent(String url) throws IOException {
return remoteHttpContent("GET", url, 0, null, null).toString(StandardCharsets.UTF_8);
}
public static String getHttpContent(String url, int timeoutMs) throws IOException {
return remoteHttpContent("GET", url, timeoutMs, null, null).toString(StandardCharsets.UTF_8);
}
public static String getHttpContent(String url, Map<String, Serializable> headers, String body) throws IOException {
return remoteHttpContent("GET", url, 0, headers, body).toString(StandardCharsets.UTF_8);
}
public static String getHttpContent(String url, int timeoutMs, Map<String, Serializable> headers, String body)
throws IOException {
return remoteHttpContent("GET", url, timeoutMs, headers, body).toString(StandardCharsets.UTF_8);
}
public static String getHttpContent(String url, Charset charset) throws IOException {
return remoteHttpContent("GET", url, 0, null, null).toString(charset.name());
}
public static String getHttpContent(String url, int timeoutMs, Charset charset) throws IOException {
return remoteHttpContent("GET", url, timeoutMs, null, null).toString(charset.name());
}
public static String getHttpContent(String url, Charset charset, Map<String, Serializable> headers, String body)
throws IOException {
return remoteHttpContent("GET", url, 0, headers, body).toString(charset.name());
}
public static String getHttpContent(
String url, int timeoutMs, Charset charset, Map<String, Serializable> headers, String body)
throws IOException {
return remoteHttpContent("GET", url, timeoutMs, headers, body).toString(charset.name());
}
public static byte[] getHttpBytesContent(String url) throws IOException {
return remoteHttpContent("GET", url, 0, null, null).toByteArray();
}
public static byte[] getHttpBytesContent(String url, int timeoutMs) throws IOException {
return remoteHttpContent("GET", url, timeoutMs, null, null).toByteArray();
}
public static byte[] getHttpBytesContent(String url, Map<String, Serializable> headers, String body)
throws IOException {
return remoteHttpContent("GET", url, 0, headers, body).toByteArray();
}
public static byte[] getHttpBytesContent(String url, int timeoutMs, Map<String, Serializable> headers, String body)
throws IOException {
return remoteHttpContent("GET", url, timeoutMs, headers, body).toByteArray();
}
public static String remoteHttpContent(HttpClient client, String method, String url, Charset charset)
throws IOException {
return remoteHttpContentAsync(client, method, url, 0, null, null)
.thenApply(out -> out.toString(charset == null ? StandardCharsets.UTF_8 : charset))
.join();
}
public static String remoteHttpContent(HttpClient client, String method, String url, int timeoutMs, Charset charset)
throws IOException {
return remoteHttpContentAsync(client, method, url, timeoutMs, null, null)
.thenApply(out -> out.toString(charset == null ? StandardCharsets.UTF_8 : charset))
.join();
}
public static String remoteHttpContent(
HttpClient client, String method, String url, Charset charset, Map<String, Serializable> headers)
throws IOException {
return remoteHttpContentAsync(client, method, url, 0, headers, null)
.thenApply(out -> out.toString(charset == null ? StandardCharsets.UTF_8 : charset))
.join();
}
public static String remoteHttpContent(
HttpClient client,
String method,
String url,
Charset charset,
Map<String, Serializable> headers,
String body)
throws IOException {
return remoteHttpContentAsync(client, method, url, 0, headers, body)
.thenApply(out -> out.toString(charset == null ? StandardCharsets.UTF_8 : charset))
.join();
}
public static String remoteHttpContent(
HttpClient client,
String method,
String url,
int timeoutMs,
Charset charset,
Map<String, Serializable> headers)
throws IOException {
return remoteHttpContentAsync(client, method, url, timeoutMs, headers, null)
.thenApply(out -> out.toString(charset == null ? StandardCharsets.UTF_8 : charset))
.join();
}
public static String remoteHttpContent(
HttpClient client,
String method,
String url,
int timeoutMs,
Charset charset,
Map<String, Serializable> headers,
String body)
throws IOException {
return remoteHttpContentAsync(client, method, url, timeoutMs, headers, body)
.thenApply(out -> out.toString(charset == null ? StandardCharsets.UTF_8 : charset))
.join();
}
public static byte[] remoteHttpBytesContent(
HttpClient client,
String method,
String url,
Charset charset,
Map<String, Serializable> headers,
String body)
throws IOException {
return remoteHttpContentAsync(client, method, url, 0, headers, body)
.thenApply(out -> out.toByteArray())
.join();
}
public static byte[] remoteHttpBytesContent(
HttpClient client,
String method,
String url,
int timeoutMs,
Charset charset,
Map<String, Serializable> headers)
throws IOException {
return remoteHttpContentAsync(client, method, url, timeoutMs, headers, null)
.thenApply(out -> out.toByteArray())
.join();
}
public static byte[] remoteHttpBytesContent(
HttpClient client,
String method,
String url,
int timeoutMs,
Charset charset,
Map<String, Serializable> headers,
String body)
throws IOException {
return remoteHttpContentAsync(client, method, url, timeoutMs, headers, body)
.thenApply(out -> out.toByteArray())
.join();
}
public static ByteArrayOutputStream remoteHttpContent(
String method, String url, Map<String, Serializable> headers, String body) throws IOException {
return remoteHttpContent(method, url, 0, headers, body);
}
public static ByteArrayOutputStream remoteHttpContent(
String method, String url, int timeoutMs, Map<String, Serializable> headers, String body)
throws IOException {
return remoteHttpContentAsync(method, url, timeoutMs, headers, body).join();
}
public static ByteArrayOutputStream remoteHttpContent(
HttpClient client, String method, String url, int timeoutMs, Map<String, Serializable> headers, String body)
throws IOException {
return remoteHttpContentAsync(client, method, url, timeoutMs, headers, body)
.join();
}
public static CompletableFuture<String> postHttpContentAsync(String url) {
return remoteHttpContentAsync("POST", url, 0, null, null)
.thenApply(out -> out.toString(StandardCharsets.UTF_8));
}
public static CompletableFuture<String> postHttpContentAsync(String url, Map<String, Serializable> respHeaders) {
return remoteHttpContentAsync("POST", url, 0, null, null, respHeaders)
.thenApply(out -> out.toString(StandardCharsets.UTF_8));
}
public static CompletableFuture<String> postHttpContentAsync(String url, int timeoutMs) {
return remoteHttpContentAsync("POST", url, timeoutMs, null, null)
.thenApply(out -> out.toString(StandardCharsets.UTF_8));
}
public static CompletableFuture<String> postHttpContentAsync(
String url, int timeoutMs, Map<String, Serializable> respHeaders) {
return remoteHttpContentAsync("POST", url, timeoutMs, null, null, respHeaders)
.thenApply(out -> out.toString(StandardCharsets.UTF_8));
}
public static CompletableFuture<String> postHttpContentAsync(String url, String body) {
return remoteHttpContentAsync("POST", url, 0, null, body)
.thenApply(out -> out.toString(StandardCharsets.UTF_8));
}
public static CompletableFuture<String> postHttpContentAsync(
String url, String body, Map<String, Serializable> respHeaders) {
return remoteHttpContentAsync("POST", url, 0, null, body, respHeaders)
.thenApply(out -> out.toString(StandardCharsets.UTF_8));
}
public static CompletableFuture<String> postHttpContentAsync(String url, int timeoutMs, String body) {
return remoteHttpContentAsync("POST", url, timeoutMs, null, body)
.thenApply(out -> out.toString(StandardCharsets.UTF_8));
}
public static CompletableFuture<String> postHttpContentAsync(
String url, int timeoutMs, String body, Map<String, Serializable> respHeaders) {
return remoteHttpContentAsync("POST", url, timeoutMs, null, body, respHeaders)
.thenApply(out -> out.toString(StandardCharsets.UTF_8));
}
public static CompletableFuture<String> postHttpContentAsync(
String url, Map<String, Serializable> headers, String body) {
return remoteHttpContentAsync("POST", url, 0, headers, body)
.thenApply(out -> out.toString(StandardCharsets.UTF_8));
}
public static CompletableFuture<String> postHttpContentAsync(
String url, Map<String, Serializable> headers, String body, Map<String, Serializable> respHeaders) {
return remoteHttpContentAsync("POST", url, 0, headers, body, respHeaders)
.thenApply(out -> out.toString(StandardCharsets.UTF_8));
}
public static CompletableFuture<String> postHttpContentAsync(
String url, int timeoutMs, Map<String, Serializable> headers, String body) {
return remoteHttpContentAsync("POST", url, timeoutMs, headers, body)
.thenApply(out -> out.toString(StandardCharsets.UTF_8));
}
public static CompletableFuture<String> postHttpContentAsync(
String url,
int timeoutMs,
Map<String, Serializable> headers,
String body,
Map<String, Serializable> respHeaders) {
return remoteHttpContentAsync("POST", url, timeoutMs, headers, body, respHeaders)
.thenApply(out -> out.toString(StandardCharsets.UTF_8));
}
public static CompletableFuture<String> postHttpContentAsync(String url, Charset charset) {
return remoteHttpContentAsync("POST", url, 0, null, null).thenApply(out -> out.toString(charset));
}
public static CompletableFuture<String> postHttpContentAsync(
String url, Charset charset, Map<String, Serializable> respHeaders) {
return remoteHttpContentAsync("POST", url, 0, null, null, respHeaders).thenApply(out -> out.toString(charset));
}
public static CompletableFuture<String> postHttpContentAsync(String url, int timeoutMs, Charset charset) {
return remoteHttpContentAsync("POST", url, timeoutMs, null, null).thenApply(out -> out.toString(charset));
}
public static CompletableFuture<String> postHttpContentAsync(
String url, int timeoutMs, Charset charset, Map<String, Serializable> respHeaders) {
return remoteHttpContentAsync("POST", url, timeoutMs, null, null, respHeaders)
.thenApply(out -> out.toString(charset));
}
public static CompletableFuture<String> postHttpContentAsync(String url, Charset charset, String body) {
return remoteHttpContentAsync("POST", url, 0, null, body).thenApply(out -> out.toString(charset));
}
public static CompletableFuture<String> postHttpContentAsync(
String url, Charset charset, String body, Map<String, Serializable> respHeaders) {
return remoteHttpContentAsync("POST", url, 0, null, body, respHeaders).thenApply(out -> out.toString(charset));
}
public static CompletableFuture<String> postHttpContentAsync(
HttpClient client, String url, Charset charset, String body) {
return remoteHttpContentAsync(client, "POST", url, 0, null, body).thenApply(out -> out.toString(charset));
}
public static CompletableFuture<String> postHttpContentAsync(
HttpClient client, String url, Charset charset, String body, Map<String, Serializable> respHeaders) {
return remoteHttpContentAsync(client, "POST", url, 0, null, body, respHeaders)
.thenApply(out -> out.toString(charset));
}
public static CompletableFuture<String> postHttpContentAsync(
HttpClient client, String url, Map<String, Serializable> headers, String body) {
return remoteHttpContentAsync(client, "POST", url, 0, headers, body)
.thenApply(out -> out.toString(StandardCharsets.UTF_8));
}
public static CompletableFuture<String> postHttpContentAsync(
HttpClient client,
String url,
Map<String, Serializable> headers,
String body,
Map<String, Serializable> respHeaders) {
return remoteHttpContentAsync(client, "POST", url, 0, headers, body, respHeaders)
.thenApply(out -> out.toString(StandardCharsets.UTF_8));
}
public static CompletableFuture<String> postHttpContentAsync(
HttpClient client, String url, Charset charset, Map<String, Serializable> headers, String body) {
return remoteHttpContentAsync(client, "POST", url, 0, headers, body).thenApply(out -> out.toString(charset));
}
public static CompletableFuture<String> postHttpContentAsync(
HttpClient client,
String url,
Charset charset,
Map<String, Serializable> headers,
String body,
Map<String, Serializable> respHeaders) {
return remoteHttpContentAsync(client, "POST", url, 0, headers, body, respHeaders)
.thenApply(out -> out.toString(charset));
}
public static CompletableFuture<String> postHttpContentAsync(
String url, int timeoutMs, Charset charset, String body) {
return remoteHttpContentAsync("POST", url, timeoutMs, null, body).thenApply(out -> out.toString(charset));
}
public static CompletableFuture<String> postHttpContentAsync(
String url, int timeoutMs, Charset charset, String body, Map<String, Serializable> respHeaders) {
return remoteHttpContentAsync("POST", url, timeoutMs, null, body, respHeaders)
.thenApply(out -> out.toString(charset));
}
public static CompletableFuture<String> postHttpContentAsync(
String url, Charset charset, Map<String, Serializable> headers, String body) {
return remoteHttpContentAsync("POST", url, 0, headers, body).thenApply(out -> out.toString(charset));
}
public static CompletableFuture<String> postHttpContentAsync(
String url,
Charset charset,
Map<String, Serializable> headers,
String body,
Map<String, Serializable> respHeaders) {
return remoteHttpContentAsync("POST", url, 0, headers, body, respHeaders)
.thenApply(out -> out.toString(charset));
}
public static CompletableFuture<String> postHttpContentAsync(
String url, int timeoutMs, Charset charset, Map<String, Serializable> headers, String body) {
return remoteHttpContentAsync("POST", url, timeoutMs, headers, body).thenApply(out -> out.toString(charset));
}
public static CompletableFuture<String> postHttpContentAsync(
String url,
int timeoutMs,
Charset charset,
Map<String, Serializable> headers,
String body,
Map<String, Serializable> respHeaders) {
return remoteHttpContentAsync("POST", url, timeoutMs, headers, body, respHeaders)
.thenApply(out -> out.toString(charset));
}
public static CompletableFuture<byte[]> postHttpBytesContentAsync(String url) {
return remoteHttpContentAsync("POST", url, 0, null, null).thenApply(out -> out.toByteArray());
}
public static CompletableFuture<byte[]> postHttpBytesContentAsync(
String url, Map<String, Serializable> respHeaders) {
return remoteHttpContentAsync("POST", url, 0, null, null, respHeaders).thenApply(out -> out.toByteArray());
}
public static CompletableFuture<byte[]> postHttpBytesContentAsync(String url, int timeoutMs) {
return remoteHttpContentAsync("POST", url, timeoutMs, null, null).thenApply(out -> out.toByteArray());
}
public static CompletableFuture<byte[]> postHttpBytesContentAsync(
String url, int timeoutMs, Map<String, Serializable> respHeaders) {
return remoteHttpContentAsync("POST", url, timeoutMs, null, null, respHeaders)
.thenApply(out -> out.toByteArray());
}
public static CompletableFuture<byte[]> postHttpBytesContentAsync(
String url, Map<String, Serializable> headers, String body) {
return remoteHttpContentAsync("POST", url, 0, headers, body).thenApply(out -> out.toByteArray());
}
public static CompletableFuture<byte[]> postHttpBytesContentAsync(
String url, Map<String, Serializable> headers, String body, Map<String, Serializable> respHeaders) {
return remoteHttpContentAsync("POST", url, 0, headers, body, respHeaders)
.thenApply(out -> out.toByteArray());
}
public static CompletableFuture<byte[]> postHttpBytesContentAsync(
String url, int timeoutMs, Map<String, Serializable> headers, String body) {
return remoteHttpContentAsync("POST", url, timeoutMs, headers, body).thenApply(out -> out.toByteArray());
}
public static CompletableFuture<byte[]> postHttpBytesContentAsync(
String url,
int timeoutMs,
Map<String, Serializable> headers,
String body,
Map<String, Serializable> respHeaders) {
return remoteHttpContentAsync("POST", url, timeoutMs, headers, body, respHeaders)
.thenApply(out -> out.toByteArray());
}
public static CompletableFuture<String> getHttpContentAsync(String url) {
return remoteHttpContentAsync("GET", url, 0, null, null).thenApply(out -> out.toString(StandardCharsets.UTF_8));
}
public static CompletableFuture<String> getHttpContentAsync(String url, Map<String, Serializable> respHeaders) {
return remoteHttpContentAsync("GET", url, 0, null, null, respHeaders)
.thenApply(out -> out.toString(StandardCharsets.UTF_8));
}
public static CompletableFuture<String> getHttpContentAsync(String url, int timeoutMs) {
return remoteHttpContentAsync("GET", url, timeoutMs, null, null)
.thenApply(out -> out.toString(StandardCharsets.UTF_8));
}
public static CompletableFuture<String> getHttpContentAsync(
String url, int timeoutMs, Map<String, Serializable> respHeaders) {
return remoteHttpContentAsync("GET", url, timeoutMs, null, null, respHeaders)
.thenApply(out -> out.toString(StandardCharsets.UTF_8));
}
public static CompletableFuture<String> getHttpContentAsync(
String url, Map<String, Serializable> headers, String body) {
return remoteHttpContentAsync("GET", url, 0, headers, body)
.thenApply(out -> out.toString(StandardCharsets.UTF_8));
}
public static CompletableFuture<String> getHttpContentAsync(
String url, Map<String, Serializable> headers, String body, Map<String, Serializable> respHeaders) {
return remoteHttpContentAsync("GET", url, 0, headers, body, respHeaders)
.thenApply(out -> out.toString(StandardCharsets.UTF_8));
}
public static CompletableFuture<String> getHttpContentAsync(
String url, int timeoutMs, Map<String, Serializable> headers, String body) {
return remoteHttpContentAsync("GET", url, timeoutMs, headers, body)
.thenApply(out -> out.toString(StandardCharsets.UTF_8));
}
public static CompletableFuture<String> getHttpContentAsync(
String url,
int timeoutMs,
Map<String, Serializable> headers,
String body,
Map<String, Serializable> respHeaders) {
return remoteHttpContentAsync("GET", url, timeoutMs, headers, body, respHeaders)
.thenApply(out -> out.toString(StandardCharsets.UTF_8));
}
public static CompletableFuture<String> getHttpContentAsync(String url, Charset charset) {
return remoteHttpContentAsync("GET", url, 0, null, null).thenApply(out -> out.toString(charset));
}
public static CompletableFuture<String> getHttpContentAsync(
String url, Charset charset, Map<String, Serializable> respHeaders) {
return remoteHttpContentAsync("GET", url, 0, null, null, respHeaders).thenApply(out -> out.toString(charset));
}
public static CompletableFuture<String> getHttpContentAsync(String url, int timeoutMs, Charset charset) {
return remoteHttpContentAsync("GET", url, timeoutMs, null, null).thenApply(out -> out.toString(charset));
}
public static CompletableFuture<String> getHttpContentAsync(
String url, int timeoutMs, Charset charset, Map<String, Serializable> respHeaders) {
return remoteHttpContentAsync("GET", url, timeoutMs, null, null, respHeaders)
.thenApply(out -> out.toString(charset));
}
public static CompletableFuture<String> getHttpContentAsync(
String url, Charset charset, Map<String, Serializable> headers, String body) {
return remoteHttpContentAsync("GET", url, 0, headers, body).thenApply(out -> out.toString(charset));
}
public static CompletableFuture<String> getHttpContentAsync(
String url,
Charset charset,
Map<String, Serializable> headers,
String body,
Map<String, Serializable> respHeaders) {
return remoteHttpContentAsync("GET", url, 0, headers, body, respHeaders)
.thenApply(out -> out.toString(charset));
}
public static CompletableFuture<String> getHttpContentAsync(
String url, int timeoutMs, Charset charset, Map<String, Serializable> headers, String body) {
return remoteHttpContentAsync("GET", url, timeoutMs, headers, body).thenApply(out -> out.toString(charset));
}
public static CompletableFuture<String> getHttpContentAsync(
String url,
int timeoutMs,
Charset charset,
Map<String, Serializable> headers,
String body,
Map<String, Serializable> respHeaders) {
return remoteHttpContentAsync("GET", url, timeoutMs, headers, body, respHeaders)
.thenApply(out -> out.toString(charset));
}
public static CompletableFuture<String> getHttpContentAsync(
java.net.http.HttpClient client, String url, String body, Map<String, Serializable> respHeaders) {
return remoteHttpContentAsync(client, "GET", url, 0, null, body, respHeaders)
.thenApply(out -> out.toString(StandardCharsets.UTF_8));
}
public static CompletableFuture<String> getHttpContentAsync(
java.net.http.HttpClient client,
String url,
Charset charset,
String body,
Map<String, Serializable> respHeaders) {
return remoteHttpContentAsync(client, "GET", url, 0, null, body, respHeaders)
.thenApply(out -> out.toString(charset));
}
public static CompletableFuture<String> getHttpContentAsync(
java.net.http.HttpClient client,
String url,
Charset charset,
Map<String, Serializable> headers,
String body,
Map<String, Serializable> respHeaders) {
return remoteHttpContentAsync(client, "GET", url, 0, headers, body, respHeaders)
.thenApply(out -> out.toString(charset));
}
public static CompletableFuture<byte[]> getHttpBytesContentAsync(String url) {
return remoteHttpContentAsync("GET", url, 0, null, null).thenApply(out -> out.toByteArray());
}
public static CompletableFuture<byte[]> getHttpBytesContentAsync(
String url, Map<String, Serializable> respHeaders) {
return remoteHttpContentAsync("GET", url, 0, null, null, respHeaders).thenApply(out -> out.toByteArray());
}
public static CompletableFuture<byte[]> getHttpBytesContentAsync(String url, int timeoutMs) {
return remoteHttpContentAsync("GET", url, timeoutMs, null, null).thenApply(out -> out.toByteArray());
}
public static CompletableFuture<byte[]> getHttpBytesContentAsync(
String url, int timeoutMs, Map<String, Serializable> respHeaders) {
return remoteHttpContentAsync("GET", url, timeoutMs, null, null, respHeaders)
.thenApply(out -> out.toByteArray());
}
public static CompletableFuture<byte[]> getHttpBytesContentAsync(
String url, Map<String, Serializable> headers, String body) {
return remoteHttpContentAsync("GET", url, 0, headers, body).thenApply(out -> out.toByteArray());
}
public static CompletableFuture<byte[]> getHttpBytesContentAsync(
String url, Map<String, Serializable> headers, String body, Map<String, Serializable> respHeaders) {
return remoteHttpContentAsync("GET", url, 0, headers, body, respHeaders).thenApply(out -> out.toByteArray());
}
public static CompletableFuture<byte[]> getHttpBytesContentAsync(
String url, int timeoutMs, Map<String, Serializable> headers, String body) {
return remoteHttpContentAsync("GET", url, timeoutMs, headers, body).thenApply(out -> out.toByteArray());
}
public static CompletableFuture<byte[]> getHttpBytesContentAsync(
String url,
int timeoutMs,
Map<String, Serializable> headers,
String body,
Map<String, Serializable> respHeaders) {
return remoteHttpContentAsync("GET", url, timeoutMs, headers, body, respHeaders)
.thenApply(out -> out.toByteArray());
}
public static CompletableFuture<byte[]> getHttpBytesContentAsync(
java.net.http.HttpClient client,
String url,
int timeoutMs,
Map<String, Serializable> headers,
String body,
Map<String, Serializable> respHeaders) {
return remoteHttpContentAsync(client, "GET", url, timeoutMs, headers, body, respHeaders)
.thenApply(out -> out.toByteArray());
}
public static CompletableFuture<ByteArrayOutputStream> remoteHttpContentAsync(
String method, String url, Map<String, Serializable> headers, String body) {
return remoteHttpContentAsync(method, url, 0, headers, body);
}
public static CompletableFuture<ByteArrayOutputStream> remoteHttpContentAsync(
String method,
String url,
Map<String, Serializable> headers,
String body,
Map<String, Serializable> respHeaders) {
return remoteHttpContentAsync(method, url, 0, headers, body, respHeaders);
}
public static CompletableFuture<ByteArrayOutputStream> remoteHttpContentAsync(
String method, String url, int timeoutMs, Map<String, Serializable> headers, String body) {
return remoteHttpContentAsync(httpClient, method, url, timeoutMs, headers, body);
}
public static CompletableFuture<ByteArrayOutputStream> remoteHttpContentAsync(
String method,
String url,
int timeoutMs,
Map<String, Serializable> headers,
String body,
Map<String, Serializable> respHeaders) {
return remoteHttpContentAsync(httpClient, method, url, timeoutMs, headers, body, respHeaders);
}
public static CompletableFuture<ByteArrayOutputStream> remoteHttpContentAsync(
java.net.http.HttpClient client,
String method,
String url,
int timeoutMs,
Map<String, Serializable> headers,
String body) {
return remoteHttpContentAsync(client, method, url, timeoutMs, headers, body, null);
}
public static CompletableFuture<ByteArrayOutputStream> remoteHttpContentAsync(
java.net.http.HttpClient client,
String method,
String url,
int timeoutMs,
Map<String, Serializable> headers,
String body,
Map<String, Serializable> respHeaders) {
java.net.http.HttpRequest.Builder builder = java.net.http.HttpRequest.newBuilder()
.uri(URI.create(url))
.timeout(Duration.ofMillis(timeoutMs > 0 ? timeoutMs : 6000))
.method(
method,
body == null
? java.net.http.HttpRequest.BodyPublishers.noBody()
: java.net.http.HttpRequest.BodyPublishers.ofString(body));
if (headers != null) {
headers.forEach((n, v) -> {
if (v instanceof Collection) {
for (Object val : (Collection) v) {
builder.header(n, val.toString());
}
} else {
builder.header(n, v.toString());
}
});
}
java.net.http.HttpClient c = client == null ? httpClient : client;
if (c == null) {
clientLock.lock();
try {
if (httpClient == null) {
httpClient = java.net.http.HttpClient.newHttpClient();
}
} finally {
clientLock.unlock();
}
c = httpClient;
}
return c.sendAsync(builder.build(), java.net.http.HttpResponse.BodyHandlers.ofByteArray())
.thenCompose((java.net.http.HttpResponse<byte[]> resp) -> {
final int rs = resp.statusCode();
if (rs == 301 || rs == 302) {
Optional<String> opt = resp.headers().firstValue("Location");
if (opt.isPresent()) {
return remoteHttpContentAsync(client, method, opt.get(), timeoutMs, headers, body);
} else {
return CompletableFuture.failedFuture(
new IOException(url + " httpcode = " + rs + ", but not found Localtion"));
}
}
byte[] result = resp.body();
if (rs == 200 || result != null) {
if (respHeaders != null) {
resp.headers().map().forEach((k, l) -> {
if (!l.isEmpty()) {
respHeaders.put(k, l.get(0));
}
});
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
if (result != null) {
if ("gzip"
.equalsIgnoreCase(resp.headers()
.firstValue("content-encoding")
.orElse(null))) {
try {
GZIPInputStream in = new GZIPInputStream(new ByteArrayInputStream(result));
in.transferTo(out);
} catch (IOException e) {
return CompletableFuture.failedFuture(e);
}
} else {
out.writeBytes(result);
}
}
return CompletableFuture.completedFuture(out);
}
return CompletableFuture.failedFuture(new RetcodeException(rs, url + " httpcode = " + rs));
});
}
//
// public static ByteArrayOutputStream remoteHttpContent(SSLContext ctx, String method, String url, int
// timeoutMs, Map<String, Serializable> headers, String body) throws IOException {
// HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
// boolean opening = true;
// try {
// conn.setConnectTimeout(timeoutMs > 0 ? timeoutMs : 30000);
// conn.setReadTimeout(timeoutMs > 0 ? timeoutMs : 30000);
// if (conn instanceof HttpsURLConnection) {
// HttpsURLConnection httpsconn = ((HttpsURLConnection) conn);
// httpsconn.setSSLSocketFactory((ctx == null ? DEFAULTSSL_CONTEXT : ctx).getSocketFactory());
// httpsconn.setHostnameVerifier(defaultVerifier);
// }
// conn.setRequestMethod(method);
// if (headers != null) {
// for (Map.Entry<String, String> en : headers.entrySet()) {
// conn.setRequestProperty(en.getKey(), en.getValue());
// }
// }
// if (body != null && !body.isEmpty()) { //conn.getOutputStream()会将GET强制变成POST
// conn.setDoInput(true);
// conn.setDoOutput(true);
// conn.getOutputStream().write(body.getBytes(UTF_8));
// }
// conn.connect();
// int rs = conn.getResponseCode();
// if (rs == 301 || rs == 302) {
// String newurl = conn.getHeaderField("Location");
// conn.disconnect();
// opening = false;
// return remoteHttpContent(ctx, method, newurl, timeoutMs, headers, body);
// }
// InputStream in = (rs < 400 || rs == 404) && rs != 405 ? conn.getInputStream() : conn.getErrorStream();
// if ("gzip".equalsIgnoreCase(conn.getContentEncoding())) in = new GZIPInputStream(in);
// ByteArrayOutputStream out = new ByteArrayOutputStream(1024);
// byte[] bytes = new byte[1024];
// int pos;
// while ((pos = in.read(bytes)) != -1) {
// out.write(bytes, 0, pos);
// }
// in.close();
// return out;
// } finally {
// if (opening) conn.disconnect();
// }
// }
public static String read(InputStream in) throws IOException {
return read(in, StandardCharsets.UTF_8, false);
}
public static String readThenClose(InputStream in) throws IOException {
return read(in, StandardCharsets.UTF_8, true);
}
public static String read(InputStream in, String charsetName) throws IOException {
return read(in, Charset.forName(charsetName), false);
}
public static String read(InputStream in, Charset charset) throws IOException {
return read(in, charset, false);
}
private static String read(InputStream in, Charset charset, boolean close) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream(1024);
byte[] bytes = new byte[1024];
int pos;
while ((pos = in.read(bytes)) != -1) {
out.write(bytes, 0, pos);
}
if (close) {
in.close();
}
return charset == null ? out.toString() : out.toString(charset);
}
public static ByteArrayOutputStream readStream(InputStream in) throws IOException {
return readStream(in, false);
}
public static ByteArrayOutputStream readStreamThenClose(InputStream in) throws IOException {
return readStream(in, true);
}
private static ByteArrayOutputStream readStream(InputStream in, boolean close) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream(1024);
byte[] bytes = new byte[1024];
int pos;
while ((pos = in.read(bytes)) != -1) {
out.write(bytes, 0, pos);
}
if (close) {
in.close();
}
return out;
}
public static byte[] readBytes(File file) throws IOException {
return readBytesThenClose(new FileInputStream(file));
}
public static byte[] readBytes(InputStream in) throws IOException {
return readStream(in).toByteArray();
}
public static byte[] readBytesThenClose(InputStream in) throws IOException {
return readStreamThenClose(in).toByteArray();
}
}