挖掘机技术哪家强

IntegerCache ByteCache CharacterCache LongCache ShortCache

new Integer(1) 与 Integer.valueOf(1) 的区别

使用 Integer.valueOf(1) 可以使用系统缓存,既减少可能的内存占用,也省去了频繁创建对象的开销。

public static Integer valueOf(int i) {
    assert IntegerCache.high >= 127;
 if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
 return new Integer(i);
}

在[IntegerCache.low, IntegerCache.high] 之前的数字都已被缓存。

private static class IntegerCache {
    static final int low = -128;
    static final int high;
    static final Integer cache[];
    static {
        // high value may be configured by property
        int h = 127;
        String integerCacheHighPropValue =
            sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
        if (integerCacheHighPropValue != null) {
            int i = parseInt(integerCacheHighPropValue);
            i = Math.max(i, 127);
            // Maximum array size is Integer.MAX_VALUE
            h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
        }
        high = h;
        cache = new Integer[(high - low) + 1];
        int j = low;
        for(int k = 0; k < cache.length; k++)
            cache[k] = new Integer(j++);
    }
    private IntegerCache() {}
}

默认区间是[-128, 127], 通过 VM 参数-XX:AutoBoxCacheMax=<size> 可以配置缓存的最大值.

Short Long Byte Characte也都类似,范围有所不同

区间
设置上限
Integer [-128,127] -XX:AutoBoxCacheMax=<size>
Short [-128,127] 不可设置
Long [-128,127] 不可设置
Byte [-128,127] 不可设置
Character [0,127] 不可设置

Guava Ordering

一、 用途

内存排序

二、 实例化静态方法

排序类 说明
NaturalOrdering 自然序
UsingToStringOrdering 字典序
AllEqualOrdering 全等
ExplicitOrdering 按照有序的列表排序
ArbitraryOrdering 无序
CompoundOrdering 多级排序

1、通过Comparator创建Ordering

通过传入的Comparator方法来比较排序;

源码:

public static <T> Ordering<T> from(Comparator<T> comparator) {
    return (Ordering)(comparator instanceof Ordering?(Ordering)comparator:new ComparatorOrdering(comparator));
}

示例:

Ordering.from(new Comparator<String>() {
    @Override
    public int compare(String o1, String o2) {
        return o1.compareTo(o2);
    }
})

2、自然序:NaturalOrdering

NaturalOrdering会先检查是否为null,是的话就抛异常,然后通过列表元素自己的compareTo方法比较排序;

源码:

//Ordering.java
public static <C extends Comparable> Ordering<C> natural() {
    return NaturalOrdering.INSTANCE;
}
 
//NaturalOrdering.java
final class NaturalOrdering extends Ordering<Comparable> implements Serializable {
    static final NaturalOrdering INSTANCE = new NaturalOrdering();
    private transient Ordering<Comparable> nullsFirst;
    private transient Ordering<Comparable> nullsLast;
    private static final long serialVersionUID = 0L;

    public int compare(Comparable left, Comparable right) {
        Preconditions.checkNotNull(left);
        Preconditions.checkNotNull(right);
        return left.compareTo(right);
    }
	......
}

示例:

List<String> list = Ordering.natural().nullsFirst().sortedCopy(Lists.<String>newArrayList("1", "afc", "aed"));
System.out.println(list);//输出[1, aed, afc]

3、字典序:UsingToStringOrdering

通过元素的toString转为String然后在比较排序

源码:

public int compare(Object left, Object right) {
    return left.toString().compareTo(right.toString());
}

示例:

List<Integer> list = Ordering.usingToString().sortedCopy(Lists.newArrayList(1, 12, 112, 23));
System.out.println(list);
//输出
[1, 112, 12, 23]

4、全相等:AllEqualOrdering

全相等。(稳定排序中)保持原序,可用来把null置后等

源码:

public int compare(@Nullable Object left, @Nullable Object right) {
    return 0;
}

示例:

List<Integer> list = Ordering.allEqual().nullsLast().sortedCopy(Lists.newArrayList(1, 12, null, 112, 23));
System.out.println(list);
//输出
[1, 12, 112, 23, null]

5、无序:ArbitraryOrdering

暂不清楚用途

源码:

static class ArbitraryOrdering extends Ordering<Object> {
    private final AtomicInteger counter = new AtomicInteger(0);
    private final ConcurrentMap<Object, Integer> uids = Platform.tryWeakKeys(new MapMaker()).makeMap();

    ArbitraryOrdering() {
    }

    private Integer getUid(Object obj) {
        Integer uid = (Integer)this.uids.get(obj);
        if(uid == null) {
            uid = Integer.valueOf(this.counter.getAndIncrement());
            Integer alreadySet = (Integer)this.uids.putIfAbsent(obj, uid);
            if(alreadySet != null) {
                uid = alreadySet;
            }
        }

        return uid;
    }

    public int compare(Object left, Object right) {
        if(left == right) {
            return 0;
        } else if(left == null) {
            return -1;
        } else if(right == null) {
            return 1;
        } else {
            int leftCode = this.identityHashCode(left);
            int rightCode = this.identityHashCode(right);
            if(leftCode != rightCode) {
                return leftCode < rightCode?-1:1;
            } else {
                int result = this.getUid(left).compareTo(this.getUid(right));
                if(result == 0) {
                    throw new AssertionError();
                } else {
                    return result;
                }
            }
        }
    }

    public String toString() {
        return "Ordering.arbitrary()";
    }

    int identityHashCode(Object object) {
        return System.identityHashCode(object);
    }
}

6、有序排无序ExplicitOrdering

按照已有的有序的列表,排序无序的列表

源码:

final class ExplicitOrdering<T> extends Ordering<T> implements Serializable {
    final ImmutableMap<T, Integer> rankMap;
    private static final long serialVersionUID = 0L;

    ExplicitOrdering(List<T> valuesInOrder) {
        this(Maps.indexMap(valuesInOrder));
    }

    ExplicitOrdering(ImmutableMap<T, Integer> rankMap) {
        this.rankMap = rankMap;
    }

    public int compare(T left, T right) {
        return this.rank(left) - this.rank(right);
    }

    private int rank(T value) {
        Integer rank = (Integer)this.rankMap.get(value);
        if(rank == null) {
            throw new IncomparableValueException(value);
        } else {
            return rank.intValue();
        }
    }

    public boolean equals(@Nullable Object object) {
        if(object instanceof ExplicitOrdering) {
            ExplicitOrdering that = (ExplicitOrdering)object;
            return this.rankMap.equals(that.rankMap);
        } else {
            return false;
        }
    }

    public int hashCode() {
        return this.rankMap.hashCode();
    }

    public String toString() {
        return "Ordering.explicit(" + this.rankMap.keySet() + ")";
    }
}

示例

//有序的id
List<Integer> orderedList = Arrays.asList(23, 1, 12, 112);
//无序的model
List<Record> nonOrderedList = Lists.newArrayList(new Record(1), new Record(12), new Record(23), new Record(112));
//排序
List<Record> list = Ordering.explicit(orderedList)
        .onResultOf(new Function<Record, Integer>() {
            @Nullable
            @Override
            public Integer apply(@Nullable Record record) {
                return record.getId();
            }
        }).sortedCopy(nonOrderedList);
System.out.println(list);//输出[[id:23], [id:1], [id:12], [id:112]]

7、多级排序CompoundOrdering

循环所有Comparator,如果相等,继续用下一个Comparator,否则直接返回比较结果

源码:

public int compare(T left, T right) {
    int size = this.comparators.size();

    for(int i = 0; i < size; ++i) {
        int result = ((Comparator)this.comparators.get(i)).compare(left, right);
		//不相等就直接返回,不进行后面的比较
        if(result != 0) {
            return result;
        }
    }

    return 0;
}

示例:

Comparator<Record> comparator1 = new Comparator<Record>() {
    @Override
    public int compare(Record o1, Record o2) {
        return o1.getScore().compareTo(o2.getScore());
    }
};
Comparator<Record> comparator2 = new Comparator<Record>() {
    @Override
    public int compare(Record o1, Record o2) {
        return o1.getDistance().compareTo(o2.getDistance());
    }
};
List<Record> nonOrderedList = Lists.newArrayList(new Record(2, 1.0), new Record(2, 100.0), new Record(1, 130.0), new Record(3, 1.0));
List<Record> list = Ordering.compound(Arrays.asList(comparator1, comparator2)).sortedCopy(nonOrderedList);
System.out.println(list);//输出[Record{id=0, score=1, distance=130.0}, Record{id=0, score=2, distance=1.0}, Record{id=0, score=2, distance=100.0}, Record{id=0, score=3, distance=1.0}]

三、链式调用

reverse()  反转
nullsFirst()  null在前
nullsLast()  null在后
onResultOf(Function) Function返回比较的元素类实例
compound(Comparator)
二级排序
lexicographical()  类“字典序”,对于Iterable一位一位比下去,例如array

可以在一个Ordering实例后面挂多个上述方法。

1、reverse()

反转,实际是在比较的时候将参数位置 a,b换为b,a,并不是排序后在反转

源码:

public int compare(T a, T b) {
    return this.forwardOrder.compare(b, a);
}

示例:

List<Integer> nonOrderedList = Arrays.asList(1,4,2,6,9);
List<Integer> list = Ordering.natural().reverse().sortedCopy(nonOrderedList);
System.out.println(list);
//输出
[9, 6, 4, 2, 1]

2、nullsFirst nullsLast

null在前 或 在后

源码:

public int compare(@Nullable T left, @Nullable T right) {
    return left == right?0:(left == null?-1:(right == null?1:this.ordering.compare(left, right)));
}public int compare(@Nullable T left, @Nullable T right) {
 return left == right?0:(left == null?1:(right == null?-1:this.ordering.compare(left, right)));
}

示例:

List<Integer> nonOrderedList = Arrays.asList(1, 4, 2, 6, 9, null);
List<Integer> list = Ordering.natural().nullsFirst().sortedCopy(nonOrderedList);
System.out.println(list);
 
//输出
[null, 1, 2, 4, 6, 9]

3、onResultOf

返回的是ByFunctionOrdering类,比较元素前先应用OnResultOf传入的Function,之后用返回结果再比较

源码:

final Function<F, ? extends T> function;
final Ordering<T> ordering;
private static final long serialVersionUID = 0L;

ByFunctionOrdering(Function<F, ? extends T> function, Ordering<T> ordering) {
    this.function = (Function)Preconditions.checkNotNull(function);
    this.ordering = (Ordering)Preconditions.checkNotNull(ordering);
}
public int compare(F left, F right) {
    return this.ordering.compare(this.function.apply(left), this.function.apply(right));
}

示例:

List<Record> nonOrderedList = Lists.newArrayList(new Record(2, 1.0), new Record(2, 100.0), new Record(1, 130.0), new Record(3, 1.0));
List<Record> list = Ordering.natural().onResultOf(new Function<Record, Integer>() {
    @Nullable
    @Override
    public Integer apply(@Nullable Record record) {
        return record.getScore();
    }
}).sortedCopy(nonOrderedList);
System.out.println(list);
 
//输出
[Record{id=0, score=1, distance=130.0}, Record{id=0, score=2, distance=1.0}, Record{id=0, score=2, distance=100.0}, Record{id=0, score=3, distance=1.0}]

4、compound

该方法返回的就是CompoundOrdering,不过compound()是在其他Odering的基础上再加一个Comparator

源码:

public <U extends T> Ordering<U> compound(Comparator<? super U> secondaryComparator) {
    return new CompoundOrdering(this, (Comparator)Preconditions.checkNotNull(secondaryComparator));
}
 
 
CompoundOrdering(Comparator<? super T> primary, Comparator<? super T> secondary) {
    this.comparators = ImmutableList.of(primary, secondary);
}

CompoundOrdering(Iterable<? extends Comparator<? super T>> comparators) {
    this.comparators = ImmutableList.copyOf(comparators);
}

示例:

List<Record> nonOrderedList = Lists.newArrayList(new Record(2, 200.0), new Record(2, 100.0), new Record(1, 130.0), new Record(2, 1.0));
Comparator<Record> comparator2 = new Comparator<Record>() {
    @Override
    public int compare(Record o1, Record o2) {
        return o1.getDistance().compareTo(o2.getDistance());
    }
};
List<Record> list = Ordering.natural().compound(comparator2).sortedCopy(nonOrderedList);
System.out.println(list);//Record.compareTo只比较了score//输出[Record{id=0, score=1, distance=130.0}, Record{id=0, score=2, distance=1.0}, Record{id=0, score=2, distance=100.0}, Record{id=0, score=2, distance=200.0}]

四、 其他方法

方法 描述
greatestOf(Iterable iterable, int k) 获取可迭代对象中最大的k个元素。堆排序 不稳定排序
leastOf(Iterator iterable, int k) 获取可迭代对象中最小的k个元素。堆排序 不稳定排序
isOrdered(Iterable) 判断可迭代对象是否已按排序器排序:允许有排序值相等的元素。
sortedCopy(Iterable) 判断可迭代对象是否已严格按排序器排序:不允许排序值相等的元素。
min(E, E) 返回两个参数中最小的那个。如果相等,则返回第一个参数。
min(E, E, E, E…) 返回多个参数中最小的那个。如果有超过一个参数都最小,则返回第一个最小的参数。
min(Iterable) 返回迭代器中最小的元素。如果可迭代对象中没有元素,则抛出NoSuchElementException。
max(E, E)

leastOf

流程:

算法:

维持一个2k大小的buffer;每次满了时,清掉较大的一半,剩下k位。

isOrdered isStrictlyOrdered

public boolean isOrdered(Iterable<? extends T> iterable) {
    Iterator it = iterable.iterator();
    Object next;
    if(it.hasNext()) {
        for(Object prev = it.next(); it.hasNext(); prev = next) {
            next = it.next();
            if(this.compare(prev, next) > 0) {
                return false;
            }
        }
    }

    return true;
}

public boolean isStrictlyOrdered(Iterable<? extends T> iterable) {
    Iterator it = iterable.iterator();
    Object next;
    if(it.hasNext()) {
        for(Object prev = it.next(); it.hasNext(); prev = next) {
            next = it.next();
            if(this.compare(prev, next) >= 0) {
                return false;
            }
        }
    }

    return true;
}