public static void waitShutdown() throws InterruptedException {
final CountDownLatch latch = new CountDownLatch(1);
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
latch.countDown();
}
});
latch.await();
}
https://mp.weixin.qq.com/s/K9r9UkrvKlR2ILv1gNiltQ
public AbstractStringBuilder append(String str) {
if (str == null)
return appendNull();
int len = str.length();
ensureCapacityInternal(count + len);
str.getChars(0, len, value, count);
count += len;
return this;
}
private AbstractStringBuilder appendNull() {
int c = count;
ensureCapacityInternal(c + 4);
final char[] value = this.value;
value[c++] = 'n';
value[c++] = 'u';
value[c++] = 'l';
value[c++] = 'l';
count = c;
return this;
}
* For positive values of {@code minimumCapacity}, this method
* behaves like {@code ensureCapacity}, however it is never
* synchronized.
* If {@code minimumCapacity} is non positive due to numeric
* overflow, this method throws {@code OutOfMemoryError}.
*/
private void ensureCapacityInternal(int minimumCapacity) {
// overflow-conscious code
if (minimumCapacity - value.length > 0) {
value = Arrays.copyOf(value,
newCapacity(minimumCapacity));
}
}
private int newCapacity(int minCapacity) {
// overflow-conscious code
int newCapacity = (value.length << 1) + 2;
if (newCapacity - minCapacity < 0) {
newCapacity = minCapacity;
}
return (newCapacity <= 0 || MAX_ARRAY_SIZE - newCapacity < 0)
? hugeCapacity(minCapacity)
: newCapacity;
}
private int hugeCapacity(int minCapacity) {
if (Integer.MAX_VALUE - minCapacity < 0) { // overflow
throw new OutOfMemoryError();
}
return (minCapacity > MAX_ARRAY_SIZE)
? minCapacity : MAX_ARRAY_SIZE;
}
public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
{
if (srcBegin < 0)
throw new StringIndexOutOfBoundsException(srcBegin);
if ((srcEnd < 0) || (srcEnd > count))
throw new StringIndexOutOfBoundsException(srcEnd);
if (srcBegin > srcEnd)
throw new StringIndexOutOfBoundsException("srcBegin > srcEnd");
System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
}
To write code in interview, it's important to familiar with classes and methods in JDK.StringBuilder implements CharSequence
==> Consider use this instead of String
.append(CharSequence)
.charAt(i) ==>
.setCharAt(int, char)
delete(int start, int end) ==> O(end-start)
if (len > 0) {
System.arraycopy(value, start+len, value, start, count-end);
count -= len;
}
.length()
.setLength(0) ==> to clear sb
.indexOf
.lastIndexOf()
.reverse()
.insert(offset,value)
.delete(start,end)
.deleteCharAt(i)
replace(int start, int end, String str)
No toCharArray()
public StringBuilder delete(int start, int end) {
super.delete(start, end);
return this;
}
public AbstractStringBuilder delete(int start, int end) {
if (start < 0)
throw new StringIndexOutOfBoundsException(start);
if (end > count)
end = count;
if (start > end)
throw new StringIndexOutOfBoundsException();
int len = end - start;
if (len > 0) {
System.arraycopy(value, start+len, value, start, count-end);
count -= len;
}
return this;
}
public AbstractStringBuilder deleteCharAt(int index) {
if ((index < 0) || (index >= count))
throw new StringIndexOutOfBoundsException(index);
System.arraycopy(value, index+1, value, index, count-index-1);
count--;
return this;
}
setLength(new length) if new length < old length is O(1) - it only change the length variable.
public void setLength(int newLength) {
if (newLength < 0)
throw new StringIndexOutOfBoundsException(newLength);
ensureCapacityInternal(newLength);
if (count < newLength) {
Arrays.fill(value, count, newLength, '\0');
}
count = newLength;
}
private void ensureCapacityInternal(int minimumCapacity) {
// overflow-conscious code
if (minimumCapacity - value.length > 0)
expandCapacity(minimumCapacity);
}
public static void fill(char[] a, int fromIndex, int toIndex, char val) {
rangeCheck(a.length, fromIndex, toIndex);
for (int i = fromIndex; i < toIndex; i++)
a[i] = val;
}
String
.length()
No reverse method
String[] split(String regex, int limit)
String[] split(String regex)
static String join(CharSequence delimiter, CharSequence... elements) 1.8
static String join(CharSequence delimiter, Iterable<? extends CharSequence> elements)
char[] toCharArray()
static String format(String format, Object... args)
.intern()
Character
.isWhitespace(char)
.isDigit
.isAlphabetic
.isLetter
public static int hashCode(char value) {
return (int)value;
}
Objects
.requireNonNull(T obj, String message)
public static boolean equals(Object a, Object b) { // Null Safe
return (a == b) || (a != null && a.equals(b));
}
Arrays
.sort(array, [start],[end])
.binarySearch(int[] a, int key)
.binarySearch(int[] a, int fromIndex, int toIndex, int key)
.equals(array, array)
.fill(long[] a, long val)
.fill(long[] a, int fromIndex, int toIndex, long val)
.deepEquals(Object[] a1, Object[] a2)
.deepToString(Object[] a) // how it's implemented
.deepHashCode(Object a[])
System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
http://stackoverflow.com/questions/2310498/why-doesnt-strings-hashcode-cache-0
Capturing groups are indexed from left to right, starting at one. Group zero denotes the entire pattern, so the expression m.group(0) is equivalent to m.group().
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value;
for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}
It uses 0 to indicate "I haven't worked out the hashcode yet". The alternative would be to use a separate Boolean flag, which would take more memory. (Or to not cache the hashcode at all, of course.)
I don't expect many strings hash to 0; arguably it would make sense for the hashing routine to deliberately avoid 0 (e.g. translate a hash of 0 to 1, and cache that). That would increase collisions but avoid rehashing. It's too late to do that now though, as the String hashCode algorithm is explicitly documented.
As for whether this is a good idea in general: it's an certainly efficient caching mechanism, andmight (see edit) be even better with a change to avoid rehashing values which end up with a hash of 0. Personally I would be interested to see the data which led Sun to believe this was worth doing in the first place - it's taking up an extra 4 bytes for every string ever created, however often or rarely it's hashed, and the only benefit is for strings which are hashed more than once.
EDIT: As KevinB points out in a comment elsewhere, the "avoid 0" suggestion above may well have a net cost because it helps a very rare case, but requires an extra comparison for every hash calculation.
Pattern r = Pattern.compile(pattern); // Now create matcher object. Matcher m = r.matcher(line); if (m.find( )) { System.out.println("Found value: " + m.group(0) ); System.out.println("Found value: " + m.group(1) ); System.out.println("Found value: " + m.group(2) ); }else { System.out.println("NO MATCH"); }http://blog.600km.xyz/2015/12/14/java-split-exception/
public String[] split(String regex)
public String[] split(String regex, int limit)
regex为指定分隔符,支持正在表达式
limit为切割后的数组长度,默认为0,不会超过实际长度
limit为切割后的数组长度,默认为0,不会超过实际长度
String[] arr2 = str.split(",", 3); //["a", "b", "c,d,e"] length=3
String[] arr3 = str.split(",", 10); //["a","b","c","d","e"] length=5
String[] arr4 = str.split("nan"); //["a,b,c,d,e"] length=1
String[] arr5 = "".split("nan"); //[""] length=1
因为split支持正则参数,可能会需要根据多个分隔符进行分隔,如 id=? and gender=? or age>?,希望根据and和or两个分隔符进行分隔,则可通过正则实现。
public static void main(String[] args) {
String str = "id=? and gender=? or age>?";
String[] arr1 = str.split("and | or"); // ["id=? ","gender=?"," age>?"] length=3
}
注意上述中的空格符, 如果只根据关键字分隔,不能输入空格。“and|or”,可实现分隔效果。
java.util.regex.PatternSyntaxException
同样是由于正则表达式参数,“+” “*”需要使用“\+” “\*”进行转义,否则,会报错java.util.regex.PatternSyntaxException
public static void main(String[] args) {
String str = "a+b+c+d+e";
String[] arr1 = str.split("\\+"); // ["a","b","c","d","e"] length=5
String[] arr2 = str.split("+"); // java.util.regex.PatternSyntaxException: Dangling meta character '+' near index 0
https://stackoverflow.com/questions/19458278/check-if-an-array-is-sorted-return-true-or-false
// Note that we are always comparing an element to its successor.
// Because of this, we can end the loop after comparing
// the second-last element to the last one.
// This means the loop iterator will end as an index of the second-last
// element of the array instead of the last one.
for (int i = 0; i < a.length - 1; i++) {
if (a[i] > a[i + 1]) {
return false; // It is proven that the array is not sorted.
}
}
return true; // If this part has been reached, the array must be sorted.
}