To solve the general programming problem, you need to create any number of objects, anytime, anywhere. So you can't rely on creating a named reference to hold each one of your objects.

  Java has several ways to hold objects:

    1. the compiler-supported type is the array

      fixed-size

    2. container classes (or called collection classes, Java library uses the name Collection to refer to a particular subset of the library)

      The java.util library has a reasonably complete set of container classes to solve this problem, The base types of which are List, Set,Queue, and Map.

Generics and type-safe containers

  ArrayList

  ArrayList<Apple>

Basic concepts

  The Java container library divides into two distinct concepts, expressed as the basic interfaces:

    1. Collection: a sequence of individual elements with one or more rules applied to them. A List must hold the elements in the way that they were inserted, a Set cannot have duplicate elements, and a Queue produces the elements in the order determined by a queuing discipline

    2. Map: a group of key-value object pairs, allowing you to look up a value using a key.

  Although it's not always possible, ideally you'll write most of your code to talk to these interfaces, and the only place where you'll specify the precise type you're using is at the point of creation.

  List<Apple> apples = new ArrayList<Apple>();

  The intent of using the interface is that if you decide you want to change your implementation, all you need to do is changed it at the point of creation.

  List<Apple> apples = new LinkedList<Apple>();

  But some concrete classes have additional functionality, if you need to use those methods, you won't be able to upcase to the more general interface.

Adding groups of elements

  public class AddingGroups {

    public static void main(String[] args) {

      Collection<Integer> collection = new ArrayList<Integer>(Arrays.asList(1,2,3));

      Integer[] moreInts = {4,5,6};

      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 (Arrays$ArrayList) cannot be resized.

  However, Collections.addAll() runs much faster, and it's just as easy to construct the Collection with no elements and then call Collections.addAll(), so this is the preferred approach.

  Collection.addAll() member method can only take an argument of another Collection object, so it is not as flexible as Arrays.asList() or Collections.addAll()

  It’s also possible to use the output of Arrays.asList( ) directly, as a List, but the underlying representation in this case is the array, which cannot be resized. If you try to add( ) or delete( ) elements in such a list, that would attempt to change the size of an array, so you’ll get an "Unsupported Operation" error at run time. 

  A limitation of Arrays.asList( ) is that it takes a best guess about the resulting type of the List, and doesn’t pay attention to what you’re assigning it to. Sometimes this can cause a problem:

  class Snow {}
  class Powder extends Snow {}
  class Light extends Powder {}
  class Heavy extends Powder {}
  class Crusty extends Snow {}
  class Slush extends Snow {}
  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());
    // 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());
    }
  }

  When trying to create snow2, Arrays.asList() only has types of Powder, so it creates a List<Power> rather than a List<Snow>, whereas Collections.addAll() works fine because it knows from the first argument what the target type is.

  As you can see from the creating of snow4, it's possible to insert a "hint" in the middle of Arrays.asList(), to tell the compiler what the actual target type should be for the resulting List type produced by Arrays.asList(). This is called an explicit type argument specification.

Printing containers

  You must use Arrays.toString() to produce a printable representation of an array,but the containers print nicely without any help.

List

  There are two types of List:

    1. The basic ArrayList, which excels a randomly accessing elements, but is slower when inserting and removing element in the middle of a List.

    2. The LinkedList, which provides optimal sequential access, with imexpensive insertions and deletions from the middle of the List. A LinkedList is relatively show for random access, but it has a larger feature set than the ArrayList.

    

    

  

    List.subList( ) produces a list backed by the original list. Therefore, changes in the returned list are reflected in the original list, and vice versa.

    The retainAll( ) method is effectively a "set intersection" operation, in this case keeping all the elements in copy that are also in sub. Again, the resulting behavior depends on the equals( ) method.

    convert any Collection to an array using toArray( ). This is an overloaded method; the no-argument version returns an array of Object, but if you pass an array of the target type to the overloaded version, it will produce an array of the type specified (assuming it passes type checking). If the argument array is too small to hold all the objects in the List (as is the case here), to Array( ) will create a new array of the appropriate size.

  Object[] o = pets.toArray();
  Pet[] pa = pets.toArray(new Pet[0]);

Iterator

  It can be used on different type of containers without rewriting that code.

  An iterator is an object whose job is to move through a sequence and select each object in that sequence without the client programmer knowing or caring about the underlying structure of that sequence.

  An iteratro is usually what's called a lightweight object: one that's cheap to create. For that reason, you'll often find seemingly strange constraints for iterators.

  There's not much you can do with an Iterator except:

    iterator(): get an Iterator

    next(): get the next object

    hasNext(): see if there are any more object in the sequence

    remove(): remove the last element returned by the iterator

  If you're simply moving forward through the List and not trying to modify the List object iteself, you can see that the foreach syntax is more succient

  An Iterator will alos remove the last element produced by next(), which means you must call next() before you call remove().

  The power of the Iterator: the ability to separate the operation of traversing a sequence from the underlying structure of that sequence. For this reason, we sometimes say that iterators unify access to containers.

  ListIterator

  The ListIterator is a more powerful subtype of Iterator that is produced only by List classes.

  While Iterator can only move forward, ListIterator is bidirectional.

  It can also produce the indexed of the next and previous elements relative to where the iterator is pointing in the list

  It can replace the last element that it visited using the set() method.

  listIterator() : produce a ListIterator that points to the beginning of the List

  listIterator(n): create a ListIterator that starts out pointing to an index n in the list

  next(): 后移

  previous():前移

  hasPrevious():

  hasNext():

  previousIndex(): 之前next()返回对象的index

  nextIndex():序列中下一个对象的index

LinkedList

  efficiently insertion and removal in the middle of the list

  less efficient for random-access operations.

  LinkedList also adds methods that allow it to be used as a stack a Queue or a double-ended queue (deque).

  Some of these methods are aliases or slight variations of each other, to produces names that are more familiar within the context of a particular usage. For example:

  getFirst()、element(): return the head (first element) of the list withou removing it, and throw NoSuchElementException if the List is empty.

  peek(): a slight variation of getFirst() and element() that returns null if the list is empty.

  removeFirst()、remove(): remove and return the head of the list, and throw NoSuchElementException for an empty list,

  poll(): a slight variation that return null if this list is empty.

  addFirst(): inserts an element at the beginning of the list

  offer()、add()、addLast(): add an element to the tail (end) of a list.

  removeLast():  removes and returns the last element of the list.

Stack

  last-in,first-out (LIFO)

  a pushdown stack

  LinkedList has methods that directly implement stack functionality, so you can also just use a LinkedList rather than making a stack class. However, a stack class can sometimes tell the story better.

Set

  A Set refuses to hold more than one instance of each object value.

  HashSet : optimized for rapid lookup

  Set has the same interface as Collection. The Set is exactly a Collection--it just has different behavior.

  HashSet: uses hashing function for speed

  TreeSet: keeps elements sorted into a red-black tree data structure.

  LinkedHashSet: use hashing for lookup speed, but appears to maintain elements in insertion order using a linked list.  

Map

  A Map can return a Set of its keys, a Collection of its values, or a Set of its pairs.

Queue

  first-in,first-out (FIFO)

  Queues are commonly used as a way to reliably transfer objects from one area of a program to another.

  Queues are especially important in concurrent programming.

  LinkedList has methods to support queue behavior and it implements the Queue interface, so a LinkedList can be used as a Queue implementation.

  PriorityQueue

  FIFO describes the most typical queuing discipline. A queuing discipline is what decides, given a group of elements in the queue, which one goes next. FIFO says that the next element should be the one that was waiting the longest.

  A priority queue says that the element that goes next is the one with the greatest need (the highest priority).

  When you offer() an object onto a PriorityQueue, that object is sorted into the queue. The default sorting uses the natural order of the objects in the queue, but you can modify the order by providing your own Comparator. The PriorityQueue ensures that when you call peek(), poll() or remove(), the element you get will be the one with the highest priority.

Collection vs. Interator

  Collection: appeared because of commonality between other interfaces

  AbstractCollection: provides a default implementation for a Collection, so that you can create a new subtype of AbstractCollection without unnecessary code duplication

  In Java, implementing Collection also means providing an iterator method.

  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 display (Collection<Pet> pets) {

    for (Pet p: pets)

      System.out.print(p.id() + ":" + p + " ");

    System.out.println();

  }

  In this case the two approaches come up even. In fact, Collection pulls ahead a bit because it is Iterable, and so in the implementation of display(Collection) the foreach construct can be used, which makes the code a little cleaner.

  Producing an Iterator is the least-coupled way of connecting a sequence to a method that consumes that sequence, and puts far fewer constraints on the sequence class than does implementing Collection.

Foreach and iterators

  Java SE5 introduced a new interface called Iterable which contains an iterator() method to produce an Iterator, and the Iterable interface is what foreach uses to move through a sequence.

  A foreach statement works with an array or anything Iterable, but that doesn't mean that an array is automatically an Iterable.

  The Adapter Method idiom  

class ReversibleArrayList<T> extends ArrayList<T> {
  public ReversibleArrayList(Collection<T> c) { super(c); }
  public Iterable<T> reversed() {
    return new Iterable<T>() {
      public Iterator<T> iterator() {
        return new Iterator<T>() {
          int current = size() - 1;
          public boolean hasNext() { return current > -1; }
          public T next() { return get(current--); }
          public void remove() { // Not implemented
            throw new UnsupportedOperationException();
          }
        };
      }
    };
  }
}
public class AdapterMethodIdiom {
  public static void main(String[] args) {
    ReversibleArrayList<String> ral =
      new ReversibleArrayList<String>(
        Arrays.asList("To be or not to be".split(" ")));
    // Grabs the ordinary iterator via iterator():
    for(String s : ral)
      System.out.print(s + " ");
    System.out.println();
    // Hand it the Iterable of your choice

    for(String s : ral.reversed())
      System.out.print(s + " ");
  }
} /* Output:
To be or not to be
be to not or be To

*/

  

public class ModifyingArraysAsList {
  public static void main(String[] args) {

    Random rand = new Random(47);
    Integer[] ia = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    List<Integer> list1 =
      new ArrayList<Integer>(Arrays.asList(ia));
    System.out.println("Before shuffling: " + list1);
    Collections.shuffle(list1, rand);
    System.out.println("After shuffling: " + list1);
    System.out.println("array: " + Arrays.toString(ia));
    List<Integer> list2 = Arrays.asList(ia);
    System.out.println("Before shuffling: " + list2);
    Collections.shuffle(list2, rand);
    System.out.println("After shuffling: " + list2);
    System.out.println("array: " + Arrays.toString(ia));
  }
} /* Output:
Before shuffling: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
After shuffling: [4, 6, 3, 1, 8, 7, 2, 5, 10, 9]
array: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Before shuffling: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
After shuffling: [9, 1, 6, 3, 7, 2, 5, 10, 4, 8]
array: [9, 1, 6, 3, 7, 2, 5, 10, 4, 8]
*/

Summary

  Java provides a number of ways to hold objects:

    1. array: holds objects of a known type,can be multidimensional, can hold primitived. However, its size cannot be changed once you create it. 

    2. Collection: hold single elements, automatically resize, won't hold primitives

    3. Map: holds associated pairs, automatically resize, won't hold primitives

    4. Like an array, a List also associated numerical indexes to objects--thus,arrays and Lists are ordered containers.

    5. The behavior of Queues and stacks is provided via the LinkedList

    6. A Map is a way to associate not integral values, but objects with other objects. HashMaps are designed for rapid access, whereas a TreeMap keeps its keys in sorted order, and thus is not as fast as a HashMap. A LinkedHashMap keeps its elements in insertion order, but provides rapid access with hashing.

    7. A Set only accepts one of each type of object. HashSets provide maximally fast lookups, whereas TreeSets keep the elements in sorted order. LinkedHashSets keep elements in insertion order.

    8. There’s no need to use the legacy classes Vector, Hashtable, and Stack in new code.

Thinking in Java,Fourth Edition(Java 编程思想,第四版)学习笔记(十一)之Holding Your Objects的更多相关文章

  1. Thinking in Java,Fourth Edition(Java 编程思想,第四版)学习笔记(二)之Introduction to Objects

    The genesis of the computer revolution was a machine. The genesis of out programming languages thus ...

  2. Thinking in Java,Fourth Edition(Java 编程思想,第四版)学习笔记(七)之Access Control

    Access control ( or implementation hiding) is about "not getting it right the first time." ...

  3. Thinking in Java,Fourth Edition(Java 编程思想,第四版)学习笔记(六)之Initialization & Cleanup

    Two of these safety issues are initialization and cleanup. initialization -> bug cleanup -> ru ...

  4. Thinking in Java,Fourth Edition(Java 编程思想,第四版)学习笔记(十三)之Strings

    Immutable Strings Objects of the String class are immutable. If you examine the JDK documentation fo ...

  5. Thinking in Java,Fourth Edition(Java 编程思想,第四版)学习笔记(十四)之Type Information

    Runtime type information (RTTI) allow you to discover and use type information while a program is ru ...

  6. Thinking in Java,Fourth Edition(Java 编程思想,第四版)学习笔记(十二)之Error Handling with Exceptions

    The ideal time to catch an error is at compile time, before you even try to run the program. However ...

  7. Thinking in Java,Fourth Edition(Java 编程思想,第四版)学习笔记(十)之Inner Classes

    The inner class is a valuable feature because it allows you to group classes that logically belong t ...

  8. Thinking in Java,Fourth Edition(Java 编程思想,第四版)学习笔记(九)之Interfaces

    Interfaces and abstract classes provide more structured way to separate interface from implementatio ...

  9. Thinking in Java,Fourth Edition(Java 编程思想,第四版)学习笔记(八)之Polymorphism

    Polymorphism is the third essential feature of an object-oriented programming language,after data ab ...

随机推荐

  1. 【面试QA-基本模型】LSTM

    目录 为什么传统 CNN 适用于 CV 任务,RNN 适用于 NLP 任务 RNN 原理 LSTM 原理 GRU 原理 RNN BPTT LSTM 如何解决 RNN 的梯度消失问题 怎样增加 LSTM ...

  2. 洛谷1880 区间dp+记忆化搜索 合并石子

    题目网址:https://www.luogu.com.cn/problem/P1880 题意是:给定一个序列,最小规则是相邻两个值的合并,开销是他们的和,将整个序列合并成一个值的情况下,求解该值的最小 ...

  3. 【Excel使用技巧】vlookup函数

    背景 前不久开发了一个运营小工具,运营人员上传一个id的列表,即可导出对应id的额外数据.需求本身不复杂,很快就开发完了,但上线后,运营反馈了一个问题,导出后的数据跟导出之前的数据顺序不一致. 经过沟 ...

  4. 李宏毅老师机器学习课程笔记_ML Lecture 1: 回归案例研究

    引言: 最近开始学习"机器学习",早就听说祖国宝岛的李宏毅老师的大名,一直没有时间看他的系列课程.今天听了一课,感觉非常棒,通俗易懂,而又能够抓住重点,中间还能加上一些很有趣的例子 ...

  5. Redis总结--【持续更新】

    # 什么是Redis? Redis 是完全开源免费的,是一个高性能的key-value内存数据库,读的速度是110000次/s,写的速度是81000次/s     它有以下三个特点:   Redis不 ...

  6. php基本数据类型解说

    一.简介: php语言是弱类型语言,声明变量的时候不需要指定数据类型.但每个数值都是有数据类型的.PHP共有九种数据类型. php基本数据类型共有四种:boolean(布尔型),integer(整型) ...

  7. __str_方法和__repr__的区别

    __str__方法和__repr__方法: 官方文档解释: Object.__repr__(self): 由 repr() 内置函数调用以输出一个对象的“官方”字符串表示.如果可能,这应类似一个有效的 ...

  8. flutter源码学习笔记-图片加载流程

    本文基于1.12.13+hotfix.8版本源码分析. 0.大纲 Image ImageProvider 图片数据加载 ImageStream.ImageStreamCompleter 缓存池 Pai ...

  9. [bzoj1800]fly 飞行棋<暴力>

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1800 说实话我这几天运气不错,随便在bzoj上找题都可以找到水题,这题在代码上没有丝毫难度 ...

  10. NCEP CFSR数据下载

    一.简介 CFSR(Climate Forecast SystemReanalysis)再分析资料使用了 GEOS-5(Goddard EarthObserving System)大气模式与资料同化系 ...