0、包装类型比较使用equals,而不是==
Long a = 11L;
Long b = 11L;
a.equals(b);
int result = Long.compare(a, b)
a>b result>0
a=b result=0
a<b result<0
1、得到当前的方法名
String methodName = Thread.currentThread().getStackTrace()[1].getMethodName();
2、打印时间
/* Given elaspedTime in ms, return a printable string */
public static String time2Str(long elapsedTime) {
String unit;
double time = elapsedTime;
if (elapsedTime < 1000) {
unit = "milliseconds";
} else if (elapsedTime < 60 * 1000) {
unit = "seconds";
time = time / 1000;
} else if (elapsedTime < 3600 * 1000) {
unit = "minutes";
time = time / (60 * 1000);
} else {
unit = "hours";
time = time / (3600 * 1000);
}
return time + " " + unit;
}
3、改变数组大小
private static Object resizeArray(Object oldArray, int newSize) {
int oldSize = Array.getLength(oldArray);
Class elementType = oldArray.getClass().getComponentType();
Object newArray = java.lang.reflect.Array.newInstance(
elementType,newSize);
int preserveLength = Math.min(oldSize,newSize);
if (preserveLength > 0)
System.arraycopy(oldArray, 0, newArray, 0, preserveLength);
return newArray;
}
4、产生随机数
random.nextInt(max) % (max - min + 1) + min
// nextInt is normally exclusive of the top value,
// so add 1 to make it inclusive
import java.util.concurrent.ThreadLocalRandom;
int randomNum = ThreadLocalRandom.current().nextInt(min, max + 1);
// java8
int randomNumber = random.ints(1, min, max + 1).findFirst().getAsInt();
import org.apache.commons.math3.random.RandomDataGenerator
new RandomDataGenerator().nextInt(min, max);
import org.apache.commons.math.random.RandomData;
import org.apache.commons.math.random.RandomDataImpl;
RandomData randomData = new RandomDataImpl();
int number = randomData.nextInt(min, max);
5、测试两个List相同
import static org.junit.Assert.*;
import static org.hamcrest.CoreMatchers.*;
@Test
public void test_array_pass()
{
List<String> actual = Arrays.asList("fee", "fi", "foe");
List<String> expected = Arrays.asList("fee", "fi", "foe");
assertThat(actual, is(expected));
assertThat(actual, is(not(expected)));
}
6、数组类型转换
// 原生数组转换对象数组
int[] arr = someAPI.getSomeInts();
Integer[] virtualType = ArrayUtils.toObject(arr);
List<Integer> inputAsList = Arrays.asList(virtualType);
List<String> orderIdList = Lists.newArrayList(virtualType);
List<Integer> aList = Ints.asList(arr);
// List 转换为原生数组
int[] arr = list.stream().mapToInt(Integer::intValue).toArray();
int[] arr = ArrayUtils.toPrimitive(list.toArray(new Integer[0]))
int[] values = Ints.toArray(list);
// 字符数组转换long数组
Long[] longArrays = (Long[]) ConvertUtils.convert(stringArrays, Long[].class);
long[] longArrays = (long[]) ConvertUtils.convert(stringArrays, Long.TYPE);
// List转换数组
String[] orderIdArr = orderIdList.toArray(new String[orderIdList.size()]);
String[] orderIdArr = orderIdList.stream().toArray(String[]::new);
// 或者更通用的方式
public static <T> T[] toArray(Class<T> c, List<T> list) {
@SuppressWarnings("unchecked")
T[] ta= (T[])Array.newInstance(c, list.size());
for (int i= 0; i<list.size(); i++)
ta[i]= list.get(i);
return ta;
}
public static <T> T[] toArray(List<T> list) {
@SuppressWarnings("unchecked")
Class<T> clazz = (Class<T>)list.get(0).getClass();
return toArray(clazz, list);
}
7、BitSet与String类型转换
private static BitSet fromString(final String s) {
return BitSet.valueOf(new long[] { Long.parseLong(s, 2) });
}
private static String toString(BitSet bs) {
return Long.toString(bs.toLongArray()[0], 2);
}
8、String转换为时间
new SimpleDateFormat("yyyy-MM-dd HH:mm:SS").parse(dateStr);
9、时间格式化
Date today = Calendar.getInstance().getTime();
// 时间格式化为字符串
DateFormatUtils.format(today, "yyyy-MM-dd HH:mm:SS");
10、打印Map
org.apache.commons.collections.MapUtils.debugPrint(System.out, "Print this", myMap);
System.out.println(StringUtils.join(resultMap.entrySet().iterator(), "\n"));
11、 Spring测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(value = { "/spring/applicationContext-dal.xml"})
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
12、BeanUtils
// Apache的BeanUtils和PropertyUtils
BeanUtils.copyProperties(toBean, frombean);
PropertyUtils.copyProperties(toBean, frombean);
// Spring的BeanUtils
BeanUtils.copyProperties(frombean, toBean);
// Cglib的BeanCopier
BeanCopier bc = BeanCopier.create(FromBean.class, ToBean.class, false);
bc.copy(frombean, toBean, null);
13、object toString
ToStringBuilder.reflectionToString(lquery)
14、 设置bean属性的值
Field field = ReflectionUtils.findField(entity.getClass(), beanName);
ReflectionUtils.makeAccessible(field);
ReflectionUtils.setField(field, entity, values);
// access properties as Map
Map<String, Object> properties = BeanUtils.describe(entity);
properties.set("name","Fred");
BeanUtils.populate(entity, properties);
// access individual properties
String oldname = BeanUtils.getProperty(entity,"name");
BeanUtils.setProperty(entity,"name","Barny");
// BeanWrapper
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.PropertyAccessorFactory;
Field[] fields = ItemBean.class.getDeclaredFields();
// 性能比Apache common高4-5倍
BeanWrapper wrapper = PropertyAccessorFactory.forBeanPropertyAccess(item);
for (Field f: fields) {
FeatureSchema anno = f.getAnnotation(FeatureSchema.class);
System.out.println(f.getName() + "--" + f.getType() + "---" + anno.name() + "---" + anno.type() + "---" + anno.struct());
Object value = wrapper.getPropertyValue(fieldName);
}
15、不同创建对象的方式
// 1
PersonObj object = new PersonObj();
// 2
PersonObj object2 = (PersonObj) Class.forName("com.tutorial.PersonObj").newInstance();
// 3
PersonObj secondObject = new PersonObj();
PersonObj object3 = (PersonObj) secondObject.clone();
// 4
Object object4 = PersonObj.class.getClassLoader().loadClass("com.tutorial.PersonObj").newInstance();
// 5
Class clazz = PersonObj.class;
Constructor personCon = clazz.getDeclaredConstructors()[0];
PersonObj obj = (PersonObj) personCon.newInstance();
16、 MathUtil
// check if a String contains only digits
NumberUtils.isDigits("123.123"); // false
// check if a string is a valid number
NumberUtils.isNumber("123.123"); // true
int maxVal = 100;
RandomUtils.nextInt(maxVal);
double[] values = new double[]{2.3, 5.4, 6.2, 7.3, 23.3};
StatUtils.min(values);
StatUtils.max(values);
StatUtils.mean(values);
StatUtils.product(values);
StatUtils.sum(values);
StatUtils.variance(values);
17、线程池创建
public final class CustomThreadPoolExecutor extends ThreadPoolExecutor {
private static final Logger log = LoggerFactory.getLogger(CustomThreadPoolExecutor.class);
public CustomThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
}
public CustomThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory);
}
public CustomThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, handler);
}
public CustomThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
}
@Override
protected void beforeExecute(Thread t, Runnable r) {
if (log.isDebugEnabled()) {
log.debug("beforeExecute in thread: {}, runnable type: {}.", Thread.currentThread().getName(), r.getClass().getName());
}
}
@Override
protected void afterExecute(Runnable r, Throwable t) {
super.afterExecute(r, t);
this.logThrowableAfterExecute(r, t);
}
private void logThrowableAfterExecute(Runnable r, Throwable t) {
if (log.isDebugEnabled()) {
log.debug("afterExecute in thread: {}, runnable type: {}.", Thread.currentThread().getName(), r.getClass().getName());
}
if (t == null && r instanceof Future<?>) {
try {
((Future<?>) r).get();
} catch (ExecutionException ee) {
log.warn("Execution exception when running task in {}", Thread.currentThread().getName());
t = ee.getCause();
} catch (InterruptedException ie) {
log.warn("Thread ({}) interrupted: {}", Thread.currentThread(), ie);
Thread.currentThread().interrupt();
} catch (Throwable throwable) {
t = throwable;
}
}
if (t != null) {
log.warn("Caught exception in thread {} : {}", Thread.currentThread().getName(), t);
}
}
}
public final class CustomExecutors {
private static final Logger log = LoggerFactory.getLogger(CustomExecutors.class);
private final AtomicInteger discardThreadCount = new AtomicInteger(0);
private final ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("custom-thread-pool-%d").setUncaughtExceptionHandler(new UncaughtExceptionHandlerImpl()).build();
private final class UncaughtExceptionHandlerImpl implements Thread.UncaughtExceptionHandler {
@Override
public void uncaughtException(Thread t, Throwable e) {
log.error("Thread {} throw UncaughtException: {}", t.getName(), e.getMessage());
}
}
private final class RejectedExecutionHandlerImpl implements RejectedExecutionHandler {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
log.warn("Thread {} is rejected, now discard count: {}", r.getClass().getName(), discardThreadCount.incrementAndGet());
}
}
private final static int CORE_POOL_SIZE = 32;
private final static int MAX_POOL_SIZE = 128;
private final static int WORK_QUEUE_SIZE = 512;
private final static int KEEP_ALIVE_TIME = 30;
private final ExecutorService customThreadPoolExecutor = new CustomThreadPoolExecutor(CORE_POOL_SIZE, MAX_POOL_SIZE,
KEEP_ALIVE_TIME, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(WORK_QUEUE_SIZE),
threadFactory, new RejectedExecutionHandlerImpl());
class AsynWriteTask implements Runnable {
private UserEnv userEnv;
public AsynWriteTask(UserEnv userEnv) {
this.userEnv = userEnv;
}
private String getStatefulThreadName() {
StringBuilder sb = new StringBuilder();
sb.append(", AppName: ").append(userEnv.getAppName()).append(", StartTime: ")
.append(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
return sb.toString();
}
@Override
public void run() {
final Thread currentThread = Thread.currentThread();
final String oldName = currentThread.getName();
final String statefulName = getStatefulThreadName();
currentThread.setName(statefulName + "-" + oldName);
try {
putTask(userEnv, appName);
} finally {
currentThread.setName(oldName);
}
}
}
// 使用ListenableFuture添加回调
private final ListeningExecutorService listeningExecutorService = MoreExecutors.listeningDecorator(
new CustomThreadPoolExecutor(CORE_POOL_SIZE, MAX_POOL_SIZE, KEEP_ALIVE_TIME, TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(WORK_QUEUE_SIZE), threadFactory));
ListenableFuture<List<InfoTO>> futureTaskResult = listeningExecutorService.submit(new BatchQueryInfoTask(subOrderArr));
Futures.addCallback(futureTaskResult, new FutureCallback<List<InfoTO>>() {
@Override
public void onSuccess(@Nullable List<InfoTO> result) {
logger.info("Query order info callback success: {}", result);
}
@Override
public void onFailure(Throwable t) {
logger.error("Query order info callback error: {}", t.getMessage(), t);
}
});
}
18、复写对象的equals和hashCode方法
public class User {
private String name;
private int age;
private String passport;
//getters and setters, constructor
@Override
public boolean equals(Object o) {
if (o == this) return true;
if (!(o instanceof User)) {
return false;
}
User user = (User) o;
return new EqualsBuilder()
.append(age, user.age)
.append(name, user.name)
.append(passport, user.passport)
.isEquals();
}
@Override
public int hashCode() {
return new HashCodeBuilder(17, 37)
.append(name)
.append(age)
.append(passport)
.toHashCode();
}
}
@Override
public int compareTo(@Nonnull User o) {
return new CompareToBuilder()
.append(o.age, this.age)
.append(o.name, this.name)
.toComparison();
}
19、截取原有集合的部分数据
Set<Integer> subset = ImmutableSet.copyOf(Iterables.limit(set, 20));
// 获取第一个元素
String first = set.stream().findFirst().get();
String first = set.iterator().next();
// 获取最后一个
String lastElement = Iterables.getLast(set, null);
20、数组查找元素索引
// 对象数组
String[] lilyFlowers = {
"Lily of the valley",
"Lily Elite",
"Lily Monte Negro",
"Lily Casa Blanca",
"Lily of the Nile – Alba",
"Lily Stargazer"};
int indexOfFlower = Iterators.indexOf(Iterators.forArray(lilyFlowers), new Predicate<String>() {
public boolean apply(String input) {
return input.equals("Lily Elite");
}
});
int indexOfFlower = ArrayUtils.indexOf(lilyFlowers, "Lily Elite");
// 原生数组
int [] twoQuarters = {1, 2, 3, 4, 5, 6};
int lastMonthInFirstQuarter = Ints.indexOf(twoQuarters, 3);
int lastMonthInFirstQuarter = ArrayUtils.indexOf(twoQuarters, 3);
21、数组中元素是否存在元素
Integer[] vikQueensLosingSeasons = {
1962, 1967, 1984, 2011, 1966,
1963, 1982, 2001, 1990, 2002,
2006, 2010, 1965, 1972, 1979,
1981, 1985};
boolean hadALosingSeason = Arrays
.asList(vikQueensLosingSeasons)
.contains(new Integer(1962));
boolean yearExists = Ints.contains(vikQueensLosingSeasons, 1972);
Optional<Integer> contains = Iterators.tryFind(
Iterators.forArray(vikQueensLosingSeasons),
new Predicate<Integer>() {
public boolean apply(Integer input) {
if (input == 1962) {
return true;
} else {
return false;
}
}
});
boolean losingSeason = ArrayUtils.contains(vikQueensLosingSeasons, 1962);
boolean contains = IntStream.of(vikQueensLosingSeasons).anyMatch(x -> x == 1962);
22、根据范围产生数据
Range<Integer> range = Range.closed(20, 30);
Set<Integer> ranges = ContiguousSet.create(range,
DiscreteDomain.integers());
23、合并字节数组
// 1 Use a ByteBuffer
ByteBuffer target = ByteBuffer.wrap(bigByteArray);
target.put(small1);
target.put(small2);
// 2 System.arraycopy
public static void copySmallArraysToBigArray(final byte[][] smallArrays,
final byte[] bigArray){
int currentOffset = 0;
for(final byte[] currentArray : smallArrays){
System.arraycopy(currentArray, 0, bigArray, currentOffset, currentArray.length);
currentOffset += currentArray.length;
}
}
// 其他类型
public static <T> T[] concat(T[] first, T[] second) {
T[] result = Arrays.copyOf(first, first.length + second.length);
System.arraycopy(second, 0, result, first.length, second.length);
return result;
}
public static <T> T[] concatAll(T[] first, T[]... rest) {
int totalLength = first.length;
for (T[] array : rest) {
totalLength += array.length;
}
T[] result = Arrays.copyOf(first, totalLength);
int offset = first.length;
for (T[] array : rest) {
System.arraycopy(array, 0, result, offset, array.length);
offset += array.length;
}
return result;
}
// 3 ByteArrayOutputStream
public byte[] concatenateByteArrays(List<byte[]> blocks) {
ByteArrayOutputStream os = new ByteArrayOutputStream();
for (byte[] b : blocks) {
os.write(b, 0, b.length);
}
return os.toByteArray();
}
// 4、ArrayUtils
Byte[] both = (Byte[])ArrayUtils.addAll(first, second);
// java8
String[] both = Stream.concat(Arrays.stream(a), Arrays.stream(b))
.toArray(String[]::new);
String[] both = Stream.of(a, b).flatMap(Stream::of)
.toArray(String[]::new);
// Guava ObjectArrays
String[] both = ObjectArrays.concat(first, second, String.class);
Bytes.concat(first, second)
Ints.concat(first, second)
24、加密
// MD5 加密
byte[] encrypt(byte[] obj) {
MessageDigest md5 = MessageDigest.getInstance("MD5");
md5.update(obj);
return md5.digest();
}
// SHA 加密
byte[] encrypt(byte[] obj) {
MessageDigest sha = MessageDigest.getInstance("SHA");
sha.update(obj);
return sha.digest();
}
// guava
Hashing.md5().hashBytes(input.getBytes()).toString();
Hashing.sha256().hashBytes(input.getBytes()).toString();
Hashing.sha512().hashBytes(input.getBytes()).toString();
Hashing.crc32().hashBytes(input.getBytes()).toString();
25、时间工具
// 时间段
Date end = new Date(new Date());
Date start = new DateTime(end).minusDays(90).toDate();
// 年月日时分秒生成
DateTime dt = new DateTime(2016, 10, 20, 13, 14, 0, 0);
// ISO8601形式生成
DateTime dt = new DateTime("2012-05-20");
DateTime dt = new DateTime("2012-05-20T13:14:00");
DateTime.parse("2012-05-20 13:14:00", DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:SS"))
// 星期
dt.getDayOfWeek()
DateTimeConstants.SUNDAY DateTimeConstants.MONDAY ...
// 月末日期
DateTime lastday = dt.dayOfMonth().withMaximumValue();
// 90天后那周的周一
DateTime firstday = dt.plusDays(90).dayOfWeek().withMinimumValue();
DateTime begin = new DateTime("2012-02-01");
DateTime end = new DateTime("2012-05-01");
// 计算区间毫秒数
Duration d = new Duration(begin, end);
long time = d.getMillis();
// 计算区间天数
Period p = new Period(begin, end, PeriodType.days());
int days = p.getDays();
// 计算特定日期是否在该区间内
Interval i = new Interval(begin, end);
boolean contained = i.contains(new DateTime("2012-03-01"));
// 日期比较
begin.isAfterNow();
begin.isAfter(end);
// 格式化输出
dateTime.toString("yyyy-MM-dd HH:mm:ss");
26、获取枚举对象
public enum CheckType {
COMMON_TYPE(1),
UNFOUND(-1);
private CheckType(Integer type) {
// for getEmumByType2
this.type = type;
// for getEmumByType1
Holder.MAP.put(type, this);
}
private Integer type;
public Integer getType() {
return type;
}
public void setType() {
this.type = type;
}
private static class Holder {
static Map<Integer, CheckType> MAP = Maps.newHashMap();
}
public static CheckType getEmumByType1(@Nullable final Integer type) {
CheckType checkType = Holder.MAP.get(type);
return Optional.fromNullable(checkType).or(UNFOUND);
}
public static CheckType getEmumByType2(@Nullable final Integer type) {
return EnumSet.allOf(CheckType.class)
.stream()
.filter(t -> type.equals(t.getType()))
.findFirst()
.orElse(UNFOUND);
}
public static CheckType getEnumByName(@Nullable final String enumName) {
CheckType checkType = EnumUtils.getEnum(CheckType.class, enumName);
return Optional.fromNullable(checkType).or(UNFOUND);
}
}
27、flat嵌套的集合
// Iterable<? extends Iterable<? extends T>>
Map<String, Set<String>> maps = mock();
Iterable<String> values = Iterables.concat(maps.values());
28、时间截取
Date date = new Date();
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
dateFormat.format(date);// 2016-11-30 09:45:49
dateFormat.format(DateUtils.truncate(date, Calendar.DATE)); // 2016-11-30 00:00:00
dateFormat.format(DateUtils.truncate(date, Calendar.HOUR_OF_DAY)); // 2016-11-30 09:00:00
dateFormat.format(DateUtils.truncate(date, Calendar.MINUTE)); // 2016-11-30 09:45:00
dateFormat.format(DateUtils.truncate(date, Calendar.SECOND)); // 2016-11-30 09:45:49
dateFormat.format(DateUtils.truncate(date, Calendar.DAY_OF_MONTH)); //2016-11-30 00:00:00
dateFormat.format(DateUtils.truncate(date, Calendar.MONTH)); // 2016-11-01 00:00:00
29、List切分partition
// 1 Lists.partition
List<Integer> intList = Lists.newArrayList(1, 2, 3, 4, 5, 6, 7, 8);
List<List<Integer>> subSets = Lists.partition(intList, 3);
// 2 Iterables.partition
Collection<Integer> intCollection = Lists.newArrayList(1, 2, 3, 4, 5, 6, 7, 8);
Iterable<List<Integer>> subSets = Iterables.partition(intCollection, 3);
// 3 java8 groupingBy
List<Integer> intList = Lists.newArrayList(1, 2, 3, 4, 5, 6, 7, 8);
Map<Boolean, List<Integer>> groups = intList.stream().collect(Collectors.partitioningBy(s -> s > 6));
Map<Integer, List<Integer>> groups = intList.stream().collect(Collectors.groupingBy(s -> (s - 1) / 3));
List<List<Integer>> subSets = new ArrayList<List<Integer>>(groups.values());
30、两个List比较Deletions、Additions
List<T> oldList = ...
List<T> newList= ...
List<T> removed = new ArrayList<T>(oldList);
removed.removeAll(newList);
List<T> same = new ArrayList<T>(oldList);
same.retainAll(newList);
List<T> added = new ArrayList<T>(newList);
added.removeAll(oldList);
31、安全转换范型
List<? extends Foo> list1 = ...
List<Foo> list2 = Collections.unmodifiableList(list1);
@SupressWarnings("unchecked")
List<Foo> list2 = (List<Foo>)(List<?>)list1;
List<? super Foo> list3 = list2;
32、Get-and-Put principle( Producer Extends, Consumer Super)
class CopyClass {
<T> void copy(List<? extends T> from, List<? super T> to) {
for(T item : from) to.add(item);
}
}
33、JSON解析(fastjson)
// 解析map
final static Type type = new TypeReference<Map<String, Long>>() {}.getType();
Map<String, Long> timeMap = JSON.parseObject(configInfo, type);
// 解析List
final static Type type = new TypeReference<List<CategoryBean>>() {}.getType();
List<CategoryBean> categoryList = JSON.parseObject(categoryListJSON, type);
// 或者
List<CategoryBean> categoryList = JSON.parseArray(categoryListJSON, CategoryBean.class);
// 解析自定义对象
Dict dict = JSON.parseObject(value, Dict.class);
// 解析成JSONObject
JSONObject config = JSON.parseObject(configJsonString);
String username = config.getString("username");
// 关闭循环引用检测
JSON.toJSONString(obj, SerializerFeature.DisableCircularReferenceDetect)
Dict dict = JSON.parseObject("...", Dict.class, Feature.DisableCircularReferenceDetect);
// JSONObject遍历
jObject = new JSONObject(contents.trim());
Iterator<?> keys = jObject.keys();
while( keys.hasNext() ) {
String key = (String)keys.next();
if ( jObject.get(key) instanceof JSONObject ) {
}
}
// 超大JSON处理
https://github.com/alibaba/fastjson/wiki/Stream-api
// 格式化JSON输出
String text = JSON.toJSONString(dict, SerializerFeature.PrettyFormat);
// 将非字符串类型输出为字符串类型,如将Integr输出为String
String text = JSON.toJSONString(dict, SerializerFeature.WriteNonStringValueAsString)
// 写入OutputStream或者Writer
JSON.writeJSONString(os, dict);
JSON.writeJSONString(writer, dict);
// BeanToArray 特性
class Company {
public int code;
@JSONField(serialzeFeatures=SerializerFeature.BeanToArray, parseFeatures=Feature.SupportArrayToBean)
public List<Department> departments = new ArrayList<Department>();
}
34、Java Bean 之间转换
MapStruct MapStruct : Transferring data from one bean to another
// maven引入
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.2.0.Final</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.2.0.Final</version>
</dependency>
@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE)
@DecoratedWith(SampleMapperDecorator.class)
public interface SampleMapper {
SampleMapper INSTANCE = Mappers.getMapper(SampleMapper.class);
@Mappings({
@Mapping(source = "riskTagCode", target = "riskCode"),
@Mapping(expression = "java(getParam.getObjectType().getCode())", target = "objectType"),
@Mapping(source = "sampleId", target = "id")
})
SampleBean paramToBean(SampleGetParam getParam);
}
public abstract class SampleMapperDecorator implements SampleMapper {
private final SampleMapper delegate;
public SampleMapperDecorator(SampleMapper delegate) {
this.delegate = delegate;
}
@Override
public SampleBean paramToBean(SampleGetParam getParam) {
SampleBean SampleBean = delegate.paramToBean(getParam);
Date endTime = Optional.ofNullable(getParam.getEndTime()).orElse(new Date());
Date startTime = Optional.ofNullable(getParam.getStartTime()).orElse(new DateTime(endTime).minusDays(7).toDate());
SampleBean.setEndTime(endTime);
SampleBean.setStartTime(startTime);
return SampleBean;
}
}
35、创建空数组
Long[] children = ArrayUtils.EMPTY_LONG_OBJECT_ARRAY;
Long[] children = {};
Long[] children = ArrayUtils.toArray();
36、Shuffle Array
void shuffleArray(String[] nodes) {
Random rnd = new Random()
for (int i = nodes.length; i > 1; i--) {
int randomIndex = rnd.nextInt(i);
String tmp = nodes[randomIndex];
nodes[randomIndex] = nodes[i - 1];
nodes[i - 1] = tmp;
}
}
Collections.shuffle(Lists.newArrayList(1,2,3));
37、流之间复制
/**
* Copies the specified length of bytes from in to out.
*
* @param in InputStream to read from
* @param out OutputStream to write to
* @param length number of bytes to copy
* @param bufferSize the size of the buffer
* @param close whether to close the streams
* @throws IOException if bytes can not be read or written
*/
public static void copyBytes(InputStream in, OutputStream out, final long length, final int bufferSize, final boolean close) throws IOException {
final byte buf[] = new byte[bufferSize];
try {
int n = 0;
for(long remaining = length; remaining > 0 && n != -1; remaining -= n) {
final int toRead = remaining < buf.length ? (int)remaining : buf.length;
n = in.read(buf, 0, toRead);
if (n > 0) {
out.write(buf, 0, n);
}
}
if (close) {
out.close();
out = null;
in.close();
in = null;
}
} finally {
if (close) {
closeStream(out);
closeStream(in);
}
}
}
private static void closeStream(java.io.Closeable... closeables) {
for(java.io.Closeable c : closeables) {
if (c != null) {
try {
c.close();
} catch(IOException e) {
log.debug("Exception in closing " + c, e);
}
}
}
}
38、byte数组和Long数组转换
public static long[] toLongArray(byte[] bArray) {
ByteBuffer byteBuffer = ByteBuffer.wrap(bArray);
LongBuffer longBuffer = byteBuffer.asLongBuffer();
long l[] = new long[longBuffer.capacity()];
longBuffer.get(l);
return l;
}
public static byte[] toByteArray(long[] data) {
ByteBuffer byteBuffer = ByteBuffer.allocate(data.length * 8);
LongBuffer longBuffer = byteBuffer.asLongBuffer();
longBuffer.put(data);
return byteBuffer.array();
}
39、取绝对值
/**
* @param x
* @return the absolute value of x
* @throws ArithmeticException when a negative value would have been returned by {@link Math#abs(int)}
*/
public static int abs(int x) throws ArithmeticException {
if (x == Integer.MIN_VALUE) {
throw new ArithmeticException("Math.abs(Integer.MIN_VALUE)");
}
return Math.abs(x);
}
40、字节数组与16进制字符串转换
// 00A0BF <=> byte[] {0x00,0xA0,0xBf}
/**
* byte array to Hex String
* @param ba
* @return string with HEX value of the key
*/
public static String toHex(byte[] ba) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(baos);
for(byte b: ba) {
ps.printf("%x", b);
}
return baos.toString();
}
public static byte[] hexToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i+1), 16));
}
return data;
}
import javax.xml.bind.DatatypeConverter;
public static String toHexString(byte[] array) {
return DatatypeConverter.printHexBinary(array);
}
public static byte[] toByteArray(String s) {
return DatatypeConverter.parseHexBinary(s);
}
import com.google.common.io.BaseEncoding;
BaseEncoding.base16().decode(string);
BaseEncoding.base16().encode(bytes);
41、最接近的二次幂
/**
* Return the exponent of the power of two closest to the given
* positive value, or zero if value leq 0.
*/
private static int getClosestPowerOf2(int value) {
if (value <= 0)
throw new IllegalArgumentException("Undefined for " + value);
final int hob = Integer.highestOneBit(value);
return Integer.numberOfTrailingZeros(hob) + (((hob >>> 1) & value) == 0 ? 0 : 1);
}
// 13: hob = 8 numberOfTrailingZeros = 3 4 & 13 = 4
// 9: hob = 8 numberOfTrailingZeros = 3 4 & 9 = 0
42、创建泛型数组
// Checked: strong typing. GenSet knows explicitly what type of objects it contains
// methods will throw an exception when they are passed arguments that are not of type E.
// See Collections.checkedCollection.
public class GenSet<E> {
private E[] a;
public GenSet(Class<E> c, int s) {
// Use Array native method to create array of a type only known at run time
@SuppressWarnings("unchecked")
final E[] a = (E[]) Array.newInstance(c, s);
this.a = a;
}
E get(int i) {
return a[i];
}
}
// Unchecked: weak typing. No type checking is actually done on any of the objects passed as argument
public class GenSet<E> {
private Object[] a;
public GenSet(int s) {
a = new Object[s];
}
E get(int i) {
@SuppressWarnings("unchecked")
final E e = (E) a[i];
return e;
}
}
43、避免ConcurrentModificationException
Collection<Integer> coll = new ArrayList<Integer>();
//populate
coll.removeIf(i -> i.intValue() == 5);
44、对map的value排序
public static <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map) {
List<Map.Entry<K, V>> list = new LinkedList<Map.Entry<K, V>>(map.entrySet());
Collections.sort(list, new Comparator<Map.Entry<K, V>>() {
public int compare( Map.Entry<K, V> o1, Map.Entry<K, V> o2 ) {
return (o1.getValue()).compareTo( o2.getValue() );
}
});
Map<K, V> result = new LinkedHashMap<K, V>();
for (Map.Entry<K, V> entry : list) {
result.put( entry.getKey(), entry.getValue() );
}
return result;
}
public static <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map) {
return map.entrySet()
.stream()
.sorted(Map.Entry.comparingByValue(/*Collections.reverseOrder()*/))
.collect(
Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new )
);
}
45、格式化double类型
DecimalFormat df = new DecimalFormat("#.#####");
df.setRoundingMode(RoundingMode.CEILING);
df.format(234.212431324); // 234.2125
BigDecimal bd = new BigDecimal(d).setScale(4, RoundingMode.HALF_EVEN);
d = bd.doubleValue(234.212431324); // 234.2125
46、clone对象
@Override
public CategoryBean clone() {
CategoryBean clone = null;
try {
clone = (CategoryBean) super.clone();
} catch (CloneNotSupportedException ex) {
throw new RuntimeException(ex);
}
return clone;
}
// 深度克隆
public static CategoryBean deepClone(CategoryBean src) {
CategoryBean dst = null;
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream oo = new ObjectOutputStream(out);
oo.writeObject(src);
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
ObjectInputStream oi = new ObjectInputStream(in);
dst = oi.readObject();
} catch (IOException e) {
throw new RuntimeException(e);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
return dst;
}
47、Enum高级用法
import org.joda.time.*;
import java.util.function.BiFunction;
import java.util.function.Function;
public enum TimePeriod {
MINUTE((from, to) -> Minutes.minutesBetween(from, to).getMinutes() + 1,
from -> from.withZone(DateTimeZone.UTC)
.withSecondOfMinute(0)
.withMillisOfSecond(0)),
HOUR((from, to) -> Hours.hoursBetween(from, to).getHours() + 1,
from -> from.withZone(DateTimeZone.UTC)
.withMinuteOfHour(0)
.withSecondOfMinute(0)
.withMillisOfSecond(0)),
DAY((from, to) -> Days.daysBetween(from, to).getDays() + 1,
from -> from.withZone(DateTimeZone.UTC)
.withTimeAtStartOfDay());
private BiFunction<DateTime, DateTime, Integer> getTimeIntervalFunc;
private Function<DateTime, DateTime> getStartTimeFunc;
private TimePeriod(BiFunction<DateTime, DateTime, Integer> getTimeIntervalFunc,
Function<DateTime, DateTime> getStartTimeFunc) {
this.getTimeIntervalFunc = getTimeIntervalFunc;
this.getStartTimeFunc = getStartTimeFunc;
}
public int getTimeInterval(DateTime from, DateTime to) {
return getTimeIntervalFunc.apply(from, to);
}
public DateTime getStartTime(DateTime from) {
return getStartTimeFunc.apply(from);
}
}
// 另一个例子
public enum Operation {
PLUS("+") {
@Override
public int apply(int x, int y) {
return x + y;
}
},
MINUS("-") {
@Override
public int apply(int x, int y) {
return x - y;
}
};
public abstract int apply(int x, int y);
public String operator() {
return op;
}
private Operation(String op) {
this.op = op;
}
private String op;
}
48、ExpectedException异常测试
class ExceptionsThrower {
void throwRuntimeException(int i) {
if (i <= 0) {
throw new RuntimeException("Illegal argument: i must be <= 0");
}
throw new RuntimeException("Runtime exception occurred");
}
}
public class ExpectedExceptionsTest {
@Rule
public ExpectedException thrown = ExpectedException.none();
@Test
public void verifiesMessageStartsWith() {
thrown.expect(RuntimeException.class);
thrown.expectMessage(startsWith("Illegal argument:"));
exceptionsThrower.throwRuntimeException(-1);
}
}
49、AOP实现方法耗时统计
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.util.StopWatch;
import org.springframework.util.StopWatch.TaskInfo;
public class TimeConsumeProfiler {
public Object timeProfile(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
StopWatch stopWatch = new StopWatch();
stopWatch.start(proceedingJoinPoint.toShortString());
boolean isExceptionThrown = false;
try {
// execute the profiled method
return proceedingJoinPoint.proceed();
} catch (RuntimeException e) {
isExceptionThrown = true;
throw e;
} finally {
stopWatch.stop();
TaskInfo taskInfo = stopWatch.getLastTaskInfo();
String profileMessage = taskInfo.getTaskName() + ": " + taskInfo.getTimeMillis() + " ms" +
(isExceptionThrown ? " (thrown Exception)" : "");
System.out.println(profileMessage);
}
}
}
// spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
">
<context:component-scan base-package="com.aaa.bbb.profiler"/>
<context:annotation-config/>
<bean id="timeConsumeProfiler" class="com.aaa.bbb.profiler.core.TimeConsumeProfiler"/>
<aop:config>
<aop:aspect ref="timeConsumeProfiler">
<!-- 定义在service包里的任意方法的执行 -->
<aop:pointcut id="serviceMethod"
expression="execution(* com.aaa.bbb.profiler.service.*.*(..))"/>
<aop:around pointcut-ref="serviceMethod" method="timeProfile"/>
</aop:aspect>
</aop:config>
</beans>
50、lambda异常包装
org.jooq.lambda.Unchecked
Arrays.stream(dir.listFiles()).forEach(
Unchecked.consumer(file -> { System.out.println(file.getCanonicalPath()); })
);
Arrays.stream(dir.listFiles())
.map(Unchecked.function(File::getCanonicalPath))
.forEach(System.out::println);
51、回调模式
public interface Callback {
void call();
}
public abstract class Task {
/**
* Execute with callback
*/
public final void executeWith(Callback callback) {
execute();
if (callback != null) {
callback.call();
}
}
public abstract void execute();
}
public class SimpleTask extends Task {
@Override
public void execute() {
LOGGER.info("Perform some important activity and then call the callback method.");
}
}
public static void main(String[] args) {
Task task = new SimpleTask();
Callback c = () -> LOGGER.info("I'm done now.");
task.executeWith(c);
}
52、数组比较
int[] arr1 = new int[20]; // Initialized to 0
int[] arr2 = new int[20]; // Initialized to 0
System.out.println(Arrays.equals(arr1, arr2)); // Prints true
System.out.println(arr1 == arr2); // Prints false
53、检测Integer溢出overflow、截取
// 使用Java8 Math类提供的addExact或者multiplyExact等方法,这些方法要么返回正确结果,要么抛出ArithmeticException
public static int multAccum(int oldAcc, int newVal, int scale) {
return Math.addExact(oldAcc, Math.multiplyExact(newVal, scale));
}
// Check whether i is within byte range
if ((i < Byte.MIN_VALUE) || (i > Byte.MAX_VALUE)) {
throw new ArithmeticException("Value is out of range");
}
byte b = (byte) i;
// int向float转换避免进度损失,float有23位的尾数
int num1 = 1234567890;
float num2 = 1234567890;
int result = num1 - (int)num2; // -46
// 扩大类型
double num2 = 1234567890;
int result = num1 - (int)num2; // 0
// 检查范围
if ((num2 > 0x007fffff) || (num2 < -0x800000)) {
throw new ArithmeticException("Insufficient precision");
}
54、整数转为浮点数
short a = 533;
int b = 6789;
long c = 4664382371590123456L;
float d = a / 7; // d is 76.0 (truncated)
double e = b / 30; // e is 226.0 (truncated)
double f = c * 2; // f is -9.1179793305293046E18
float d = a / 7.0f; // d is 76.14286
double e = b / 30.; // e is 226.3
double f = (double)c * 2; // f is 9.328764743180247E18
d /= 7; // d is 76.14286
e /= 30; // e is 226.3
f *= 2; // f is 9.328764743180247E18
double value = Math.ceil(a/((double) b));
55、集合元素类型和方法参数类型保持一致
HashSet<Short> s = new HashSet<Short>();
for (int i = 0; i < 10; i++) {
s.add((short)i);
// Remove a Short
if (s.remove((short)i) == false) {
System.err.println("Error removing " + i);
}
}
56、取余操作
5 % 3 = 2
5 % (-3) = 2
(-5) % 3 = -2
(-5) % (-3) = -2
private int imod(int i, int j) {
int temp = i % j;
return (temp < 0) ? -temp : temp;
}
public int lookup(int hashKey) {
return hash[imod(hashKey, SIZE)];
}
57、ExecutorCompletionService使用
ExecutorCompletionService
内部维护列一个队列BlockingQueue,用于管理已完成的任务;内部还维护列一个Executor, 可以执行任务。任务一旦完成就加入到BlockingQueue中, 如果队列中的数据为空时, 调用take()就会阻塞 (等待任务完成)。
ExecutorCompletionService<String> completionService = new ExecutorCompletionService<String>(Executors.newFixedThreadPool(10));
for(int i=0; i<50; i++) {
completionService.submit(new Callable<String>() {
@Override
public String call() throws Exception {
return Thread.currentThread().getName();
}
});
}
int completionTask = 0;
while(completionTask < 50) {
//如果完成队列中没有数据, 则阻塞; 否则返回队列中的数据
Future<String> resultHolder = completionService.take();
System.out.println("result: " + resultHolder.get());
completionTask++;
}
58、耗时统计
public class TraceWatch implements AutoCloseable {
/** Start time of the current task. */
private long startMs;
/** Name of the current task. */
@Nullable
private String currentTaskName;
@Getter
private final Map<String, List<TaskInfo>> taskMap = new HashMap<>();
public TraceWatch start(String taskName) throws IllegalStateException {
if (this.currentTaskName != null) {
throw new IllegalStateException("Can't start TraceWatch: it's already running");
}
this.currentTaskName = taskName;
this.startMs = TimeUtils.nowMs();
return this;
}
public void stop() throws IllegalStateException {
if (this.currentTaskName == null) {
throw new IllegalStateException("Can't stop TraceWatch: it's not running");
}
long lastTime = TimeUtils.nowMs() - this.startMs;
TaskInfo info = new TaskInfo(this.currentTaskName, lastTime);
this.taskMap.computeIfAbsent(this.currentTaskName, e -> new LinkedList<>()).add(info);
this.currentTaskName = null;
}
@Override
public void close() {
this.stop();
}
public void record(String taskName, Object data) {
TaskInfo info = new TaskInfo(taskName, data);
this.taskMap.computeIfAbsent(taskName, e -> new LinkedList<>()).add(info);
}
@Getter
@AllArgsConstructor
public static final class TaskInfo {
private final String taskName;
private final Object data;
}
}
TraceWatch traceWatch = new TraceWatch();
try(TraceWatch ignored = traceWatch.start("function1")) {
try {
TimeUnit.SECONDS.sleep(1); // 模拟业务代码
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public class TraceHolder {
public static <T> T run(TraceWatch traceWatch, String taskName, Supplier<T> supplier) {
try {
traceWatch.start(taskName);
return supplier.get();
} finally {
traceWatch.stop();
}
}
public static void run(TraceWatch traceWatch, String taskName, IntConsumer function) {
try {
traceWatch.start(taskName);
function.accept(0);
} finally {
traceWatch.stop();
}
}
}
TraceWatch traceWatch = new TraceWatch();
TraceHolder.run(traceWatch, "function1", i -> {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
String result = TraceHolder.run(traceWatch, "function2", () -> {
try {
TimeUnit.SECONDS.sleep(1);
return "YES";
} catch (InterruptedException e) {
e.printStackTrace();
return "NO";
}
});