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对象的视图集;(注意:开发者可以将所有返回的视图集中的元素删除,同时它对应的源中的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): 构建一个拥有预期最大尺寸的空的全同哈希映像。放置超过预期最大尺寸的键/值映射时,将引起内部数据结构的增长,有时可能很费时 。
时间: 2024-10-18 08:12:43

1.JAVA基础——数组、集合1的相关文章

java基础之集合List-ArrayList、LinkedList、Vector的区别

PS:本篇博客主要参考jdk的底层源码,而非自己动手写代码. 请问ArrayList.LinkedList.Vector的区别 ①ArrayList底层实际上是采用数组实现的(并且该数组的类型的Object类型的) ②如果jdk6,采用Array.copyOf()方法来生成一个新的数组,如果是jdk5,采用的是System.arraycopy()方法(当添加的数据量大于数组的长度时候) ③List list = newArrayList()时,底层会生成一个长度为10的数组来存放对象 ④Arra

Java基础之 集合体系结构(Collection、List、ArrayList、LinkedList、Vector)

Java基础之 集合体系结构详细笔记(Collection.List.ArrayList.LinkedList.Vector) 集合是JavaSE的重要组成部分,其与数据结构的知识密切相联,集合体系就是对数据结构的封装 数组与集合的比较 数组:长度固定,可以存储基本数据类型,也能存储对象 集合:长度可变,只能存储对象类型(由于有包装类的存在,集合可以存储任何类型) 集合的体系结构 集合也叫容器,用于存储对象 我们根据不同的需求和不同的数据结构来对集合做了不同的抽象 Collection接口-公共

[java基础]数组1

[java基础]数组1 1 /** 2 文件路径:G:\JavaByHands\数组 3 文件名称:ArrayTest.java 4 编写时间:2016/6/13 5 编写说明:学习数组的使用方法~~ 6 知识来源:疯狂java讲义 7 */ 8 9 /* 10 数组是用来储存多个数据的一种数据结构~~ 11 一个数据被成为一个数组元素 12 可以通过数组元素的索引来访问数组元素 13 java要求所有的数组元素具有相同的数据类型 14 一旦数组初始化完成,数组在内存中所占的空间将被固定下来,长

java基础之集合Set

1.集合 当向集合Set中增加对象时,首先集合计算要增加对象的hashcode,根据该值得到一个位置用来存放当前的对象,当在该位置没有一个对象存在的时候,集合set认为该对象在集合中不存在,直接增加进去.如果在该位置有一个对象存在,接着将准备增加到集合中的的对象与该位置上的对象进行equals比较,若返回false,在进行一次散列,将该对象放到散列后计算出的新地址.若返回true,不会再将该对象增加到集合中 2.当重写equals方法时,必须要重写hashcode方法 如果一个类的两个对象,使用

黑马程序员——java基础 ArrayList集合基本方法演示

java基础 ArrayList集合基本方法演示 import java.util.ArrayList; import java.util.Iterator; public class ArrayListDemos { public static void main(String[] args) { // 创建一个新的容器 ArrayList al = new ArrayList(); al.add("abc1"); al.add("abc2"); al.add(&

Java基础——数组Array

一.数组基本概念 数组是相同类型数据的有序集合. 数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成.其中,每一个数据称作一个数组元素,每个数组元素可以通过一个下标来访问它们. 数组有三个特点: 1. 其长度是确定的.数组一旦被创建,它的大小就是不可以改变的.不可越界,如果越界,则报:ArrayIndexOutOfBoundsException 2. 其元素必须是相同类型,不允许出现混合类型. 3. 数组中的元素可以是任何数据类型,包括基本类型和引用类型. 数组不属于八种基本数据类

JAVA基础学习-集合三-Map、HashMap,TreeMap与常用API

一.Map简述 1.1.简述 public interface Map<K,V> 类型参数: K - 此映射所维护的键的类型 key V - 映射值的类型 value 该集合提供键--值的映射.key不能重复,一对对的存储方式 将键映射到值的对象.一个映射不能包含重复的键:每个键最多只能映射到一个值. 1.2.方法 嵌套类摘要 static interface Map.Entry<K,V> 映射项(键-值对). 方法摘要 void clear() 从此映射中移除所有映射关系(可选操

JAVA基础之集合框架

集合框架(collections framework) 首先要明确,集合代表了一组对象(和数组一样,但数组长度不能变,而集合能).Java中的集合框架定义了一套规范,用来表示.操作集合,使具体操作与实现细节解耦. 其实说白了,可以把一个集合看成一个微型数据库,操作不外乎"增删改查"四种操作,我们在学习使用一个具体的集合类时,需要把这四个操作的时空复杂度弄清楚了,基本上就可以说掌握这个类了. 设计理念 主要理念用一句话概括就是:提供一套"小而美"的API.API需要对

Java基础——数组复习

数组是一个变量,存储相同数据类型的一组数据 声明一个变量就是在内存空间划出一块合适的空间 声明一个数组就是在内存空间划出一串连续的空间 数组长度固定不变,避免数组越界 数组是静态分配内存空间的,所有元素存放在一组连续的存储单元中,一旦分配,不可更改,不便于扩展, 数组便于查找和修改,不利于插入和删除. 使用数组 : ① 声明数组    ② 分配空间    ③ 赋值    ④ 处理数据 Java中数组定义要指定长度. 数据类型[] 数组名 = new 数据类型[数组长度]; 数据类型[][] 数组