Java编程思想---容器
填充容器
public class StringAddress {
private String string;
public StringAddress(String string) {
this.string = string;
}
@Override
public String toString() {
return "StringAddress{" +
"string='" + string + '\'' +
'}';
}
}
public class FillingLists {
public static void main(String[] args) {
List<StringAddress> list = new ArrayList<>(
Collections.nCopies(4,new StringAddress("World"))
);
System.out.println(list);
System.out.println("________________________________________");
Collections.fill(list,new StringAddress("World"));
System.out.println(list);
}
}
上面展示了两种用对单个对象的引用填充Collection的方式,一种是用Collections.nCopies,第二种是Collections.fill
使用生成器
public class CollectionData<T> extends ArrayList<T> {
public CollectionData(Generator<T> generator,int quantity){
for (int i = 0; i < quantity; i++) {
add(generator.next());
}
}
public static <T> CollectionData<T> list(Generator<T> generator,int quantity){
return new CollectionData<T>(generator,quantity);
}
}
上边使用Generator在容器中放置需要数量的对象,然后所产生的容器可以传递给任何Collection的构造器
Map生成器
public class Pair<K,V> {
public final K key;
public final V value;
public Pair(K key, V value) {
this.key = key;
this.value = value;
}
}
public class MapData<K,V> extends LinkedHashMap<K,V> {
public MapData(Generator<Pair<K,V>> generator,int quantity){
for (int i = 0; i < quantity; i++) {
Pair<K,V> p = generator.next();
put(p.key,p.value);
}
}
public MapData(Generator<K> kGenerator,Generator<V> vGenerator,int quantity){
for (int i = 0; i < quantity; i++) {
put(kGenerator.next(),vGenerator.next());
}
}
public MapData(Generator<K> kGenerator,V v,int quantity){
for (int i = 0; i < quantity; i++) {
put(kGenerator.next(),v);
}
}
// An Iterable and a value Generator:
public MapData(Iterable<K> genK, Generator<V> genV) {
for(K key : genK) {
put(key, genV.next());
}
}
// An Iterable and a single value:
public MapData(Iterable<K> genK, V value) {
for(K key : genK) {
put(key, value);
}
}
// Generic convenience methods:
public static <K,V> MapData<K,V>
map(Generator<Pair<K,V>> gen, int quantity) {
return new MapData<K,V>(gen, quantity);
}
public static <K,V> MapData<K,V>
map(Generator<K> genK, Generator<V> genV, int quantity) {
return new MapData<K,V>(genK, genV, quantity);
}
public static <K,V> MapData<K,V>
map(Generator<K> genK, V value, int quantity) {
return new MapData<K,V>(genK, value, quantity);
}
public static <K,V> MapData<K,V>
map(Iterable<K> genK, Generator<V> genV) {
return new MapData<K,V>(genK, genV);
}
public static <K,V> MapData<K,V>
map(Iterable<K> genK, V value) {
return new MapData<K,V>(genK, value);
}
}
上边的例子有多种选择:
-
单一的Generator<Pair<K,V>>
-
两个分离的Generator
-
一个Generator和一个常量值
-
一个Iterable和一个Generator
-
一个Iterable和一个单一的值
测试下
public class Letter implements Generator<Pair<Integer,String>>,Iterable<Integer> {
private int size = 9;
private int number = 1;
private char letter = 'A';
@Override
public Iterator<Integer> iterator() {
return new Iterator<Integer>() {
@Override
public boolean hasNext() {
return number<size;
}
@Override
public Integer next() {
return number++;
}
};
}
@Override
public Pair<Integer, String> next() {
return new Pair<>(number++,"" + letter++);
}
}
public class MapDataTest {
public static void main(String[] args) {
// Pair Generator
System.out.println(MapData.map(new Letter(),11));
System.out.println("_____________________________________________________");
System.out.println(MapData.map(new Letter(),"OPO"));
}
}
下面这个例子通过继承java.util.AbstractMap来定制Map和Collection
创建只读Map,可以继承AbstractMap并实现entrySet(),创建只读Set,可以继承AbstractSet并实现iterator()以及size()
public class Alphats {
public static final String[][] ALPS = {
{"A","1"},
{"B","2"},
{"C","3"},
{"D","4"},
{"E","5"},
{"F","6"},
{"G","7"},
};
private static class FlyweightMap
extends AbstractMap<String,String> {
private static class Entry
implements Map.Entry<String,String> {
int index;
Entry(int index) { this.index = index; }
public boolean equals(Object o) {
return ALPS[index][0].equals(o);
}public String getKey() { return ALPS[index][0]; }
public String getValue() { return ALPS[index][1]; }
public String setValue(String value) {
throw new UnsupportedOperationException();
}
public int hashCode() {
return ALPS[index][0].hashCode();
}
}
// Use AbstractSet by implementing size() & iterator()
static class EntrySet
extends AbstractSet<Map.Entry<String,String>> {
private int size;
EntrySet(int size) {
if(size < 0)
this.size = 0;
// Can’t be any bigger than the array:
else if(size > ALPS.length)
this.size = ALPS.length;
else
this.size = size;
}
public int size() { return size; }
private class Iter
implements Iterator<Map.Entry<String,String>> {
// Only one Entry object per Iterator:
private Alphats.FlyweightMap.Entry entry = new Alphats.FlyweightMap.Entry(-1);
public boolean hasNext() {
return entry.index < size - 1;
}
public Map.Entry<String,String> next() {
entry.index++;
return entry;
}
public void remove() {
throw new UnsupportedOperationException();
}
}
public
Iterator<Map.Entry<String,String>> iterator() {
return new Alphats.FlyweightMap.EntrySet.Iter();
}
}
private static Set<Map.Entry<String,String>> entries =
new EntrySet(ALPS.length);
public Set<Map.Entry<String,String>> entrySet() {
return entries;
}
}
// Create a partial map of ‘size’ countries:
static Map<String,String> select(final int size) {
return new FlyweightMap() {
public Set<Map.Entry<String,String>> entrySet() {
return new EntrySet(size);
}
};
}
static Map<String,String> map = new FlyweightMap();
public static Map<String,String> alphat_s() {
return map; // The entire map
}
public static Map<String,String> alphat_s(int size) {
return select(size); // A partial map
}
static List<String> names =
new ArrayList<String>(map.keySet());
// All the names:
public static List<String> names() {
return names;
}
// A partial list:
public static List<String> names(int size) {
return new ArrayList<String>(select(size).keySet());
}
public static void main(String[] args) {
System.out.println(alphat_s(10));
System.out.println("_______________________");
System.out.println(names(10));
System.out.println("_______________________");
System.out.println(new HashMap<String,String>(alphat_s(3)));
System.out.println("_______________________");
System.out.println(new LinkedHashMap<String,String>(alphat_s(3)));
}
}
Collection的功能方法
public class CollectionMethods {
public static void main(String[] args) {
Collection<String> collection = new ArrayList<>();
collection.addAll(Alphats.names(3));
collection.add("LKLKL");
collection.add("OPOPOP");
System.out.println(collection);
System.out.println("______________________________________");
Object[] array = collection.toArray();
String[] strings = collection.toArray(new String[0]);
System.out.println("Max ----" + Collections.max(collection));
System.out.println("______________________________________");
System.out.println("Min ----" + Collections.min(collection));
Collection<String> collection_2 = new ArrayList<>();
collection_2.addAll(Alphats.names(3));
collection.addAll(collection_2);
System.out.println("______________________________________");
System.out.println(collection);
System.out.println("______________________________________");
collection.remove(Alphats.ALPS[0][0]);
System.out.println(collection);
System.out.println("______________________________________");
collection.removeAll(collection_2);
System.out.println(collection);
System.out.println("______________________________________");
String val = Alphats.ALPS[3][0];
System.out.println("Exist? " + collection.contains(val));
System.out.println("______________________________________");
Collection<String> collection_3 = ((List<String>)collection).subList(1,2);
System.out.println(collection_3);
}
}
未获支持的操作
public class Unsupported {
static void test(String msg, List<String> list) {
System.out.println("--- " + msg + " ---");
System.out.println("___________________________________");
Collection<String> c = list;
Collection<String> subList = list.subList(1,8);
// Copy of the sublist:
Collection<String> c2 = new ArrayList<String>(subList);
try { c.retainAll(c2); } catch(Exception e) {
System.out.println("retainAll(): " + e);
System.out.println("___________________________________");
}
try { c.removeAll(c2); } catch(Exception e) {
System.out.println("removeAll(): " + e);
System.out.println("___________________________________");
}
try { c.clear(); } catch(Exception e) {
System.out.println("clear(): " + e);
System.out.println("___________________________________");
}
try { c.add("X"); } catch(Exception e) {
System.out.println("add(): " + e);
System.out.println("___________________________________");
}
try { c.addAll(c2); } catch(Exception e) {
System.out.println("addAll(): " + e);
System.out.println("___________________________________");
}
try { c.remove("C"); } catch(Exception e) {
System.out.println("remove(): " + e);
System.out.println("___________________________________");
}
// The List.set() method modifies the value but
// doesn’t change the size of the data structure:
try {
list.set(0, "X");
} catch(Exception e) {
System.out.println("List.set(): " + e);
}
}
public static void main(String[] args) {
List<String> list =
Arrays.asList("A B C D E F G H I J K L".split(" "));
test("Modifiable Copy", new ArrayList<String>(list));
test("Arrays.asList()", list);
test("unmodifiableList()",
Collections.unmodifiableList(
new ArrayList<String>(list)));
}
}
因为ArrayList.asList()会生成一个List,它基于一个固定大小的数组,仅仅支持那些不会改变数组大小的操作,任何会引起底层数据结构尺寸进行修改的方法都会产生一个UnsupportedOperationException异常
List的功能方法
public class Lists {
private static boolean b;
private static String s;
private static int i;
private static Iterator<String> it;
private static ListIterator<String> lit;
public static void basicTest(List<String> a) {
a.add(1, "x"); // Add at location 1
a.add("x"); // Add at end
// Add a collection:
a.addAll(Countries.names(25));
// Add a collection starting at location 3:
a.addAll(3, Countries.names(25));
b = a.contains("1"); // Is it in there?
// Is the entire collection in there?
b = a.containsAll(Countries.names(25));
// Lists allow random access, which is cheap
// for ArrayList, expensive for LinkedList:
s = a.get(1); // Get (typed) object at location 1
i = a.indexOf("1"); // Tell index of object
b = a.isEmpty(); // Any elements inside?
it = a.iterator(); // Ordinary Iterator
lit = a.listIterator(); // ListIterator
lit = a.listIterator(3); // Start at loc 3
i = a.lastIndexOf("1"); // Last match
a.remove(1); // Remove location 1
a.remove("3"); // Remove this object
a.set(1, "y"); // Set location 1 to "y"
// Keep everything that’s in the argument
// (the intersection of the two sets):
a.retainAll(Countries.names(25));
// Remove everything that’s in the argument:
a.removeAll(Countries.names(25));
i = a.size(); // How big is it?
a.clear(); // Remove all elements
}
public static void iterMotion(List<String> a) {
ListIterator<String> it = a.listIterator();
b = it.hasNext();
b = it.hasPrevious();
s = it.next();
i = it.nextIndex();
s = it.previous();
i = it.previousIndex();
}
public static void iterManipulation(List<String> a) {
ListIterator<String> it = a.listIterator();
it.add("47");
// Must move to an element after add():
it.next();
// Remove the element after the newly produced one:
it.remove();
// Must move to an element after remove():
it.next();
// Change the element after the deleted one:
it.set("47");
}
public static void testVisual(List<String> a) {
print(a);
List<String> b = Countries.names(25);
print("b = " + b);
a.addAll(b);
a.addAll(b);
print(a);
// Insert, remove, and replace elements
// using a ListIterator:
ListIterator<String> x = a.listIterator(a.size()/2);
x.add("one");
print(a);
print(x.next());
x.remove();
print(x.next());
x.set("47");
print(a);
// Traverse the list backwards:
x = a.listIterator(a.size());
while(x.hasPrevious())
printnb(x.previous() + " ");
print();
print("testVisual finished");
}
// There are some things that only LinkedLists can do:
public static void testLinkedList() {
LinkedList<String> ll = new LinkedList<String>();
ll.addAll(Countries.names(25));
print(ll);
// Treat it like a stack, pushing:
ll.addFirst("one");
ll.addFirst("two");
print(ll);
// Like "peeking" at the top of a stack:
print(ll.getFirst());
// Like popping a stack:
print(ll.removeFirst());
print(ll.removeFirst());
// Treat it like a queue, pulling elements
// off the tail end:
print(ll.removeLast());
print(ll);
}
public static void main(String[] args) {
// Make and fill a new list each time:
basicTest(
new LinkedList<String>(Countries.names(25)));
basicTest(
new ArrayList<String>(Countries.names(25)));
iterMotion(
new LinkedList<String>(Countries.names(25)));
iterMotion(
new ArrayList<String>(Countries.names(25)));
iterManipulation(
new LinkedList<String>(Countries.names(25)));
iterManipulation(
new ArrayList<String>(Countries.names(25)));
testVisual(
new LinkedList<String>(Countries.names(25)));
testLinkedList();
}
}
Set的使用
public class SetType {
int i;
public SetType(int i) {
this.i = i;
}
@Override
public boolean equals(Object obj) {
return obj instanceof SetType && ( i == ((SetType)obj).i);
}
@Override
public String toString() {
return "SetType{" +
"i=" + i +
'}';
}
}
public class HashType extends SetType {
public HashType(int n) {
super(n);
}
@Override
public int hashCode() {
return i;
}
}
public class TreeType extends SetType implements Comparable<TreeType>{
public TreeType(int i) {
super(i);
}
@Override
public int compareTo(TreeType o) {
return (o.i < i ? -1 : (o.i == i ? 0 : 1));
}
}
public class TypesForSets {
static <T> Set<T> fill(Set<T> set,Class<T> type){
for (int i = 0; i < 10; i++) {
try {
set.add(
type.getConstructor(int.class).newInstance(i));
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
return set;
}
static <T> void test(Set<T> set,Class<T> type){
fill(set,type);
fill(set,type);
fill(set,type);
System.out.println(set);
}
public static void main(String[] args) {
test(new HashSet<HashType>(),HashType.class);
System.out.println("___________________________________");
test(new LinkedHashSet<HashType>(),HashType.class);
System.out.println("___________________________________");
test(new TreeSet<TreeType>(),TreeType.class);
}
}
SortedSet
public class SortedSetDemo {
public static void main(String[] args) {
SortedSet<String> strings = new TreeSet<>();
Collections.addAll(strings,"J JKJK jJKJKHGGHF HJHJ".split(" "));
System.out.println(strings);
System.out.println("______________________________________________");
String low = strings.first();
String high = strings.last();
System.out.println(low);
System.out.println("______________________________________________");
System.out.println(high);
System.out.println("______________________________________________");
Iterator<String> iterator = strings.iterator();
for (int i = 0; i <=3 ; i++) {
if (i == 3){
low = iterator.next();
} else {
iterator.next();
}
}
System.out.println(low);
System.out.println("______________________________________________");
System.out.println(high);
System.out.println("______________________________________________");
System.out.println(strings.subSet(low,high));
}
}
队列
public class QueueBehavior {
private static int count = 7;
static <T> void test(Queue<T> queue, Generator<T> generator){
for (int i = 0; i < count; i++) {
queue.offer(generator.next());
}
while (queue.peek() != null){
System.out.println(queue.remove() + " ");
}
System.out.println("");
}
static class Gen implements Generator<String>{
String[] strings = ("dhd jdjh wudh hf5 455 dkd 78 djis".split(" "));
int i;
@Override
public String next() {
return strings[i++];
}
}
public static void main(String[] args) {
test(new LinkedList<String>(),new Gen());
test(new PriorityQueue<String>(),new Gen());
test(new ArrayBlockingQueue<String>(count),new Gen());
}
}
优先级队列
public class ToDoList extends PriorityQueue<ToDoList.ToDoItem> {
static class ToDoItem extends ToDoList implements Comparable<ToDoItem>{
private char primary;
private int secondary;
private String item;
public ToDoItem(char primary, int secondary, String item) {
this.primary = primary;
this.secondary = secondary;
this.item = item;
}
@Override
public int compareTo(ToDoItem o) {
if (primary > o.primary){
return +1;
}
if (primary == o.primary){
if (secondary>o.secondary){
return +1;
} else if (secondary==o.secondary){
return 0;
}
}
return -1;
}
@Override
public String toString() {
return "ToDoItem{" +
"primary=" + primary +
", secondary=" + secondary +
", item='" + item + '\'' +
'}';
}
}
public void add(String td,char pri,int sec){
super.add(new ToDoItem(pri,sec,td));
}
public static void main(String[] args) {
ToDoList toDoItems = new ToDoList();
toDoItems.add("ass",'s',44);
while (!toDoItems.isEmpty()){
System.out.println(toDoItems.remove());
}
}
}
Map使用
看下关联数组是如何创建的
public class AssociativeArray<K,V> {
private Object[][] pairs;
private int index;
public AssociativeArray(int len) {
pairs = new Object[len][2];
}
public void put(K key,V val){
if (index >= pairs.length){
throw new ArrayIndexOutOfBoundsException();
}
pairs[index++] = new Object[]{key,val};
}
public V get(K k){
for (int i = 0; i < index; i++) {
if (k.equals(pairs[i][0])){
return (V) pairs[i][1];
}
}
return null;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < index; i++) {
builder.append(pairs[i][0].toString());
builder.append(":");
builder.append(pairs[i][1].toString());
if (i < index-1){
builder.append("\n");
}
}
return builder.toString();
}
public static void main(String[] args) {
// 限定大小为6个 有可能不小心出现数组越界错误
AssociativeArray<String,String> map =
new AssociativeArray<>(6);
map.put("sky","blue");
map.put("grass","green");
map.put("tree","tall");
map.put("extar","object");
System.out.println(map);
System.out.println(map.get("sky"));
}
}
Map接口的用法
public class Maps {
public static void printKeys(Map<Integer,String> map){
System.out.println("Size = " + map.size() + ". ");
System.out.println("Keys : ");
System.out.println(map.keySet());
}
public static void test(Map<Integer,String> map){
System.out.println(map.getClass().getSimpleName());
map.putAll(new CountingMapData(20));
printKeys(map);
System.out.println("________________");
System.out.println(map.values());
System.out.println("________________");
System.out.println(map.containsKey(11));
System.out.println("________________");
System.out.println(map.containsValue(12));
System.out.println("________________");
Integer key = map.keySet().iterator().next();
}
public static void main(String[] args) {
test(new HashMap<Integer,String>());
}
}
SortedMap
public class SortedMapDemo {
public static void main(String[] args) {
TreeMap<Integer,String> sortMap =
new TreeMap<>(new CountingMapData(30));
System.out.println(sortMap);
System.out.println("______________________________________________");
Integer low = sortMap.firstKey();
Integer high = sortMap.lastKey();
System.out.println(low);
System.out.println("______________________________________________");
System.out.println(high);
Iterator<Integer> integerIterator = sortMap.keySet().iterator();
for (int i = 0; i <=6 ; i++) {
if (i == 3) {
low = integerIterator.next();
}
if (i == 6) {
high = integerIterator.next();
}
else {
integerIterator.next();
}
}
System.out.println(low);
System.out.println("______________________________________________");
System.out.println(high);
System.out.println(sortMap.subMap(low,high));
}
}
散列与散列码
例子:土拨鼠(Groundhog)与预报(Prediction)联系在一起
public class Prediction {
private static Random random = new Random(47);
private boolean shadow = random.nextDouble() > 0.5;
@Override
public String toString() {
if (shadow) {
return "Six more weeks of Winter";
}
else {
return "Early Spring";
}
}
}
public class Groundhog {
protected int number;
public Groundhog(int number) {
this.number = number;
}
@Override
public String toString() {
return "Groundhog{" +
"number=" + number +
'}' + "\n";
}
}
public class SpringDetector {
public static <T extends Groundhog>
void detectSpring(Class<T> type) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Constructor<T> ghog = type.getConstructor(int.class);
Map<Groundhog,Prediction> map =
new HashMap<>();
for (int i = 0; i < 10; i++) {
map.put(ghog.newInstance(i),new Prediction());
}
System.out.println("map " + map);
Groundhog gh = ghog.newInstance(3);
System.out.println("prediction " + gh);
if (map.containsKey(gh)) {
System.out.println(map.get(gh));
} else {
System.out.println("No found" + gh);
}
}
public static void main(String[] args) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
detectSpring(Groundhog.class);
}
}
这边有个问题,数字3这个键无法找到
是因为Groundhog自动继承基类Object,所以它使用Object的hashCode方法生成散列码,而这默认使用对象的地址计算散列码,因此Groundhog(3)生成的第一个实例的散列码与由Groundhog(3)生成的第二个实例的散列码是不一样的
同时重载hashCode与equals
public class Groundhog2 extends Groundhog{
public Groundhog2(int n) {
super(n);
}
@Override
public int hashCode() {
return number;
}
@Override
public boolean equals(Object obj) {
return obj instanceof Groundhog2 &&
(number == ((Groundhog2)obj).number);
}
}
public class SpringDetector2 {
public static void main(String[] args) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
SpringDetector.detectSpring(Groundhog2.class);
}
}
选择怎样的接口
容器的性能测试
基本框架
public abstract class Test<C> {
String name;
public Test(String name) { this.name = name; }
// Override this method for different tests.
// Returns actual number of repetitions of test.
abstract int test(C container, TestParam tp);
}
public class TestParam {
public final int size;
public final int loops;
public TestParam(int size, int loops) {
this.size = size;
this.loops = loops;
}
// Create an array of TestParam from a varargs sequence:
public static TestParam[] array(int... values) {
int size = values.length/2;
TestParam[] result = new TestParam[size];
int n = 0;
for(int i = 0; i < size; i++)
result[i] = new TestParam(values[n++], values[n++]);
return result;
}
// Convert a String array to a TestParam array:
public static TestParam[] array(String[] values) {
int[] vals = new int[values.length];
for(int i = 0; i < vals.length; i++)
vals[i] = Integer.decode(values[i]);
return array(vals);
}
}
public class Tester<C> {
public static int fieldWidth = 8;
public static TestParam[] defaultParams= TestParam.array(
10, 5000, 100, 5000, 1000, 5000, 10000, 500);
// Override this to modify pre-test initialization:
protected C initialize(int size) { return container; }
protected C container;
private String headline = "";
private List<Test<C>> tests;
private static String stringField() {
return "%" + fieldWidth + "s";
}
private static String numberField() {
return "%" + fieldWidth + "d";
}
private static int sizeWidth = 5;
private static String sizeField = "%" + sizeWidth + "s";
private TestParam[] paramList = defaultParams;
public Tester(C container, List<Test<C>> tests) {
this.container = container;
this.tests = tests;
if(container != null)
headline = container.getClass().getSimpleName();
}
public Tester(C container, List<Test<C>> tests,
TestParam[] paramList) {
this(container, tests);
this.paramList = paramList;
}
public void setHeadline(String newHeadline) {
headline = newHeadline;
}
// Generic methods for convenience :
public static <C> void run(C cntnr, List<Test<C>> tests){
new Tester<C>(cntnr, tests).timedTest();
}
public static <C> void run(C cntnr,
List<Test<C>> tests, TestParam[] paramList) {
new Tester<C>(cntnr, tests, paramList).timedTest();
}
private void displayHeader() {
// Calculate width and pad with ‘-’:
int width = fieldWidth * tests.size() + sizeWidth;
int dashLength = width - headline.length() - 1;
StringBuilder head = new StringBuilder(width);
for(int i = 0; i < dashLength/2; i++)
head.append('-');
head.append(' ');
head.append(headline);
head.append(' ');
for(int i = 0; i < dashLength/2; i++)
head.append('-');
System.out.println(head);
// Print column headers:
System.out.format(sizeField, "size");
for(Test test : tests)
System.out.format(stringField(), test.name);
System.out.println();
}
// Run the tests for this container:
public void timedTest() {
displayHeader();
for(TestParam param : paramList) {
System.out.format(sizeField, param.size);
for(Test<C> test : tests) {
C kontainer = initialize(param.size);
long start = System.nanoTime();
// Call the overriden method:
int reps = test.test(kontainer, param);
long duration = System.nanoTime() - start;
long timePerRep = duration / reps; // Nanoseconds
System.out.format(numberField(), timePerRep);
}
System.out.println();
}
}
}
List测试
public class ListPerformance {
static Random rand = new Random();
static int reps = 1000;
static List<Test<List<Integer>>> tests =
new ArrayList<Test<List<Integer>>>();
static List<Test<LinkedList<Integer>>> qTests =
new ArrayList<Test<LinkedList<Integer>>>();
static {
tests.add(new Test<List<Integer>>("add") {
int test(List<Integer> list, TestParam tp) {
int loops = tp.loops;
int listSize = tp.size;
for(int i = 0; i < loops; i++) {
list.clear();
for(int j = 0; j < listSize; j++)
list.add(j);
}
return loops * listSize;
}
});
tests.add(new Test<List<Integer>>("get") {
int test(List<Integer> list, TestParam tp) {
int loops = tp.loops * reps;
int listSize = list.size();
for(int i = 0; i < loops; i++)
list.get(rand.nextInt(listSize));
return loops;
}
});
tests.add(new Test<List<Integer>>("set") {
int test(List<Integer> list, TestParam tp) {
int loops = tp.loops * reps;
int listSize = list.size();
for(int i = 0; i < loops; i++)
list.set(rand.nextInt(listSize), 47);
return loops;
}
});
tests.add(new Test<List<Integer>>("iteradd") {
int test(List<Integer> list, TestParam tp) {
final int LOOPS = 1000000;
int half = list.size() / 2;
ListIterator<Integer> it = list.listIterator(half);
for(int i = 0; i < LOOPS; i++)
it.add(47);
return LOOPS;
}
});
tests.add(new Test<List<Integer>>("insert") {
int test(List<Integer> list, TestParam tp) {
int loops = tp.loops;
for(int i = 0; i < loops; i++)
list.add(5, 47); // Minimize random-access cost
return loops;
}
});
tests.add(new Test<List<Integer>>("remove") {
int test(List<Integer> list, TestParam tp) {
int loops = tp.loops;
int size = tp.size;
for(int i = 0; i < loops; i++) {
list.clear();
list.addAll(new CountingIntegerList(size));
while(list.size() > 5)
list.remove(5); // Minimize random-access cost
}
return loops * size;
}
});
// Tests for queue behavior:
qTests.add(new Test<LinkedList<Integer>>("addFirst") {
int test(LinkedList<Integer> list, TestParam tp) {
int loops = tp.loops;
int size = tp.size;
for(int i = 0; i < loops; i++) {
list.clear();
for(int j = 0; j < size; j++)
list.addFirst(47);
}
return loops * size;
}
});
qTests.add(new Test<LinkedList<Integer>>("addLast") {
int test(LinkedList<Integer> list, TestParam tp) {
int loops = tp.loops;
int size = tp.size;
for(int i = 0; i < loops; i++) {
list.clear();
for(int j = 0; j < size; j++)
list.addLast(47);
}
return loops * size;
}
});
qTests.add(
new Test<LinkedList<Integer>>("rmFirst") {
int test(LinkedList<Integer> list, TestParam tp) {
int loops = tp.loops;
int size = tp.size;
for(int i = 0; i < loops; i++) {
list.clear();
list.addAll(new CountingIntegerList(size));
while(list.size() > 0)
list.removeFirst();
}
return loops * size;
}
});
qTests.add(new Test<LinkedList<Integer>>("rmLast") {
int test(LinkedList<Integer> list, TestParam tp) {
int loops = tp.loops;
int size = tp.size;
for(int i = 0; i < loops; i++) {
list.clear();
list.addAll(new CountingIntegerList(size));
while(list.size() > 0)
list.removeLast();
}
return loops * size;
}
});
}
static class ListTester extends Tester<List<Integer>> {
public ListTester(List<Integer> container,
List<Test<List<Integer>>> tests) {
super(container, tests);
}
// Fill to the appropriate size before each test:
@Override protected List<Integer> initialize(int size){
container.clear();
container.addAll(new CountingIntegerList(size));
return container;
}
// Convenience method:
public static void run(List<Integer> list,
List<Test<List<Integer>>> tests) {
new ListTester(list, tests).timedTest();
}
}
public static void main(String[] args) {
if(args.length > 0)
Tester.defaultParams = TestParam.array(args);
// Can only do these two tests on an array:
Tester<List<Integer>> arrayTest =
new Tester<List<Integer>>(null, tests.subList(1, 3)){
// This will be called before each test. It
// produces a non-resizeable array-backed list:
@Override protected
List<Integer> initialize(int size) {
Integer[] ia = Generater.array(Integer.class,
new CountingGenerator.Integer(), size);
return Arrays.asList(ia);
}
};
arrayTest.setHeadline("Array as List");
arrayTest.timedTest();
Tester.defaultParams= TestParam.array(
10, 5000, 100, 5000, 1000, 1000, 10000, 200);
if(args.length > 0)
Tester.defaultParams = TestParam.array(args);
ListTester.run(new ArrayList<Integer>(), tests);
ListTester.run(new LinkedList<Integer>(), tests);
ListTester.run(new Vector<Integer>(), tests);
Tester.fieldWidth = 12;
Tester<LinkedList<Integer>> qTest =
new Tester<LinkedList<Integer>>(
new LinkedList<Integer>(), qTests);
qTest.setHeadline("Queue tests");
qTest.timedTest();
}
}
Set测试
public class SetPerformance {
static List<Test<Set<Integer>>> tests =
new ArrayList<Test<Set<Integer>>>();
static {
tests.add(new Test<Set<Integer>>("add") {
int test(Set<Integer> set, TestParam tp) {
int loops = tp.loops;
int size = tp.size;
for(int i = 0; i < loops; i++) {
set.clear();
for(int j = 0; j < size; j++)
set.add(j);
}
return loops * size;
}
});
tests.add(new Test<Set<Integer>>("contains") {
int test(Set<Integer> set, TestParam tp) {
int loops = tp.loops;
int span = tp.size * 2;
for(int i = 0; i < loops; i++)
for(int j = 0; j < span; j++)
set.contains(j);
return loops * span;
}
});
tests.add(new Test<Set<Integer>>("iterate") {
int test(Set<Integer> set, TestParam tp) {
int loops = tp.loops * 10;
for(int i = 0; i < loops; i++) {
Iterator<Integer> it = set.iterator();
while(it.hasNext())
it.next();
}
return loops * set.size();
}
});
}
public static void main(String[] args) {
if(args.length > 0)
Tester.defaultParams = TestParam.array(args);
Tester.fieldWidth = 10;
Tester.run(new TreeSet<Integer>(), tests);
Tester.run(new HashSet<Integer>(), tests);
Tester.run(new LinkedHashSet<Integer>(), tests);
}
}
Map测试
public class MapPerformance {
static List<Test<Map<Integer,Integer>>> tests =
new ArrayList<Test<Map<Integer,Integer>>>();
static {
tests.add(new Test<Map<Integer,Integer>>("put") {
int test(Map<Integer,Integer> map, TestParam tp) {
int loops = tp.loops;
int size = tp.size;
for(int i = 0; i < loops; i++) {
map.clear();
for(int j = 0; j < size; j++)
map.put(j, j);
}
return loops * size;
}
});
tests.add(new Test<Map<Integer,Integer>>("get") {
int test(Map<Integer,Integer> map, TestParam tp) {
int loops = tp.loops;
int span = tp.size * 2;
for(int i = 0; i < loops; i++)
for(int j = 0; j < span; j++)
map.get(j);
return loops * span;
}
});
tests.add(new Test<Map<Integer,Integer>>("iterate") {
int test(Map<Integer,Integer> map, TestParam tp) {
int loops = tp.loops * 10;
for(int i = 0; i < loops; i ++) {
Iterator it = map.entrySet().iterator();
while(it.hasNext())
it.next();
}
return loops * map.size();
}
});
}
public static void main(String[] args) {
if(args.length > 0)
Tester.defaultParams = TestParam.array(args);
Tester.run(new TreeMap<Integer,Integer>(), tests);
Tester.run(new HashMap<Integer,Integer>(), tests);
Tester.run(new LinkedHashMap<Integer,Integer>(),tests);
Tester.run(
new IdentityHashMap<Integer,Integer>(), tests);
Tester.run(new WeakHashMap<Integer,Integer>(), tests);
Tester.run(new Hashtable<Integer,Integer>(), tests);
}
}
实用方法
public class Utilities {
static List<String> list = Arrays.asList(
"one Two three Four five six one".split(" "));
public static void main(String[] args) {
print(list);
System.out.println("__________________________________________________");
print("‘list’ disjoint (Four)?: " +
Collections.disjoint(list,
Collections.singletonList("Four")));
System.out.println("__________________________________________________");
print("max: " + Collections.max(list));
System.out.println("__________________________________________________");
print("min: " + Collections.min(list));
System.out.println("__________________________________________________");
print("max w/ comparator: " + Collections.max(list,
String.CASE_INSENSITIVE_ORDER));
System.out.println("__________________________________________________");
print("min w/ comparator: " + Collections.min(list,
String.CASE_INSENSITIVE_ORDER));
System.out.println("__________________________________________________");
List<String> sublist =
Arrays.asList("Four five six".split(" "));
print("indexOfSubList: " +
Collections.indexOfSubList(list, sublist));
System.out.println("__________________________________________________");
print("lastIndexOfSubList: " +
Collections.lastIndexOfSubList(list, sublist));
System.out.println("__________________________________________________");
Collections.replaceAll(list, "one", "Yo");
print("replaceAll: " + list);
System.out.println("__________________________________________________");
Collections.reverse(list);
print("reverse: " + list);
System.out.println("__________________________________________________");
Collections.rotate(list, 3);
print("rotate: " + list);
System.out.println("__________________________________________________");
List<String> source =
Arrays.asList("in the matrix".split(" "));
Collections.copy(list, source);
print("copy: " + list);
System.out.println("__________________________________________________");
Collections.swap(list, 0, list.size() - 1);
print("swap: " + list);
System.out.println("__________________________________________________");
Collections.shuffle(list, new Random(47));
print("shuffled: " + list);
System.out.println("__________________________________________________");
Collections.fill(list, "pop");
System.out.println("__________________________________________________");
print("fill: " + list);
System.out.println("__________________________________________________");
print("frequency of ‘pop’: " +
Collections.frequency(list, "pop"));
System.out.println("__________________________________________________");
List<String> dups = Collections.nCopies(3, "snap");
System.out.println("__________________________________________________");
print("dups: " + dups);
System.out.println("__________________________________________________");
print("‘list’ disjoint ‘dups’?: " +
Collections.disjoint(list, dups));
System.out.println("__________________________________________________");
// Getting an old-style Enumeration:
Enumeration<String> e = Collections.enumeration(dups);
Vector<String> v = new Vector<String>();
while(e.hasMoreElements())
v.addElement(e.nextElement());
// Converting an old-style Vector
// to a List via an Enumeration:
ArrayList<String> arrayList =
Collections.list(v.elements());
print("arrayList: " + arrayList);
}
}
设定Collection或Map为不可修改
public class ReadOnly {
static Collection<String> data =
new ArrayList<>(Alphats.names());
public static void main(String[] args) {
Collection<String> collection =
Collections.unmodifiableCollection(new ArrayList<>(data)
);
System.out.println(collection);
System.out.println("___________________________");
// java.lang.UnsupportedOperationException
// collection.add("s");
List<String> a = Collections.unmodifiableList(new ArrayList<>(data));
ListIterator<String> listIterator = a.listIterator();
System.out.println(listIterator.nextIndex());
Set<String> s = Collections.unmodifiableSet(
new HashSet<String>(data));
print(s); // Reading is OK
//! s.add("one"); // Can’t change it
// For a SortedSet:
// Set<String> ss = Collections.unmodifiableSortedSet(
// new TreeSet<String>(data));
// Map<String,String> m = Collections.unmodifiableMap(
// new HashMap<String,String>(data);
// print(m); // Reading is OK
////! m.put("Ralph", "Howdy!");
//// For a SortedMap:
// Map<String,String> sm =
// Collections.unmodifiableSortedMap(
// new TreeMap<String,String>(Alphats.names(3));
}
}
网友评论