static boolean equals(Annotation a1, Annotation a2) // Annotation.equals(Object)의 문서대로 처리해준다
static int hashCode(Annotation a) // Annotation.hashCode()의 문서대로 처리해준다
static String toString(Annotation a) // Annotation.toString()의 문서대로 처리해준다
ArchUtils
"os.arch" 시스템 프로퍼티에 관한 유틸리티를 제공한다
↓ java
static Processor getProcessor()
ArrayUtils
스레드-안전. null에 관대한 배열 유틸리티를 제공한다
↓ java
static <T> boolean isArrayIndexValid(T[] array, int index)
static String toString(Object array, String stringIfNull) // + toStringArray
static Map<Object, Object> toMap(Object[] array)
// 각 원소는 Map.Entry거나 배열이여야 하며, 배열인 경우 원소가 2개 이상 있어야 한다(1번째는 키, 2번째는 값)
static <T> T[] toArray(T... items)
static <T> T[] clone(T[] array) // 얕은 복사 수행
static <T> T[] nullToEmpty(T[] array, Class<T[]> type)
// 방어적 프로그래밍 기법 : array가 null이면 같은 타입의 빈 배열을 반환한다. null이 아니면 그대로 반환
static <T> T[] subarray(T[] array, int startIndexInclusive, int endIndexExclusive)
static boolean isSameLength(Object[] array1, Object[] array2) // null은 카운트 제외
static boolean isSameType(Object array1, Object array2) // 배열이 같은 타입인지 반환한다. 다차원 배열 타입도 처리된다
static void shuffle(Object[] array)
static void reverse(Object[] array, int startIndexInclusive, int endIndexExclusive)
static void swap(Object[] array, int offset1, int offset2, int len)
// array가 null이거나, 인덱스가 오버플로된 경우 작업을 하지 않는다. 음수 인덱스는 0으로 간주한다
static void shift(Object[] array, int startIndexInclusive, int endIndexExclusive, int offset)
static int indexOf(Object[] array, Object objectToFind, int startIndex)
// null에 대하여 INDEX_NOT_FOUND(-1)를 반환한다
// + lastIndexOf, contains
static <T> T[] addAll(T[] array1, T... array2)
// + add, remove, removeElement, removeAll, removeElements, removeAllOccurences, insert
static <T> boolean isSorted(T[] array, Comparator<T> comparator)
BitField
클래스 인스턴스 내부에 비트값들을 저장하지 않고, 외부 int, short, byte에 대한 마스킹 연산을 지원한다
↓ java
int getValue(int holder) // 마스크 비트에 해당하는 비트들을 우측으로 시프트하여 값 반환
int getRawValue(int holder) // 마스크 비트에 해당하는 비트들의 위치 그대로 값 반환
int set(int holder) // + clear
int setValue(int holder, int value) // 마스크 비트에 value를 설정한 후의 값을 반환
boolean isSet(int holder) // 마스크 비트에 해당하는 비트들 중 하나라도 설정되었다면 true
static <T extends Serializable> T clone(T object) // 직렬화를 이용한 deep clone
static <T extends Serializable> T roundtrip(T msg) // 직렬화 후 역직렬화하여 반환
static byte[] serialize(Serializable obj)
static <T> T deserialize(byte[] objectData)
StringUtils
스레드-안전. null 안전한 String 유틸리티 제공
↓ java
static String normalizeSpace(String str)
static String repeat(String str, String separator, int repeat)
static String rightPad(String str, int size) // + leftPad
static boolean isEmpty(CharSequence cs)
// + isNotEmpty, isAnyEmpty, isNoneEmpty, isAllEmpty, isBlank(isEmpty 포함), isNotBlank, isAnyBlank, isNoneBlank, isAllBlank
static String trim(String str) // heading, trailing 제어 문자(ASCII <= 32) 제거
// + trimToNull(결과가 isBlank면 null), trimToEmpty, strip(공백 문자; Character#isWhitespace 또는 사용자 지정 문자 제거), stripToNull, stripToEmpty, stripStart, stripEnd, stripAll, stripAccents
static String truncate(String str, int maxWidth)
static int compare(String str1, String str2, boolean nullIsLess)
static boolean contains(CharSequence seq, CharSequence searchSeq)
// + containsAny, containsOnly(검색 대상 문자들로만 구성됐는지 여부), containsNone, startWithAny, endsWithAny
static int indexOf(CharSequence seq, CharSequence searchSeq, int startPos)
// + lastIndexOf, indexOfAny, indexOfAnyBut(검색 대상 문자에 해당하지 않는 최초의 인덱스)
static int ordinalIndexOf(CharSequence str, CharSequence searchStr, int ordinal)
// ordinal번째로 검색된 위치를 반환. + lastOrdinalIndexOf
static String left(String str, int len) // + right, mid, center, abbreviate
static String substringBefore(String str, String separator)
// + substringAfter, substringBeforeLast, substringAfterLast, substringBetween, substringsBetween
static String[] splitByWholeSeparator(String str, String separator, int max)
// + splitPreserveAllTokens, splitByWholeSeparatorPreserveAllTokens, splitByCharacterType
static <T> String join(T... elements) // + joinWith
static String deleteWhitespace(String str)
// + removeStart, removeEnd, remove, replaceOnce, replaceEach, replaceEachRepeatedly(문자열이 containsNone을 만족할 때까지 반복), replaceChars
static String overlay(String str, String overlay, int start, int end)
// str의 부분 문자열[start, end)을 overlay로 교체한다. start > end인 경우 스왑된다
static String rotate(String str, int shift)
// + reverse, reverseDelimited
static String getCommonPrefix(String... strs)
static String appendIfMissing(String str, CharSequence suffix, CharSequence... suffixes) // + prependIfMissing
static String wrap(String str, String wrapWith) // + wrapIfMissing, unwrap
SystemUtils
스레드-안전. java.lang.System에 관한 헬퍼 제공
↓ java
public static final String JAVA_HOME
public static final String JAVA_IO_TMPDIR
public static final String OS_ARCH
public static final String USER_DIR
public static final boolean IS_OS_WINDOWS
// ...
Validate
스레드-안전. 인자 평가에 관한 유틸리티를 제공한다
↓ java
static void isTrue(boolean expression, String format, Object... values)
static <T> T notNull(T object, String format, Object... values)
static <T> T[] notEmpty(T[] array, String format, Object... values)
static <T> T[] noNullElements(T[] array, String format, Object... values)
static <T> T[] validIndex(T[] array, int index, String format, Object... values)
static void matchesPattern(CharSequence input, String pattern)
static <T> void inclusiveBetween(T start, T end, Comparable<T> value) // + exclusiveBetween
static void isInstanceOf(Class<?> type, Object obj)
static void isAssignableFrom(Class<?> superType, Class<?> type)
리소스를 신뢰할 수 없는 상태로 변이되면 당분간 리소스에 대한 모든 요청을 즉시 거부하도록 고안된 개념이지만, 적절하게 알아서 구현하면 된다
회로에서 가져온 개념이므로 close가 가용, open이 불가를 의미한다
↓ java
boolean isOpen()
void close() // + open
boolean checkState()
// 가용 상태를 재확인하여 필요하다면 상태를 변경한다
boolean incrementAndCheckState(T increment)
// checkState()에 인자가 필요한 경우 이용한다
ThresholdCircuitBreaker
스레드-안전. 1회용 CircuitBreaker를 제공한다. 물론 close()로 강제로 천이시킬 수 있다
↓ java
public ThresholdCircuitBreaker(long threshold)
long getThreshold()
EventCountCircuitBreaker
카운트와 인터벌을 가지고 아래와 같은 서비스를 제공할 수 있다. 카운팅은 외부에서 직접해야함에 유의
n개 이상의 실패가 발생하면 상태를 OPEN으로 천이
n분 동안 m개 이상의 실패가 발생하면 l분간 상태를 OPEN으로 천이
분당 요청이 n개 이하로 떨어지면 상태를 CLOSED로 천이
public EventCountCircuitBreaker(int threshold, long checkInterval, TimeUnit checkUnit)
기준 이벤트 카운트/인터벌 모두 공유. 초당 최대 5개의 처리를 하는
public EventCountCircuitBreaker(int openingThreshold, long checkInterval, TimeUnit checkUnit, int closingThreshold)
기준 인터벌을 공유. 초당 5개 이상의 요청이 발생하면 OPEN, 초당 2개 이하로 떨어지면(부정확) CLOSE하는
public EventCountCircuitBreaker(int openingThreshold, long openingInterval, TimeUnit openingUnit, int closingThreshold, long closingInterval, TimeUnit closingUnit)
초당 5번 이상 실패하면 2초간 OPEN하는
Initializer
ConcurrentInitializer<T>
스레드-안전한 초기화 로직을 의미한다
AtomicInitializer<T>
『Effective Java』에서 소개하는Goto - 객체 필드 초기화 지연과 유사한 형태의 로직으로, AtomicReference를 이용해 단 한 번만 객체가 초기화됨을 보장한다
AtomicSafeInitializer<T>
AtomicInitializer + initialize()가 단 한 번만 호출됨이 보장된다
BackgroundInitializer<T>
내부적으로 ExecutorService와 Future를 이용해 백그라운드 초기화 작업을 지원한다. start()로 초기화를 다른 스레드에서 시작시키고, get()을 통해 블로킹할 수 있다
↓ java
boolean start()
// 단 한 번만 실행됨이 보장된다. 최초에만 true, 나머지는 false 반환
boolean isStarted()
// == (future != null)
Future<T> getFuture()
final void setLimit(int limit)
void acquire()
// 순번을 얻기까지 스레드를 블록한다
boolean tryAcquire()
// 순번을 얻을 수 있다면 얻은 뒤 true를 반환하고, 아니면 false를 반환한다. true를 받았다면 즉시 다음으로 진행하면 된다
...event
EventListenerSupport<L>
이벤트 리스터들을 관리하고, 일괄 통지하는 기능을 제공한다
↓ java
static <T> EventListenerSupport<T> create(Class<T> listenerInterface)
L fire()
// 프록시 객체를 반환한다. 프록시 메서드는 등록된 모든 이벤트 리스너에 포워딩된다
void addListener(L listener, boolean allowDuplicate)
// allowDuplicate는 지정되지 않은 경우 true
void removeListener(L listener)
L[] getListeners()
EventUtils
↓ java
static <L> void addEventListener(Object eventSource, Class<L> listenerType, L listener)
// eventSource의 "add" + listenerType.getSimpleName()에 해당하는 메서드로 listener 등록
static <L> void bindEventsToMethod(Object target, String methodName, Object eventSource, Class<L> listenerType, String... eventTypes)
// addEventListener를 호출한다. 등록하는 listener는 target의 methodName 메서드를 호출하는 프록시
// eventTypes는 listenerType 인터페이스 중 어떤 메서드들에 대해 동작할 지를 의미하며, 비어 있는 경우 모든 메서드에 대해 동작한다
...exception
ExceptionUtils
↓ java
static Throwable getRootCause(Throwable throwable)
static <R> R rethrow(Throwable throwable)
// R은 장식. throwable을 즉시 throw한다. 아래와 같이 제네릭을 이용하여 CheckedException을 컴파일러로부터 숨긴다. 메서드 시그니처의 불필요한 throws 절과 예외 체인의 불필요한 "Caused by" 항목을 제거할 수 있다. 자바의 예외 처리 방법에 벗어나는 감이 있지만, 라이브러리 개발에는 유용하다
@SuppressWarnings("unchecked")
private static <R, T extends Throwable> R typeErasure(final Throwable throwable) throws T {
throw (T) throwable;
}
static <R> R wrapAndThrow(Throwable throwable)
// throwable이 RuntimeException, Error의 인스턴스면 각각 해당 타입으로 throw하고, 나머지는 UndeclaredThrowableException로 throw한다. 결과적으로 Error를 제외하면 모두 RuntimeException으로 throw하는 셈
...math
Fraction
int 분자/분모를 이용한다. BigInteger 구현은 Commons Math BigFraction을 이용
NumberUtils
↓ java
static int toInt(String str, int defaultValue)
// null과 빈 문자열은 defaultValue를 반환. 지정되지 않은 경우 0
// + toLong, toFloat, toDouble, toByte, toShort
static BigDecimal toScaledBigDecimal(String value)
// RoundingMode.HALF_EVEN으로 소수점 둘째 자리까지만 남긴다
static Number createNumber(String str)
// 0x, -0x, #, -#로 시작하면 16진수로 간주
// 타입 정보를 명시하지 않은 경우, 정수는 Integer, Long(8자 이상), BigInteger(16자 이상)로 변환, 소수는 Float, Double, BigDecimal로 변환된다
// + createFloat, createDouble, createInteger, ...
...mutable
Mutable<T>
java.lang에서 제공하는 기본 타입의 래퍼들이 변경할 수 없는 것에 반해, 변경할 수 있는 T 타입 래퍼를 제공한다
↓ java
T getValue() // + setValue
class MutableBoolean
class MutableInt
class MutableObject<T>
...reflect
사용할 일 생기면 정리 : TypeUtils, FieldUtils, ConstructorUtils, MethodUtils
...time
DateParser
↓ java
Date parse(String source)
String getPattern()
DatePrinter
↓ java
String format(long millis)
<B extends Appendable> B format(long millis, B buf)
FastDateFormat
SimpleDateFormat의 고속, 스레드-안전한 버전
↓ java
static FastDateFormat getInstance(String pattern)
static FastDateFormat getDateTimeInstance(int dateStyle, int timeStyle, TimeZone timeZone)
// 스타일 : FULL, LONG, MEDIUM, SHORT
DateFormatUtils
↓ java
public static final FastDateFormat ISO_8601_EXTENDED_DATETIME_FORMAT // yyyy-MM-dd'T'HH:mm:ss
public static final FastDateFormat ISO_8601_EXTENDED_DATETIME_TIME_ZONE_FORMAT // yyyy-MM-dd'T'HH:mm:ssZZ
public static final FastDateFormat ISO_8601_EXTENDED_DATE_FORMAT // yyyy-MM-dd
public static final FastDateFormat ISO_8601_EXTENDED_TIME_FORMAT // HH:mm:ss
public static final FastDateFormat ISO_8601_EXTENDED_TIME_TIME_ZONE_FORMAT // HH:mm:ssZZ
public static final FastDateFormat SMTP_DATETIME_FORMAT // EEE, dd MMM yyyy HH:mm:ss Z
DateUtils
↓ java
static boolean isSameDay(Calendar cal1, Calendar cal2)
static boolean isSameInstant(Calendar cal1, Calendar cal2)
static boolean truncatedEquals(Calendar cal1, Calendar cal2, int field)
static boolean truncatedCompareTo(Calendar cal1, Calendar cal2, int field)
static Date addYears(Date date, int amount)
// + addMonths, addWeeks, addDays, addHours, addMinutes, addSeconds, addMilliseconds
static Date setYears(Date date, int amount)
// + setMonths, setDays, setHours, setMinutes, setSeconds, setMilliseconds
static Calendar toCalendar(Date date, TimeZone tz)
static Date round(Calendar date, int field)
// + truncate, ceiling
StopWatch
↓ java
static StopWatch createStarted()
void start()
// + stop, reset, split, unsplit, suspend, resume
// + isStarted, isSuspended, isStopped
long getTime(TimeUnit timeUnit)
long getNanoTime()
long getSplitTime() // + getSplitNanoTime
long getStartTime()
String toString()
...tuple
↓ java
class Pair<L, R>
class ImmutablePair<L, R>
class MutablePair<L, R>
class Triple<L, M, R>
class ImmutableTriple<L, M, R>
class MutableTriple<L, M, R>