美文网首页
11.持有对象

11.持有对象

作者: 云木杉 | 来源:发表于2019-03-04 10:02 被阅读0次
    image.png

    1.泛型和类型安全的容器

    • 编译器将不允许你向容器里插入不正确的类型。

    2.基本概念

      1. Collection 一个独立元素的序列,这些元素都服从一条或多条规则。List必须按照插入顺序保存元素,而Set不能有重复元素。Queue按照排队规则来确定对象产生的顺序。
      1. Map一组成对的“键值对”对象,允许你使用键来查找值。
    
    public class SimpleCollection {
      public static void main(String[] args) {
        Collection<Integer> c = new ArrayList<Integer>();
        for(int i = 0; i < 10; I++)
          c.add(i); // Autoboxing
        for(Integer i : c)
          System.out.print(i + ", ");
      }
    } /* Output:
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
    *///:~
    

    3.添加一组元素

    Arrays.asList()方法接受一个数组或是一个用逗号隔开分隔的元素列表,并将其转换为一个List对象。Collections.addAll()方法接受一个Collection对象,以及一个数组或用逗号分隔的列表,将其添加到Collection中。

    class Snow {}
    class Crusty extends Snow {}
    class Slush extends Snow {}
    class Powder extends Snow {}
    
    class Light extends Powder {}
    class Heavy extends Powder {}
    
    public class AsListInference {
      public static void main(String[] args) {
        List<Snow> snow1 = Arrays.asList(
          new Crusty(), new Slush(), new Powder());
    
        // Won't compile: 当Arrays.asList里都是Powder类时,声明为List<Powder>
        // List<Snow> snow2 = Arrays.asList(
        //   new Light(), new Heavy());
        // Compiler says:
        // found   : java.util.List<Powder>
        // required: java.util.List<Snow>
    
        // 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());
      }
    } ///:~
    
    
    public class AddingGroups {
      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 };
        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.
      }
    } ///:~
    

    4.容器的打印

    Collection每个槽中只保存一个元素

    • List 以特定顺序保存一组对象
    • Set 元素不能重复
      HashSet是最快的获取元素方式。如果存储顺序很重要,那么可以使用TreeSet,它按照比较结果的升序保存对象,或者使用LinkedHashSet,它按照被添加的顺序保存对象。
    • Queue 只允许在容器的一端插入对象,并从另一端移除对象
    • map在每个槽找那个保存两个对象,即键与值;
      同理,HashMap是最快的获取元素方式,如果存储顺序很重要,使用TreeMap,它按照比较结果的升序保存对象,或者使用LinkedHashSet,它按照被添加的顺序保存对象。
    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}
    *///:~
    

    5. List

    List承诺可以将元素维护在特定的序列中。

    ArrayList

    • 以数组实现。节约控件,但数组容量有限制。超出限制会增加50%容量。默认第一次插入元素时创建大小为10的数组。
    • 按数组下标访问元素 get set方法的性能更高,这是数组的基本优势
    • 直接在数组末尾加入元素 -add()的性能也高,但如果按照下标插入add(),删除remove(),则要用System.arraycopy()来移动部分受影响的元素(角标会发生变化),这是基本劣势
    public static void main(String[] args) {
            Random rand = new Random(47);
            List<String> pp = Arrays.asList("abc", "bcd", "cde", "def");
            List<String> pets = new ArrayList<>(pp);
            print("1: " + pets);
            String p = pets.get(2);
            print("4: " + p + " " + pets.indexOf(p));
            String cymric = new String();
            print("5: " + pets.indexOf(cymric));
            print("6: " + pets.remove(cymric));
            // Must be the exact object:
            print("7: " + pets.remove(p));
            print("8: " + pets);
            pets.add(3, new String("efg")); // Insert at an index
            print("9: " + pets);
            List<String> sub = pets.subList(1, 4);
            print("subList: " + sub);
            print("10: " + pets.containsAll(sub));
            Collections.sort(sub); // In-place sort
            print("sorted subList: " + sub);
    //         Order is not important in containsAll():
            print("11: " + pets.containsAll(sub));
            Collections.shuffle(sub, rand); // Mix it up
            print("shuffled subList: " + sub);
            print("12: " + pets.containsAll(sub));
            List<String> copy = new ArrayList<String>(pets);
            sub = Arrays.asList(pets.get(1), pets.get(4));
            print("sub: " + sub);
            copy.retainAll(sub);
            print("13: " + copy);
            copy = new ArrayList<String>(pets); // Get a fresh copy
            copy.remove(2); // Remove by index
            print("14: " + copy);
            copy.removeAll(sub); // Only removes exact objects
            print("15: " + copy);
            copy.set(1, new String()); // 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());
            print("21: " + pets);
            Object[] o = pets.toArray();
        }
    

    6.迭代器

    迭代器能够将遍历序列的操作与序列底层的结构分离。正由于此,我们常说迭代器统一了对容器的访问方式。

    public static void main(String[] args) {
            List<String> pp = Arrays.asList("admin", "what this", "spaces", "feature","uimian","who that",
                    "nonoN");
            List<String> pets = new ArrayList<>(pp);
            Iterator<String> it = pets.iterator();
            while (it.hasNext()) {
                String p = it.next();
                System.out.print("" + p + " ");
            }
            System.out.println();
            // A simpler approach, when possible:
            for (String p : pets)
                System.out.print("" + 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);
        }
    

    ListIterator是一个更加强大的Iterator的子类型,它只能用于各种list类的访问。尽管Iterator只能向前移动,但是ListIterator可以双向移动。

    public static void main(String[] args) {
            List<String> pp = Arrays.asList("admin", "what this", "spaces", "feature", "uimian", "who that",
                    "nonoN", "open");
            List<String> pets = new ArrayList<>(pp);
            ListIterator<String> 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() + "- ");
            }
            System.out.println();
            System.out.println(pets);
            it = pets.listIterator(3);
            while (it.hasNext()) {
                it.next();
                it.set("");
            }
            System.out.println(pets);
        }
    

    7. LinkedList

    以双向链表实现。链表无容量限制,但双向链表本身使用了更多控件,也需要额外的链表指针操作。按下标访问元素—get(i)/set(i,e) 要悲剧的遍历链表将指针移动到位(如果i>数组大小的一半,会从末尾移起)。

    LinkedList是一个简单的数据结构,与ArrayList不同的是,他是基于链表实现的。

    public static void main(String[] args) {
        List<String> pp = Arrays.asList("admin", "what this", "spaces", "feature","uimian","who that",
                "nonoN");
        LinkedList<String> pets =
          new LinkedList<>(pp);
        print(pets);
        // Identical:
        print("pets.getFirst(): " + pets.getFirst());
        print("pets.element(): " + pets.element());
        // Only differs in empty-list behavior:
        print("pets.peek(): " + pets.peek());
        // 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());
        print(pets);
        pets.addFirst(new String("miandiin"));
        print("After addFirst(): " + pets);
        print("After offer(): " + pets);
        print("After add(): " + pets);
        pets.addLast(new String("andiin"));
        print("After addLast(): " + pets);
        print("pets.removeLast(): " + pets.removeLast());
      }
    

    8.Set

    Set不保存重复的元素。

    public static void main(String[] args) {
            Set<String> set1 = new HashSet<String>();
            Collections.addAll(set1,
                    "A B C D E F G h H I J K L".split(" "));
            set1.add("M");
            print("H: " + set1.contains("H"));
            print("N: " + set1.contains("N"));
            Set<String> set2 = new HashSet<String>();
            Collections.addAll(set2, "h H I J K L".split(" "));
            print("set2 in set1: " + set1.containsAll(set2));
            set1.remove("H");
            print("set1: " + set1);
            print("set2 in set1: " + set1.containsAll(set2));
            set1.removeAll(set2);
            print("set2 removed from set1: " + set1);
            Collections.addAll(set1, "X Y Z".split(" "));
            print("'X Y Z' added to set1: " + set1);
        }
    

    9.Map

    Map是一种将对象映射到其他对象的能力

    HashMap
    HashMap是基于Map接口的实现,存储键值对时,它可以接收null的键值,是非同步的,HashMap存储着Entry(hash,key,value,next)对象。

    ***LinkedHashMap
    LinkedHashMap是Hash表和链表的实现,并且依靠着双向链表保证了迭代顺序是插入的顺序。

    public static Map<String, List<String>>
        petPeople = new HashMap<String, List<String>>();
      static {
        petPeople.put(new String("Dawn"),
          Arrays.asList(new String("Molly"),new String("Spot")));
        petPeople.put(new String("Kate"),
          Arrays.asList(new String("Shackleton"),
            new String("Elsie May"), new String("Margrett")));
        petPeople.put(new String("Marilyn"),
          Arrays.asList(
           new String("Louie aka Louis Snorkelstein Dupree"),
           new String("Stanford aka Stinky el Negro"),
           new String("Pinkola")));
        petPeople.put(new String("Luke"),
          Arrays.asList(new String("Fuzzy"), new String("Fizzy")));
        petPeople.put(new String("Isaac"),
          Arrays.asList(new String("Freckly")));
      }
      public static void main(String[] args) {
        print("People: " + petPeople.keySet());
        print("Pets: " + petPeople.values());
        for(String person : petPeople.keySet()) {
          print(person + " has:");
          for(String pet : petPeople.get(person))
            print("    " + pet);
        }
      }
    } /* Output:    
    People: [Person Luke, Person Marilyn, Person Isaac, Person Dawn, Person Kate]
    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]]
    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
    *///:~
    

    10.Queue

    队列是一个典型的先进先出的容器。即从容器的一端放入事物,从另一端取出,并且事物放入容器的顺序与取出的顺序是相同的。子弹头儿原理。

    • offer()方法是与Queue相关的方法之一,它在允许的情况下,将一个元素插入到队尾,或者返回false
    • peek()和element()都将在不移除的情况下返回队头,但peek()方法在队列为空时返回null,而element()会抛出NoSuchElementException异常。
    • poll()和remove()方法将移除并返回队头,但poll在队列为空时返回null,而remove()会抛出NoSuchElementException。
    public class QueueDemo {
      public static void printQ(Queue queue) {
        while(queue.peek() != null)
          System.out.print(queue.remove() + " ");
        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++){
          System.out.println(rand.nextInt(i + 10));
          queue.offer(rand.nextInt(i + 10));
    //      boolean offer = queue.offer(i);
        }
        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
    *///:~
    

    10.Collection和Iterator

    Collection是描述所有序列容器的共性的根接口,它可能被认为是一个附属接口,即因为要表示其他若干个接口的共性而出现的接口。

    public class CollectionSequence extends AbstractCollection<String> {
    
        private String[] pets = new String[]{"b", "c", "a", "d", "g", "e", "f", "h"};
    
        @NonNull
        @Override
        public Iterator<String> iterator() {
                return new Iterator<String>() {
                    private int index = 0;
    
                    public boolean hasNext() {
                        return index < pets.length;
                    }
    
                    public String next() {
                        return pets[index++];
                    }
    
                    public void remove() { // Not implemented
                        throw new UnsupportedOperationException();
                    }
                };
        }
    
        public int size() {
            return pets.length;
        }
    
    
        public static void main(String[] args) {
            CollectionSequence c = new CollectionSequence();
            InterfaceVsIterator.display(c);
            InterfaceVsIterator.display(c.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
    *///:~
    

    11.Foreach与迭代器

    public class IterableClass implements Iterable<String> {
      protected String[] words = ("And that is how " +
        "we know the Earth to be banana-shaped.").split(" ");
      public Iterator<String> iterator() {
        return new Iterator<String>() {
          private int index = 0;
          public boolean hasNext() {
            return index < words.length;
          }
          public String next() { return words[index++]; }
          public void remove() { // Not implemented
            throw new UnsupportedOperationException();
          }
        };
      } 
      public static void main(String[] args) {
        for(String s : new IterableClass())
          System.out.print(s + " ");
      }
    } /* Output:
    And that is how we know the Earth to be banana-shaped.
    *///:~
    

    到这里持有对象就告一段落了,大部分粘贴出的是编程思想里的案例,也比较方便复习。

    相关文章

      网友评论

          本文标题:11.持有对象

          本文链接:https://www.haomeiwen.com/subject/fzfbuqtx.html