Queue
队列对并发编程很重要。将LinkedList向上转型为Queue,以下是常用方法
public class Command {
private String s;
public Command(String s) { this.s = s;}
public String operation() { return s;}
public static void main(String[] args) {
Queue<Command> q = new LinkedList<>();
UseCommand.use(FillCommand.fill(q, new Command("fuck1"), new Command("fuck2")));
}
}
class FillCommand {
public static Queue<Command> fill(Queue<Command> queue, Command... args) {
for (Command c : args) queue.offer(c);
return queue;
}
}
class UseCommand {
public static void use(Queue<Command> q) {
while (!q.isEmpty()) { println(q.poll().operation());}
}
}
PriorityQueue
优先级队列声明下一个弹出元素是最需要的元素。在优先级队列调用offer,这个对象在队列中会被排序。默认的排序将使用自然顺序。Integer、String和Character都内建了Comparator
,所以自然排序是值从小到大(空格有最大优先级)
public static void main(String[] args) {
Queue<Double> q = new PriorityQueue<>();
var rand = new Random();
while (q.size() < 20) q.offer(rand.nextDouble()*100);
while (!q.isEmpty()) println(q.poll());
}
Collection和Iterator
Collection接口描述可以让我们创建更通用的代码。实现Collection意味着要提供Iterator方法
可以继承AbstractCollection代替实现Collection,虽然两者都要实现Iterator,但前者不用实现Collection中的其他方法。
public class CollectionSequence extends AbstractCollection<Pet> {
private Pet[] pets = Pets.createArray(9);
public int size() { return pets.length;}
public Iterator<Pet> iterator() { // 实现Iterator<>
return new Iterator<>() {
private int index = 0;
@Override
public boolean hasNext() { return index < pets.length; }
@Override
public Pet next() { return pets[index++];}
public void remove() { throw new UnsupportedOperationException();}
};
}
public static void main(String[] args) {
var cs = new CollectionSequence();
for (Pet p : cs) {
print(p.id() + ": " + p + " ");
}
println();
Iterator<Pet> it = cs.iterator();
while (it.hasNext()) {
Pet p = it.next();
print(p.id() + ": " + p + " ");
}
}
}
Foreach与迭代器
foreach语句可以用于数组和其他任何Iterable,但数组不一定是一个Iterable。
public class ArrayNotIterable {
static <T> void test(Iterable<T> ib) {
for (T t : ib) println(t + " ");
}
public static void main(String[] args) {
test(Arrays.asList(1, 2 ,3)); // ok
String[] s = {"A", "B", "C"};
// !test(s) s is not an iterable
test(Arrays.asList(s)); // ok
}
}
实现迭代器:
class RandomShapeGenerator implements Iterable<Shape>{ // randomly creates shapes...
private Random rand = new Random();
private int count;
private ArrayList<Shape> s = new ArrayList<>(count);
public RandomShapeGenerator(int count) { this.count = count;}
public void next() { // return a Shape reference randomly...
switch(rand.nextInt(3)) {
case 0: s.add(new Circle()); break;
case 1: s.add(new Square()); break;
case 2: s.add(new Triangle()); break;
default:
}
}
@Override
public Iterator<Shape> iterator() {
return new Iterator<>() {
private int index = 0;
@Override
public boolean hasNext() { return index < count;}
@Override
public Shape next() { return s.get(index++);}
};
}
}
适配器方法惯用法
适配器方法,提供特定接口满足需求,即对一个方法,有不同的具体需求。
public class MultiIterableClass extends IterableClass {
public Iterable<String> reversed() {
// 不同的具体实现,但返回类型仍然是Iterator
return () -> new Iterator<>() {
int current = words.length - 1;
@Override
public boolean hasNext() { return current > -1; }
@Override
public String next() { return words[current--]; }
@Override
public void remove() { throw new UnsupportedOperationException();}
};
}
public Iterable<String> randomized() {
// 不同的具体实现,但返回类型仍然是Iterator
return () -> {
List<String> shuffled =
new ArrayList<>(Arrays.asList(words));
Collections.shuffle(shuffled, new Random());
return shuffled.iterator(); // 返回类型仍然是iterator
};
}
public static void main(String[] args) {
var mic = new MultiIterableClass();
for (String s : mic.reversed()) print(s + " ");
println();
for (String s : mic.randomized()) print(s + " ");
println();
for (String s : mic) print(s + " ");
}
}
总结
Collection和Map是容器类库中的两种主要类型,区别在于容器中每个槽保存的元素个数。
- Collection在每个槽中只能保存一个元素:
- List: 以特定的顺序保存一组元素;
- ArrayList & LinkedList按插入顺序输出,都是排好序的
- Set: 元素不能重复;
- HashSet: 排序无实际意义,但获取速度最快;
- TreeSet: 按照一定顺序排序,保持元素处于排序状态;
- LinkedHashSet: 按元素被添加的顺序保存对象
- Queue: 只允许在容器一端插入,并从另一段移除。
- PriorityQueue: 优先级队列;
- List: 以特定的顺序保存一组元素;
- Map每个槽可以保存两个元素:即键值 。
- HashMap: 排序无实际意义,但获取速度最快;
- TreeMap: 按照一定顺序排序,保持键处于排序状态;
- LinkedHashMap: 按元素被添加的顺序保存对象,速度也很快。
Map 和 Collection的重叠就是Map可以使用entrySet()和values()来产生Collection。
public class Test {
public static void main(String[] args) {
var m = new LinkedHashMap<Integer, Integer>();
m.put(1, 2);
m.put(2, 4);
List<Map.Entry<Integer, Integer>> me = new LinkedList<>(m.entrySet());
println(m); // {1=2, 2=4}
println(me); // [1=2, 2=4]
}
}