• Java编程思想(第十一章持有对象)


    1. 第11章 持有对象

    20200131134546.png

    java通过使用容器类来储存对象,与普通数组不同的是,普通数组的长度不可变。

    1.1. 泛型与类型安全的容器

    使用预定义的泛型,它指定了这个容器实例可以保存的类型,通过使用泛型,就可以在编译器防止将错误类型的对象放置到容器中。

    public class gerbil {
        private int gerbilNumber;
        public gerbil(int gerbilNumber){
            this.gerbilNumber = gerbilNumber;
        }
        public void hop(){
            System.out.println(this.gerbilNumber);
            System.out.println("he is running");
    
        }
    }
    
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class Main {
    
        public static void main(String[] args) {
    	// write your code here
            List<gerbil> gerbils = new ArrayList<>();
            gerbils.add(new gerbil(2));
            gerbils.add(new gerbil(3));
            gerbils.add(new gerbil(4));
            gerbils.add(new gerbil(5));
            for (gerbil g:gerbils
                 ) {
                g.hop();
            }
        }
    }
    
    

    1.2. 基本概念

    java容器类库的用途是保存对象,将其划分为两个不同的接口:

    • Collection:一个独立元素的序列,这些元素都服从一条或多条规则,List必须按插入顺序保存元素,set不能有重复元素,Queue按照排队规则来确定对象产生的顺序。
    • Map:一组成对的键值对对象,允许你使用键值来查找值。

    在进行容器创建时,可以创建接口的对象,可以方便于实现的修改,LinkList中具有List接口中没有实现的方法,TreeMap中也有Map中未实现的方法,在使用这些方法时,不可以向上转型:

    List<gerbil> gerbils = new ArrayList<>();
    List<gerbil> gerbils = new LinkedList<>();
    

    1.3. 向容器添加元素和容器的打印

    在java.utill包中的Arrays和Collections类中都有方法可以在Collenction中添加一组元素。

    • Arrays.asList()方法接受一个数组或是一个用逗号分隔的列表,转换为一个List对象

    20200129163652.png

    • Collections.addAll()方法接受一个Collection对象,以及一个数组或是一个用逗号分割的列表,将元素添加到Collection中,此方法效率高。

    20200129165956.png

    • Collection的构造方法也以接受另一个Collection对象,用来自身初始化。
    • Collection.addAll()成员方法只能接受另一个Collection对象作为参数,不能使用可变参数列表。
    • 也可直接使用Arrays.asList()方法的输出,将其当作List,但是得到的底层为数组长度不可变。
    public class AddingGroup {
        public static void main(String[] args) {
            Collection<Integer> collection =
                    new ArrayList<Integer>(Arrays.asList(1, 2, 3, 4, 5));
            Integer[] moreInts = { 6, 7, 8, 9, 10 };
            //int[] moreInts = { 6, 7, 8, 9, 10 };//进行自动装箱
            collection.addAll(Arrays.asList(moreInts));
            // Runs significantly faster, but you can't
            // construct a Collection this way:
            Collections.addAll(collection, 11, 12, 13, 14, 15);
            Collections.addAll(collection, moreInts);
            // Produces a list "backed by" an array:
            List<Integer> list = Arrays.asList(16, 17, 18, 19, 20);//长度不可变
            list.set(1, 99); // OK -- modify an element
            list.add(21); // Runtime error because the
            // underlying array cannot be resized.
        }
    }
    
    public class AsListInference {
      public static void main(String[] args) {
        List<Snow> snow1 = Arrays.asList(
          new Crusty(), new Slush(), new Powder());
    
        // Won't compile:
        List<Snow> snow2 = Arrays.asList(
          new Light(), new Heavy());//jdk1.7/1.8支持
    
        // Collections.addAll() doesn't get confused:
        List<Snow> snow3 = new ArrayList<Snow>();
        Collections.addAll(snow3, new Light(), new Heavy());
    
        // Give a hint using an
        // explicit type argument specification:
        List<Snow> snow4 = Arrays.<Snow>asList(
           new Light(), new Heavy());
      }
    } ///:~
    

    对于基本数组的打印,可以使用Arrays.toString()方法

    int[] a = {1,2,3};
    System.out.println(Arrays.toString(a));
    //Output:
    [1, 2, 3]
    

    对于容器的打印,可以使用容器内置的toString()方法

    对于一个对象,在执行system.out.println()方法时,会自动调用toString方法,

    20200131155519.png

    20200131155641.png

    20200131160322.png

    import java.util.*;
    import static net.mindview.util.Print.*;
    
    public class PrintingContainers {
      static Collection fill(Collection<String> collection) {
        collection.add("rat");
        collection.add("cat");
        collection.add("dog");
        collection.add("dog");
        return collection;
      }
      static Map fill(Map<String,String> map) {//方法的重载
        map.put("rat", "Fuzzy");
        map.put("cat", "Rags");
        map.put("dog", "Bosco");
        map.put("dog", "Spot");
        return map;
      }	
      public static void main(String[] args) {
        print(fill(new ArrayList<String>()));
        print(fill(new LinkedList<String>()));
        print(fill(new HashSet<String>()));
        print(fill(new TreeSet<String>()));
        print(fill(new LinkedHashSet<String>()));
        print(fill(new HashMap<String,String>()));
        print(fill(new TreeMap<String,String>()));
        print(fill(new LinkedHashMap<String,String>()));
      }
    } /* Output:
    [rat, cat, dog, dog]
    [rat, cat, dog, dog]
    [dog, cat, rat]
    [cat, dog, rat]
    [rat, cat, dog]
    {dog=Spot, cat=Rags, rat=Fuzzy}
    {cat=Rags, dog=Spot, rat=Fuzzy}
    {rat=Fuzzy, cat=Rags, dog=Spot}
    *///:~
    

    1.4. List

    list接口在collection接口的基础上添加了大量的方法,可以在List的中间插入和删除元素

    • ArrayList:方便于随机访问元素,如增与查,但是在List的中间插入和移动元素时较慢。
    • LinkedList:方便插入与删除,但在随机访问方面较慢,但是他的特性集较ArrayList更大。

    1.4.1. ArrayList

    20200204100708.png

    add(),contain(),remove(),get(),indexof(),remove(),sublist(),containall();removeall(),addall(),clear(),toarray()

    //: holding/ListFeatures.java
    import typeinfo.pets.*;
    import java.util.*;
    import static net.mindview.util.Print.*;
    
    public class ListFeatures {
      public static void main(String[] args) {
        Random rand = new Random(47);
        List<Pet> pets = Pets.arrayList(7);//arraylist容器类
        print("1: " + pets);
        //1: [Rat, Manx, Cymric, Mutt, Pug, Cymric, Pug]
        Hamster h = new Hamster();
        pets.add(h); // Automatically resizes
        print("2: " + pets);
        //2: [Rat, Manx, Cymric, Mutt, Pug, Cymric, Pug, Hamster]
        print("3: " + pets.contains(h));
        //3: true
        pets.remove(h); // Remove by object
        Pet p = pets.get(2);// get()得到下标值对应的值
        print("4: " +  p + " " + pets.indexOf(p));//返回此列表中指定元素的第一次出现的索引,如果此列表不包含元素,则返回-1。 
        //4: Cymric 2
        Pet cymric = new Cymric();
        print("5: " + pets.indexOf(cymric));
        //5: -1
        print("6: " + pets.remove(cymric));
        //6: false
        // Must be the exact object:
        print("7: " + pets.remove(p));
        //7: true
        print("8: " + pets);
        //8: [Rat, Manx, Mutt, Pug, Cymric, Pug]
        pets.add(3, new Mouse()); // Insert at an index
        print("9: " + pets);
        //9: [Rat, Manx, Mutt, Mouse, Pug, Cymric, Pug]
    
    
        List<Pet> sub = pets.subList(1, 4);//含低端点,不含高端点
        print("subList: " + sub);
        //subList: [Manx, Mutt, Mouse]
        print("10: " + pets.containsAll(sub));
        //10: true
        Collections.sort(sub); // In-place sort
        print("sorted subList: " + sub);
        //sorted subList: [Manx, Mouse, Mutt]
        // Order is not important in containsAll():
        print("11: " + pets.containsAll(sub));
        //11: true
        Collections.shuffle(sub, rand); // Mix it up使用默认的随机源随机排列指定的列表。
        print("shuffled subList: " + sub);
        //shuffled subList: [Mouse, Manx, Mutt]
        print("12: " + pets.containsAll(sub));
        //12: true
    
    
        print("9: " + pets);
        //9: [Rat, Manx, Mutt, Mouse, Pug, Cymric, Pug]
        List<Pet> copy = new ArrayList<Pet>(pets);
        sub = Arrays.asList(pets.get(1), pets.get(4));
        print("sub: " + sub);
        //sub: [Mouse, Pug]
        copy.retainAll(sub);
        print("13: " + copy);
        //13: [Mouse, Pug]
    
    
        copy = new ArrayList<Pet>(pets); // Get a fresh copy
        copy.remove(2); // Remove by index
        print("14: " + copy);
        //14: [Rat, Mouse, Mutt, Pug, Cymric, Pug]
        copy.removeAll(sub); // Only removes exact objects
        print("15: " + copy);
        //15: [Rat, Mutt, Cymric, Pug]
        copy.set(1, new Mouse()); // Replace an element
        print("16: " + copy);
        copy.addAll(2, sub); // Insert a list in the middle
        print("17: " + copy);
        print("18: " + pets.isEmpty());
        pets.clear(); // Remove all elements
        print("19: " + pets);
        print("20: " + pets.isEmpty());
        pets.addAll(Pets.arrayList(4));
        print("21: " + pets);
        Object[] o = pets.toArray();
        print("22: " + o[3]);
        Pet[] pa = pets.toArray(new Pet[0]);
        print("23: " + pa[3].id());
      }
    } 
    /*
    16: [Rat, Mouse, Cymric, Pug]
    17: [Rat, Mouse, Mouse, Pug, Cymric, Pug]
    18: false
    19: []
    20: true
    21: [Manx, Cymric, Rat, EgyptianMau]
    22: EgyptianMau
    23: 14
    *///:~
    

    remove()方法可以有移除标号和移除对象,移除对象时重写equals方法,重写hashcode方法。

    在使用下标迭代删除对象时应该注意倒序删除

    //倒序删除元素
    for(int i=list.size()-1;i>=0;i--){
    	if(list.get(i)==3){
    		list.remove(i);
    	}
    }
    System.out.println(list);
    
    //迭代器删除元素
    Iterator<Integer> it=list.iterator();
    	while(it.hasNext()){
    		if(it.next()==3){
    			it.remove();
    		}
            }
    System.out.println(list);
    

    remove()方法源码:

        public boolean remove(Object o) {
            if (o == null) {
                for (int index = 0; index < size; index++)
                    if (elementData[index] == null) {
                        fastRemove(index);
                        return true;
                    }
            } else {
                for (int index = 0; index < size; index++)
                    if (o.equals(elementData[index])) {
                        fastRemove(index);
                        return true;
                    }
            }
            return false;
        }
    
    

    list遍历方法

    //**********三种遍历方式*************
    		for(int i = 0;i<list1.size();i++) {
    			System.out.println(list1.get(i));
    		}//
    		
    		for(String s:list1) {
    			System.out.println(s);
    		}
    		
    		Iterator it = list1.iterator();
    		while(it.hasNext()) {
    			System.out.println(it.next());
    		}
    		
    	}
    
    

    Integer的equal()实现源码

    20200131110439.png

    1.4.2. LinkedList

    20200203215805.png

    LinkedList也和ArrayList一样也实现了基本的list接口,在插入和删除方面比较高效,随机访问方面不如ArrayList。
    以下是特有的方法。

    //: holding/LinkedListFeatures.java
    import typeinfo.pets.*;
    import java.util.*;
    import static net.mindview.util.Print.*;
    
    public class LinkedListFeatures {
      public static void main(String[] args) {
        LinkedList<Pet> pets =
          new LinkedList<Pet>(Pets.arrayList(5));
        print(pets);
        // Identical:
        print("pets.getFirst(): " + pets.getFirst());//返回此列表中的第一个元素。
        print("pets.element(): " + pets.element());//检索但不删除此列表的头(第一个元素)。 
        // Only differs in empty-list behavior:
        print("pets.peek(): " + pets.peek());
        //检索但不删除此列表的头(第一个元素),上面两个方法在List=null时抛出NoSuchElement异常,这个方法会返回null
        // Identical; remove and return the first element:
        print("pets.remove(): " + pets.remove());//在不带参数时,表示删除列表的头第一个元素
        print("pets.removeFirst(): " + pets.removeFirst());//删除列表的头第一个元素
        // Only differs in empty-list behavior:
        print("pets.poll(): " + pets.poll());
        //弹出堆栈中的第一个元素,上面两个方法在List=null时抛出NoSuchElement异常,这个方法会返回null
        print(pets);
        pets.addFirst(new Rat());//将指定的元素追加到此列表的头。
        print("After addFirst(): " + pets);//开头插入指定的元素。
        pets.offer(Pets.randomPet());//将指定的元素添加为此列表的尾部(最后一个元素)。 
        print("After offer(): " + pets);
        pets.add(Pets.randomPet());//将指定的元素追加到此列表的末尾。
        print("After add(): " + pets);
        pets.addLast(new Hamster());//将指定的元素追加到此列表的末尾。
        print("After addLast(): " + pets);
        print("pets.removeLast(): " + pets.removeLast());//删除列表的最后一个元素
      }
    } /* Output:
    [Rat, Manx, Cymric, Mutt, Pug]
    pets.getFirst(): Rat
    pets.element(): Rat
    pets.peek(): Rat
    pets.remove(): Rat
    pets.removeFirst(): Manx
    pets.poll(): Cymric
    [Mutt, Pug]
    After addFirst(): [Rat, Mutt, Pug]
    After offer(): [Rat, Mutt, Pug, Cymric]
    After add(): [Rat, Mutt, Pug, Cymric, Pug]
    After addLast(): [Rat, Mutt, Pug, Cymric, Pug, Hamster]
    pets.removeLast(): Hamster
    *///:~
    

    1.5. Stack(栈)

    :是一种“后进先出的容器”,即最后一个压入栈中的元素,总是第一个出来。

    • LinkedList具有可以实现栈的所有功能的方法,也可以用LinkList创建一个Stack类。
    • 也可以使用java.util包中的stack类。
    import java.util.LinkedList;
     
    public class Stack<T> {
    	private LinkedList<T> storage=new LinkedList<T>();
    	public void push(T t){
    		storage.addFirst(t);在该列表开头插入指定的元素。
    	}//向栈中添加元素
    	public T peek(){
    		return storage.getFirst();//返回此列表中的第一个元素。
    	}//查看栈顶元素
    	public T pop(){
    		return storage.removeFirst();//从此列表中删除并返回第一个元素。
    	}//移除栈顶元素
    	public boolean isEmpty(){
    		return storage.isEmpty();
    	}//判断栈是否为空
    	public String toString(){
    		return storage.toString();
    	}
    }
    

    两种栈的比较

    //: holding/StackCollision.java
    import net.mindview.util.*;
    
    public class StackCollision {
      public static void main(String[] args) {
    
        
        net.mindview.util.Stack<String> stack =
          new net.mindview.util.Stack<String>();
        for(String s : "My dog has fleas".split(" "))
          stack.push(s);
        while(!stack.empty())
          System.out.print(stack.pop() + " ");
        System.out.println();
    
        
        java.util.Stack<String> stack2 =
          new java.util.Stack<String>();
        for(String s : "My dog has fleas".split(" "))
          stack2.push(s);
        while(!stack2.empty())
          System.out.print(stack2.pop() + " ");
      }
    } /* Output:
    fleas has dog My
    fleas has dog My
    *///:~
    

    1.6. Set

    Set不保存重复元素,通过equals(),hashcode()方法判断两个元素是否相同。

    HashSet使用了HASH散列算法,TreeSet使用了红黑树,LinkedHashSet也使用了散列表,

    //HashSet示例,hash输出为无序的:
    //: holding/SetOfInteger.java
    import java.util.*;
    
    public class SetOfInteger {
      public static void main(String[] args) {
        Random rand = new Random(47);
        Set<Integer> intset = new HashSet<Integer>();
        for(int i = 0; i < 10000; i++)
          intset.add(rand.nextInt(30));
        System.out.println(intset);
      }
    } /* Output:
    [15, 8, 23, 16, 7, 22, 9, 21, 6, 1, 29, 14, 24, 4, 19, 26, 11, 18, 3, 12, 27, 17, 2, 13, 28, 20, 25, 10, 5, 0]
    *///:~
    //TreeSet示例,treeset为有序的:
    //: holding/SortedSetOfInteger.java
    import java.util.*;
    
    public class SortedSetOfInteger {
      public static void main(String[] args) {
        Random rand = new Random(47);
        SortedSet<Integer> intset = new TreeSet<Integer>();
        for(int i = 0; i < 10000; i++)
          intset.add(rand.nextInt(30));
        System.out.println(intset);
      }
    } /* Output:
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29]
    *///:~
    

    Set常用操作之一就是使用contains用来测试归属性

    public class hashset {
    	private int name;
    	private int age;
    	public int hashCode() {
    		
    		return Objects.hash(name,age);
    		
    	}
    	public static void main(String[] args) {
    		HashSet<String> set = new HashSet<String>();
    		set.size();
    		set.clear();
    		set.contains("aaa");
    		set.remove("aas");
    		set.add("122");
    		set.add("月月");
    		set.add("122");//String类重写了equal()方法
    		set.add("月月");//
    		
    		//System.out.println(null==null);
    		//********************遍历**********************
    		
    		for(String s:set) {
    			System.out.println(s);
    		}
    		Iterator it = set.iterator();
    		while(it.hasNext()) {
    			System.out.println(it.next());
    		}
    	}
    }
    
    

    1.7. Map

    对于HashMap而言,key是唯一的,不可以重复的。所以,以相同的key 把不同的value插入到 Map中会导致旧元素被覆盖,只留下最后插入的元素。

    //: holding/Statistics.java
    // Simple demonstration of HashMap.
    import java.util.*;
    
    public class Statistics {
      public static void main(String[] args) {
        Random rand = new Random(47);
        Map<Integer,Integer> m =new HashMap<Integer,Integer>();
        for(int i = 0; i < 100; i++) {
          // Produce a number between 0 and 20:
          int r = rand.nextInt(20);
          Integer freq = m.get(r);
          m.put(r, freq == null ? 1 : freq + 1);
        }
        System.out.println(m.get(1));//根据key查找value
        System.out.println(m.containsKey(1));//判断是否包含这个key
        System.out.println(m.containsValue(5));//判断是否有这个value值
        System.out.println(m);
      }
    } /* Output:
    6
    true
    true
    {0=4, 1=6, 2=9, 3=3, 4=6, 5=3, 6=5, 7=4, 8=7, 9=6, 10=5, 11=3, 12=3, 13=5, 14=6, 15=4, 16=5, 17=5, 18=8, 19=3}
    *///:~
    
    

    Map与list和其他的Collection一样,可以很容易的扩展到多维,可以将容器组合起来形成强大的数据结构,例如可以生成一个人有多个宠物的数据结构,如Map<Person,List>:

    //: holding/MapOfList.java
    package holding;
    import typeinfo.pets.*;
    import java.util.*;
    import static net.mindview.util.Print.*;
    
    public class MapOfList {
      public static Map<Person, List<? extends Pet>>
        petPeople = new HashMap<Person, List<? extends Pet>>();
      static {
        petPeople.put(new Person("Dawn"),
          Arrays.asList(new Cymric("Molly"),new Mutt("Spot")));
    
        petPeople.put(new Person("Kate"),
          Arrays.asList(new Cat("Shackleton"),
            new Cat("Elsie May"), new Dog("Margrett")));
    
        petPeople.put(new Person("Marilyn"),
          Arrays.asList(
           new Pug("Louie aka Louis Snorkelstein Dupree"),
           new Cat("Stanford aka Stinky el Negro"),
           new Cat("Pinkola")));
    
        petPeople.put(new Person("Luke"),
          Arrays.asList(new Rat("Fuzzy"), new Rat("Fizzy")));
    
        petPeople.put(new Person("Isaac"),
          Arrays.asList(new Rat("Freckly")));
      }
      public static void main(String[] args) {
        print("People: " + petPeople.keySet());
        //People: [Person Luke, Person Marilyn, Person Isaac, Person Dawn, Person Kate]
        print("Pets: " + petPeople.values());
        //Pets: [[Rat Fuzzy, Rat Fizzy], [Pug Louie aka Louis Snorkelstein Dupree, Cat Stanford aka Stinky el Negro, Cat Pinkola], [Rat Freckly], [Cymric Molly, Mutt Spot], [Cat Shackleton, Cat Elsie May, Dog Margrett]]
        for(Person person : petPeople.keySet()) {
          print(person + " has:");
          for(Pet pet : petPeople.get(person))
            print("    " + pet);
        /*
        Person Luke has:
        Rat Fuzzy
        Rat Fizzy
    Person Marilyn has:
        Pug Louie aka Louis Snorkelstein Dupree
        Cat Stanford aka Stinky el Negro
        Cat Pinkola
    Person Isaac has:
        Rat Freckly
    Person Dawn has:
        Cymric Molly
        Mutt Spot
    Person Kate has:
        Cat Shackleton
        Cat Elsie May
        Dog Margrett
        */
        }
      }
    } 
    

    map可以通过KeySet()方法来返回Key的Set集合,

    20200203150337.png

    也可以通过value()方法返回其value的Collection视图,可用在for-each中遍历

    20200203150425.png

    1.8. Queue(队列)

    20200203215805.png

    队列是一个先进先出的容器,LinkedList提供方式支持队列的行为实现了Queue的接口:

    它在LinkedList的基础上添加了element(),offer(),peek(),poll(),和remove()方法,可以使其成为一个Queue的实现。

    //: holding/QueueDemo.java
    // Upcasting to a Queue from a LinkedList.
    import java.util.*;
    
    public class QueueDemo {
      public static void printQ(Queue queue) {
        while(queue.peek() != null)
          System.out.print(queue.remove() + " ");//移除并返回队列头
          System.out.print(queue.poll() + " ");//移除并返回队列头
          System.out.print(queue.element() + " ");//  不移除并返回队列头
          System.out.print(queue.peek() + " ");//  不移除并返回队列头
    
        System.out.println();
      }
      public static void main(String[] args) {
        Queue<Integer> queue = new LinkedList<Integer>();
        Random rand = new Random(47);
        for(int i = 0; i < 10; i++)
          queue.offer(rand.nextInt(i + 10));
        printQ(queue);
        Queue<Character> qc = new LinkedList<Character>();
        for(char c : "Brontosaurus".toCharArray())
          qc.offer(c);//将指定的元素添加为此列表的尾部(最后一个元素)。
        printQ(qc);
      }
    } /* Output:
    8 1 1 1 5 14 3 1 0 1
    B r o n t o s a u r u s
    *///:~
    

    1.8.1. priorityQueue队列

    先进先出队列是最基本的队列规则,即下一个元素应该是等待时间最长的元素。

    优先级队列的下一个弹出对象是最需要的元素(具有最高的优先级),所以在调用PriorityQueue中的offer()方法时,这个对象会在队列中被排序,默认的排序为自然排序,但可以通过Comparator比较器来修改顺序。

    1.9. 迭代器

    Iterator是一种设计模式,java的Iterator只能单向移动,这个Iterator只能用来:

    • 使用方法Iterater()返回一个Iterator对象,Iterator准备返回序列的第一个元素。
    • 使用next()获取序列中的下一个元素。
    • 使用hasNext()判断序列中是否有下一个元素。
    • 使用remove()将迭代器返回的元素删除
    //: holding/SimpleIteration.java
    import typeinfo.pets.*;
    import java.util.*;
    
    public class SimpleIteration {
      public static void main(String[] args) {
        List<Pet> pets = Pets.arrayList(12);
        Iterator<Pet> it = pets.iterator();
        while(it.hasNext()) {//判断是否存在下一个元素
          Pet p = it.next();//获取返回的元素
          System.out.print(p.id() + ":" + p + " ");
        }
        System.out.println();
        // A simpler approach, when possible:
        for(Pet p : pets)
          System.out.print(p.id() + ":" + p + " ");
        System.out.println();	
        // An Iterator can also remove elements:
        it = pets.iterator();
        for(int i = 0; i < 6; i++) {
          it.next();//获取返回的元素
          it.remove();//将返回的元素删除
        }
        System.out.println(pets);
      }
    } /* Output:
    0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug 7:Manx 8:Cymric 9:Rat 10:EgyptianMau 11:Hamster
    0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug 7:Manx 8:Cymric 9:Rat 10:EgyptianMau 11:Hamster
    [Pug, Manx, Cymric, Rat, EgyptianMau, Hamster]
    *///:~
    

    set和list都可以使用这种方法进行遍历,map要复杂一点

    //: holding/CrossContainerIteration.java
    import typeinfo.pets.*;
    import java.util.*;
    
    public class CrossContainerIteration {
      public static void display(Iterator<Pet> it) {
        while(it.hasNext()) {
          Pet p = it.next();
          System.out.print(p.id() + ":" + p + " ");
        }
        System.out.println();
      }	
      public static void main(String[] args) {
        ArrayList<Pet> pets = Pets.arrayList(8);
        LinkedList<Pet> petsLL = new LinkedList<Pet>(pets);
        HashSet<Pet> petsHS = new HashSet<Pet>(pets);
        TreeSet<Pet> petsTS = new TreeSet<Pet>(pets);
        display(pets.iterator());
        display(petsLL.iterator());
        display(petsHS.iterator());
        display(petsTS.iterator());
      }
    } /* Output:
    0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug 7:Manx
    0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug 7:Manx
    4:Pug 6:Pug 3:Mutt 1:Manx 5:Cymric 7:Manx 2:Cymric 0:Rat
    5:Cymric 2:Cymric 7:Manx 1:Manx 3:Mutt 6:Pug 4:Pug 0:Rat
    *///:~
    

    ListIterator

    ListIterator是一个更强大的子类型提供了双向访问的功能,Iterator只能向前移动,但是ListIterator可以双向移动,还可以产生迭代子的前一个位置或者后一个位置的索引,

    还可以像remove()方法一样,使用set()方法来对该元素进行替换,

    并且可以使用listiterator(n)方法让迭代子从下标为n开始迭代。

    //: holding/ListIteration.java
    import typeinfo.pets.*;
    import java.util.*;
    
    public class ListIteration {
      public static void main(String[] args) {
        List<Pet> pets = Pets.arrayList(8);
        ListIterator<Pet> it = pets.listIterator();
        while(it.hasNext())
          System.out.print(it.next() + ", " + it.nextIndex() +
            ", " + it.previousIndex() + "; ");
        System.out.println();
        // Backwards:
        while(it.hasPrevious())
          System.out.print(it.previous().id() + " ");
        System.out.println();
        System.out.println(pets);	
        it = pets.listIterator(3);
        while(it.hasNext()) {
          it.next();
          it.set(Pets.randomPet());
        }
        System.out.println(pets);
      }
    } /* Output:
    Rat, 1, 0; Manx, 2, 1; Cymric, 3, 2; Mutt, 4, 3; Pug, 5, 4; Cymric, 6, 5; Pug, 7, 6; Manx, 8, 7;
    7 6 5 4 3 2 1 0
    [Rat, Manx, Cymric, Mutt, Pug, Cymric, Pug, Manx]
    [Rat, Manx, Cymric, Cymric, Rat, EgyptianMau, Hamster, EgyptianMau]
    *///:~
    
    
  • 相关阅读:
    使用Modelsim对Nios II系统进行系统级仿真
    电视相关知识学习
    SAD和SATD的区别[摘]
    vim自动补全括号的最好方法
    vim sinppets插件介绍
    在centos下安装开发环境
    初始化以及动态设置Edit控件的背景及字体颜色
    CTreeCtrl SetItemData 释放问题
    C#4.0 新特性 匿名方法,lambds
    对象序列化Serialization与Deserialize方法进行反序列化
  • 原文地址:https://www.cnblogs.com/innndown/p/12392110.html
Copyright © 2020-2023  润新知