1.JAVA基础——数组、集合1

1.数组声明

int score[] = new int[]{1,2,3};
int[] score2 = {1,2,3};
int[] score3 = new int[3];

2.集合

先上一张逻辑图。

在JAVA中,集合容器分为两类:一种是单值的Collection,一种是存储键-值对的Map。

  • Colleciton:Collection是一个接口,用于表示任何对象或元素组。
    • Collection接口的方法(Collection不提供get方法,要遍历Collection必须使用Iterator)。
      1. 单元素添加、删除操作:boolean add(Object o);boolean remove(Objcet o);
      2. 查询操作:int size();boolean isEmpty();boolean contains(Object o);Iterator iterator()//返回一个迭代器,用于访问集合各元素;
      3. 组操作:boolean containsAll(Collection c);boolean addAll(Collection c);void clear();void removeAll(Collection c);void retainAll(Collection c)//从集合中删除集合c中不包含的元素,即取与集合c的交集;
      4. 转Objcet数组操作:Object[] toArray()//返回一个包含集合内所有元素的array(必须是Object对象,不能是基本数据类型);Object[] toArray(Object[] a)//返回一个包含集合内所有元素的array,其中a表示存储此 collection 元素的数组(如果其足够大),否则,将为此分配一个具有相同运行时类型的新数组;
    • AbstarctCollection抽象类:该类是Collection接口的抽象实现类,它提供了具体“集合框架”的基本功能,该类提供了除 iterator()和size()外其他方法的实现,不过AbstarctCollection类对于add()方法(该方法在 AbstarctCollection中的实现是直接抛出UnsupportedOperationException异常),在使用时需要重新实现。
    • Iterator接口:Collection通过iterator()方法返回一个Iterator(迭代器)。该接口以迭代的方式逐个访问集合中的各个元素,并安全地从Collection中除去适当的元素。
      • 注意:这里的“安全”是指(网上解释):Iterator 是工作在一个独立的线程中,并且拥有一个 mutex 锁。 Iterator 被创建之后会建立一个指向原来对象的单链索引表,当原来的对象数量发生变化时,这个索引表的内容不会同步改变,所以当索引指针往后移动的时候就找不到要迭 代的对象,所以按照 fail-fast 原则(故障快速修复) Iterator 会马上抛出java.util.ConcurrentModificationException 异常。所以 Iterator 在工作的时候是不允许被迭代的对象被改变的。但你可以使用 Iterator 本身的方法 remove() 来删除对象, Iterator.remove() 方法会在删除当前迭代对象的同时维护索引的一致性。看以下代码:
        public static void main(String[] args) {
            Set<String> set = new HashSet<String>();
            set.add("a");
            set.add("b");
            set.add("c");
            set.add("d");
            Iterator<String> iterator = set.iterator();
            /* 下面这个while循环中进行删除就是正常的*/
            while (iterator.hasNext()) {
                String string = (String) iterator.next();
                if (string.endsWith("c")) {
                    iterator.remove();
                }
            }
            /* 下面这个for循环中进行删除就会抛异常*/
            /*for (String string : set) {
                if (string.endsWith("c")) {
                    set.remove(string);
                }
                
            }*/
            for (String string : set) {
                System.out.println(string);
            }
        }
    • ListIterator接口:它集成自Iterator接口,以支持添加或更改底层集合中的元素,还支持双向访问,它没有当前位置,光标位于previous和next方法返回的值之间。
      • 关于ListIterator的几个方法:
        • Object previous():返回光标前一个对象,并且光标前移一位。
        • Object next():返回光标后一个对象,并且光标后移一位。由于光标处于两者之间,所以连续调用next和previous方法返回是同一个对象。
        • void add(Object o):添加一个元素,添加的位置是当前光标的前面,所以在用add添加一个元素后,调用previous()方法会返回刚刚添加的元素,而next方法的返回值不受add方法影响。
        • void set(Object o):对一个元素进行设值,这个元素是前一次调用previous()或next()方法后返回的那个元素。(注:如果上次调用后列表结构被修改了,那么将抛出IllegalStateException 异常。)
          public static void main(String[] args) {
              List<String> list = new ArrayList<String>();
              list.add("a");
              list.add("b");
              list.add("c");
              ListIterator<String> listIterator = list.listIterator();
              if (listIterator.hasNext()) {
                  System.out.println(listIterator.nextIndex());
                  System.out.println(listIterator.next());
                  System.out.println(listIterator.nextIndex());
                  System.out.println(listIterator.previous());
                  System.out.println(listIterator.nextIndex());
                  System.out.println("----------------------");
                  
                  
                  System.out.println(listIterator.next());
                  listIterator.set("m");
                  System.out.println(listIterator.previous());
                  listIterator.add("n");
                  System.out.println(listIterator.previous());
              }
          }
          
          //输出结果为:
          0
          a
          1
          a
          0
          ----------------------
          a
          m
          n
    • AbstractList和AbstractSequentialList抽象类:都是List的抽象实现类,它们覆盖了equals()和hashCode()方法,确保相等集合返回相同的哈希码。此外,AbstractList和AbstractSequentialList实现了List的其余一些方法,其中包括iterator方法的实现。
    • RandomAccess接口:这是一个特征接口,当某个集合实现类实现该接口的时候,表示该集合实现类支持有效的随机访问。ArrayList和Vector类都实现了该接口。
      • 注意:JDK中推荐对于List集合尽量要实现RandomAccess接口,如果集合实现了该接口,那么在遍历该集合的时候,尽量使用for(int i = 0; i < size; i++)来遍历,而不要使用Iterator迭代器来实现。反之,如果List是Sequence List,则最好采用迭代器来迭代。JDK中说的很清楚,在对List特别是Huge size的List的遍历算法中,要尽量来判断是属于RandomAccess(如ArrayList)还是Sequence List (如LinkedList),因为适合RandomAccess List的遍历算法,用在Sequence List上就差别很大,常用的作法就是:
        if (list instanceof RandomAccess) {
            for(int m = 0; m < list.size(); m++){
        } }
        else{ Iterator iter = list.iterator(); while(iter.hasNext()){
        } }
    • Comparable接口和Comparator接口:集合框架中的两种比较接口。
      • 实现了Comparable接口的JAVA类需要实现compareTo(Object o)方法,用于比较当前对象与对象o的顺序,如果位于对象o之前,就返回负数,如果两个对象位置相同,则返回0(注意:0只是表示位置相同,元素不一定相同),如果在o之后,则返回正值。
      • 如果一个类无法或不方便实现Comparable接口,并且向提供自己的排序方式,可以自行实现Comparator接口,从而定义一个比较器,比较器包含compare(Object o1, Object2)和equalse(Object o)两个方法,第一个方法用于比较o1和o2两个对象顺序,如果o1在o2前面,则返回负值,如果相等则返回0(注意:0只是表示位置相同,元素不一定相同),如果o1位于o2后面,则返回正值。第二个equalse方法用于比较对象o是否与比较器相等。
    • SortedSet接口:特殊的集合接口,它保持元素的有序排序(从低到高)。注意:这里的有序,不是指元素的录入顺序,而是指元素在加入该类集合后,会根据comparable接口实现的compareTo方法或Comparator接口的comapre方法进行比较,按返回结果对元素进行有序排列。具体可见下面代码:
      public static void main(String[] args) {
          Set<String> ts = new TreeSet<String>();
          ts.add("c");
          ts.add("z");
          ts.add("a");
          ts.add("b");
          ts.add("3");
          for (String string : ts) {
              System.out.println(string);
          }
      }
      
      //输出结果为:
      3
      a
      b
      c
      z

      由于需要对元素排序,所以添加到SortedSet的元素必须实现Comparable接口,否则必须为SortedSet接口实现类的构造方法提供一个Comparator接口的实现。例如SortedSet接口的唯一实现类TreeSet,它就提供了一个包含Comparator接口的构造方法:

      public TreeSet(Comparator<? super E> comparator) {
          this(new TreeMap<E,Object>(comparator));
      }

      该接口提供了访问集合的视图(子集)和两端的方法。

      • Comparator comparator():返回对元素进行排序时的比较器,如果使用Comparable接口的compareTo方法进行比较,则返回null

      • Object first():返回有序集合中的第一个(最低)元素。

      • Object last():返回有序集合中的最后(最高)一个元素。

      • SortedSet subSet(Object fromElement, Object endElement):返回从fromElement(包括)到endElement(不包括)范围内元素的SortedSet视图(子集)

      • SortedSet headSet(Object toElement):返回一个视图(子集),包括集合中所有小于toElement的元素。

      • SortedSet tailSet(Object fromElement):返回一个视图(子集),包括集合中所有大于或等于fromElement的元素。
    • AbstractSet抽象类:该类覆盖了equals和hashCode方法。
  • Map接口:Map接口用于维护键/值对,该接口描述了从不重复的键到值的映射。
    • Map接口的方法:
      1. 添加删除操作:Object put(Object key, Object value)//如果key已存在,则覆盖旧值,并返回旧值,如果不存在则添加并返回null;Object remove(Object key);void putAll(Map t);void clear();(注意:map的key和value都可以是null)
        public static void main(String[] args) {
            Map<String, String> map1 = new HashMap<String, String>();
            map1.put("a", "a");
            Map<String, Map> map = new HashMap<String, Map>();
            map.put("0", map1);
            map.put("1", map);
            Map neeMap = map.get("1");
            System.out.println(neeMap == map);
            System.out.println(neeMap.get("0"));
        }

        返回结果是:true和{a=a}
        说明:Map可以把自身作为key或value添加给自身

      2. 查询操作:Object get(Object key)//如果找不到则返回null;boolean containsKey(Object key);boolean containsValue(Object value);int size();boolean isEmpty();
      3. 视图操作:Set keySet()//返回所有key的视图集;Collection values()//返回所有value的视图集;Set entrySet()//返回Map.Entry对象的视图集;(注意:1.entrySet()方式速度比keySet()然后去value方式快很多;2.开发者可以将所有返回的视图集中的元素删除,同时它对应的源中的key/value也会被删除,但是不能在视图集中添加元素)
        public static void main(String[] args) {
            Map<String, String> map = new HashMap<String, String>();
            map.put("a", "1");
            map.put("b", "2");
            map.put("c", "3");
            Set<Entry<String, String>> set = map.entrySet();
            Iterator<Entry<String, String>> iterator = set.iterator();
            while (iterator.hasNext()) {
                Entry<String, String> entry = iterator.next();
                if (entry.getKey().equals("b")) {
                    iterator.remove();
                }
            }
            for (Entry<String, String> entry : set) {
                System.out.println("修改前key为:" + entry.getKey() + "  value为:" + entry.getValue());
                entry.setValue(entry.getValue() + "~~");
                System.out.println("修改后key为:" + entry.getKey() + "  value为:" + entry.getValue());
            }
        }
        
        //输出结果为:
        修改前key为:c  value为:3
        修改后key为:c  value为:3~~
        修改前key为:a  value为:1
        修改后key为:a  value为:1~~
    • Map.Entry接口:Map的entrySet()方法返回一个实现了Map.Entry接口的对象集合,通过这个集合的迭代器,您可以获得每一个条目(唯一获取方式)的键或值并对值进行更改。当条目通过迭代器返回后,除非是迭代器自身的remove()方 法或者迭代器返回的条目的setValue()方法,其余对源Map外部的修改都会导致此条目集变得无效,同时产生条目行为未定义。
    • SortedMap接口:SortedMap接口是集成自Map的一个特殊接口,它用来保持键的有序顺序。处理与SorterSet一样,只是它比较的是Map的key。
    • AbstractMap抽象类:与AbstractSet、AbstractList类似,覆盖了equals和hashCode方法。
    • WeakHashMap类:WeakHashMap是Map的一个特殊实现,它使用WeakReference(弱引用)来存放哈希表关键字。使用这种方式时,当映射的键在 WeakHashMap 的外部不再被引用时,垃圾收集器会将它回收,但它将把到达该对象的弱引用纳入一个队列。WeakHashMap的运行将定期检查该队列,以便找出新到达的 弱应用。当一个弱引用到达该队列时,就表示关键字不再被任何人使用,并且它已经被收集起来。然后WeakHashMap便删除相关的映射。
      • (1) WeakHashMap(): 构建一个空弱哈希映像
      • (2) WeakHashMap(Map t): 构建一个弱哈希映像,并且添加映像t中所有映射
      • (3) WeakHashMap(int initialCapacity): 构建一个拥有特定容量的空的弱哈希映像
      • (4) WeakHashMap(int initialCapacity, float loadFactor): 构建一个拥有特定容量和加载因子的空的弱哈希映像
    • IdentityHashMap类:IdentityHashMap也是Map的一个特殊实现。在这个类中,关键字的哈希码不应该由hashCode()方法来计算,而应该由 System.identityHashCode方法进行计算(即使已经重新定义了hashCode方法)。这是Object.hashCode根据对象的内存地址来计算哈希码时使用的方法。另外,为了对各个对象进行比较,IdentityHashMap将使用==,而不使用equals方法。换句话说,不同的关键字对象,即使它们的内容相同,也被视为不同的对象。IdentityHashMap类可以用于实现对象拓扑结构转换 (topology-preserving object graph transformations)(比如实现对象的串行化或深度拷贝),在进行转换时,需要一个“节点表”跟踪那些已经处理过的对象的引用。即使碰巧有对象相等,“节点表”也不应视其相等。另一个应用是维护代理对象。比如,调试工具希望在程序调试期间维护每个对象的一个代理对象。
      IdentityHashMap类不是一般意义的Map实现,它的实现有意的违背了Map接口要求通过equals方法比较对象的约定。这个类仅使用在很少发生的需要强调等同性语义的情况。
      (1) IdentityHashMap (): 构建一个空的全同哈希映像,默认预期最大尺寸为21
      “预期最大尺寸是映像期望把持的键/值映射的最大数目”
      (2) IdentityHashMap (Map m): 构建一个全同哈希映像,并且添加映像m中所有映射
      (3) IdentityHashMap (int expectedMaxSize): 构建一个拥有预期最大尺寸的空的全同哈希映像。放置超过预期最大尺寸的键/值映射时,将引起内部数据结构的增长,有时可能很费时 。

 

posted @ 2015-04-28 15:53  L______eo  阅读(187)  评论(0编辑  收藏  举报