您的位置:首页 > 其它

[Guava源码阅读笔记]-Basic Utilities篇-1

2015-06-06 20:38 323 查看
欢迎访问:个人博客

写该系列文章的目的是记录Guava源码中个人感觉不错且值得借鉴的内容。

一、MoreObjects类

//MoreObjects.ToStringHelper类的toString()方法:对于字符串拼接的写法蛮不错的,此前本人一直用比较挫的方式:不管三七二一,先拼接然后再subString()
@Override public String toString() {
// create a copy to keep it consistent in case value changes
boolean omitNullValuesSnapshot = omitNullValues;
String nextSeparator = "";
StringBuilder builder = new StringBuilder(32).append(className)
.append('{');
for (ValueHolder valueHolder = holderHead.next; valueHolder != null;
valueHolder = valueHolder.next) {
if (!omitNullValuesSnapshot || valueHolder.value != null) {
builder.append(nextSeparator);
nextSeparator = ", ";

if (valueHolder.name != null) {
builder.append(valueHolder.name).append('=');
}
builder.append(valueHolder.value);
}
}
return builder.append('}').toString();
}

private ValueHolder addHolder() {
ValueHolder valueHolder = new ValueHolder();
holderTail = holderTail.next = valueHolder;
return valueHolder;
}

private ToStringHelper addHolder(@Nullable Object value) {
ValueHolder valueHolder = addHolder();
valueHolder.value = value;
return this;
}

private ToStringHelper addHolder(String name, @Nullable Object value) {
ValueHolder valueHolder = addHolder();
valueHolder.value = value;
valueHolder.name = checkNotNull(name);
return this;
}

private static final class ValueHolder {
String name;
Object value;
ValueHolder next;
}


二、Preconditions类

从整体上讲,在使用带有提示消息的相关check方法时需要考虑到性能问题,在一些性能敏感产品中可能。

/*
* All recent hotspots (as of 2009) *really* like to have the natural code
*
* if (guardExpression) {
*    throw new BadException(messageExpression);
* }
*
* refactored so that messageExpression is moved to a separate String-returning method.
*
* if (guardExpression) {
*    throw new BadException(badMsg(...)); //意思好像是说这种写法比较影响性能
* }
*
* The alternative natural refactorings into void or Exception-returning methods are much slower.
* This is a big deal - we're talking factors of 2-8 in microbenchmarks, not just 10-20%.  (This
* is a hotspot optimizer bug, which should be fixed, but that's a separate, big project).
*
* The coding pattern above is heavily used in java.util, e.g. in ArrayList.  There is a
* RangeCheckMicroBenchmark in the JDK that was used to test this.
*
* But the methods in this class want to throw different exceptions, depending on the args, so it
* appears that this pattern is not directly applicable.  But we can use the ridiculous, devious
* trick of throwing an exception in the middle of the construction of another exception.  Hotspot
* is fine with that.
*/

/**
* Ensures that {@code index} specifies a valid <i>element</i> in an array, list or string of size
* {@code size}. An element index may range from zero, inclusive, to {@code size}, exclusive.
*
* @param index a user-supplied index identifying an element of an array, list or string
* @param size the size of that array, list or string
* @return the value of {@code index}
* @throws IndexOutOfBoundsException if {@code index} is negative or is not less than {@code size}
* @throws IllegalArgumentException if {@code size} is negative
*/
public static int checkElementIndex(int index, int size) {
return checkElementIndex(index, size, "index");
}
// 但作者在下面的方法中为了实现抛出不同类型的异常时,还是使用了上述所描述的不太OK方式,原因我没太明白。
/**
* Ensures that {@code index} specifies a valid <i>element</i> in an array, list or string of size
* {@code size}. An element index may range from zero, inclusive, to {@code size}, exclusive.
*
* @param index a user-supplied index identifying an element of an array, list or string
* @param size the size of that array, list or string
* @param desc the text to use to describe this index in an error message
* @return the value of {@code index}
* @throws IndexOutOfBoundsException if {@code index} is negative or is not less than {@code size}
* @throws IllegalArgumentException if {@code size} is negative
*/
public static int checkElementIndex(
int index, int size, @Nullable String desc) {
// Carefully optimized for execution by hotspot (explanatory comment above)
if (index < 0 || index >= size) {
throw new IndexOutOfBoundsException(badElementIndex(index, size, desc));
}
return index;
}

private static String badElementIndex(int index, int size, String desc) {
if (index < 0) {
return format("%s (%s) must not be negative", desc, index);
} else if (size < 0) {
throw new IllegalArgumentException("negative size: " + size);
} else { // index >= size
return format("%s (%s) must be less than size (%s)", desc, index, size);
}
}


当然,还有一个format方法(仍然是字符串处理)

/**
* Substitutes each {@code %s} in {@code template} with an argument. These are matched by
* position: the first {@code %s} gets {@code args[0]}, etc.  If there are more arguments than
* placeholders, the unmatched arguments will be appended to the end of the formatted message in
* square braces.
*
* @param template a non-null string containing 0 or more {@code %s} placeholders.
* @param args the arguments to be substituted into the message template. Arguments are converted
*     to strings using {@link String#valueOf(Object)}. Arguments can be null.
*/
// Note that this is somewhat-improperly used from Verify.java as well.
static String format(String template, @Nullable Object... args) {
template = String.valueOf(template); // null -> "null"

// start substituting the arguments into the '%s' placeholders
StringBuilder builder = new StringBuilder(template.length() + 16 * args.length);
int templateStart = 0;
int i = 0;
while (i < args.length) {
int placeholderStart = template.indexOf("%s", templateStart);
if (placeholderStart == -1) {
break;
}
builder.append(template.substring(templateStart, placeholderStart));
builder.append(args[i++]);
templateStart = placeholderStart + 2;
}
builder.append(template.substring(templateStart));

// if we run out of placeholders, append the extra args in square braces
if (i < args.length) {
builder.append(" [");
builder.append(args[i++]);
while (i < args.length) {
builder.append(", ");
builder.append(args[i++]);
}
builder.append(']');
}

return builder.toString();
}


三、Optional及其实现类

// Optional及其两个实现类Absent,Present,这三个类用简洁的方式解决了Java中null值的不确定性问题(其设计哲学值得学习)
// public abstract class Optional<T> implements Serializable
// final class Absent<T> extends Optional<T>
// final class Present<T> extends Optional<T>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: