集合框架知识总结

1—Collection集合

Collection集合关系简表:

一:集合简述

  1. Collection集合:
    它是集合的根接口,不可以直接实现。
    Collection 实现了 Iterable 接口,可以用iterator()【迭代器】遍历对象。

    Collection集合常用方法:

    boolean  add (E  e)                 //添加一个待定类型的元素,添加成功返回 true ,添加失败返回 false 。
        boolean  isEmpty ()             //判断集合是否为空,是的话就返回true 。
        boolean  contains (Object  o)   //判断集合中是否包含元素 o(注意o的类型)。
        boolean  equals (Object  o)     //判断集合与指定对象是否相等,已经覆盖了上帝类中的equals 。
        boolean  remove(Object  o)      //移除一个元素,移除成功返回true。
    
        int  size ()            //返回集合中的元素个数。
        int  hashCode ()        //返回集合的哈希值。
        void  clear ()          //移除Collection中所有元素。
        Iterator<> iterator()   //返回集合元素的迭代。
    

    数组和集合同是容器,其不同在于:
      数组长度是固定的。集合长度是可变的。
      数组可以存储基本数据类型,集合只能存储对象,而且可以存储不同类型的对象。

  2. 迭代器的概念:
    集合的内部都定义了集合元素的取出方式,每种集合的数据结构都不同,迭代器就是抽取了取出方式的共性内容。

  3. 泛型:
    集合在创建对象时最好明确要存入的元素的类型,这样更安全。
    形式如:

    ArrayList<String> list=new ArrayList<String>(); 
    //指定集合中只能存储字符串类型。
    

      这就是泛型限定。
    泛型的好处
    如果不指定集合的类型,用户在传值时,有可能传入不同类型的元素,而取出时按照统一类型取出,就会出现异常。
    所以泛型的出现,就把运行时容易出现的问题ClassCastException 转移到编译时期。
    泛型也避免了强转。
    泛型类:
    当类中要操作的引用数据类型不确定时,就 在类上定义泛型,如:

        class Demo<T>
        {
            private T t;
            public T show() 
            {
                return t;
            }
        }
    

    注意:
    静态方法加载时,泛型还未指定,所以不可以访问类上定义的泛型。
    定义了泛型之后,创建该类对象时需要指定类型,这样就只可以存入一种类型的元素。
    但是创建了对象之后,泛型就被锁定,不可以再传入其他类型,这是泛型类的局限性。

    泛型方法
    把泛型定义在方法上,可以在同一个对象引用中操作不同类型。
    形式:

        class Demo
        {
            public <T> void show(T t) {}    //方法上的泛型放在返回值类型前。
            public <T> void print(T t) {}
        }
    

    这样定义的泛型就只在本方法中有效,可以一个对象调用多种类型数据。

    如果类上的泛型和类中方法上的泛型同名,那么类上的泛型被锁定时,类中方法上的泛型也被锁定。

    泛型接口
    就是在接口上使用泛型,由实现它的类或者该类的对象指定泛型,如:

        interface Inter<T>
        {
            void show(T t);
        }
        class Demo implements Inter<String> //接口被实现时指定了泛型,有局限性。
        {
            public void show(String t) {}
        }
        class Demo_2<T> implements Inter<T> //接口被实现时不指定类型。
        {
            public void show(T t) {}
        }
    

    泛型限定
    当不同类型的泛型调用同一个方法时,该方法不确定是哪一种类型的泛型,所以就用一个占位符表示,
    形如:

    public void (ArrayList<?> list){}
    

    这样的泛型不可以调用具体类型的方法,因为类型不确定,所以类型中不确定有没有此方法。
    问号作为占位符代表类型不确定,但仍然可以是任何类型,如果要缩小范围,就可以写成:

    public void (ArrayList<? extends E> list)
    

    这样的泛型限定代表的是上限,意思是只可以接收E类型或者E的子类,
    还可以写成:

        public void (ArrayList<? super E> list)
    

    这样的泛型代表的是下限,意思是只可以接受E类型或者E的父类。

二:Collection集合框架详解

  1. List
    是一个接口,继承自Collection接口。
    List 无法实例化,只有实现它的子类可以实例化。
    List 可以有重复元素。
    List中的元素有角标,可根据元素的角标索引访问元素。

    常用方法

    boolean  add (E  e)             //往列表最后添加一个待定类型的元素,添加成功返回 true ,添加失败返回 false 。
    boolean  isEmpty ()             //判断List是否为空,是的话就返回true 。
    boolean  contains (Object  o)   //判断List列表中是否包含指定元素。
    boolean  equals (Object  o)     //判断List列表与指定对象是否相等 。
    boolean  remove(Object  o)      //移除第一个o元素,移除成功返回true。
    
    void  add(int  index,E  element)//指定位置上插入元素。
    void  clear ()                  //移除List列表中所有元素。
    int      indeOf (Object  o)     //返回指定元素在列表中第一次出现的位置,如果列表不包含次元素,返回-1.
    int      lastIndeOf (Object  o) //返回指定元素在列表中逆向第一次出现的位置,如果列表不包含次元素,返回-1.
    int  size ()                    //返回List集合中的元素个数。
    int  hashCode ()                //返回List集合的哈希值。
    E    get (int  index)           //返回列表中指定位置上的元素。
    E    remove (int  index)        //移除指定位置上的元素,返回被移除元素,可能抛角标越界异常。
    E    set(int  index,E  element) //用指定元素替代指定角标上的元素,返回被替换元素,要抛异常。
    
    boolean  removeAll(Collection<?>  c)    //移除指定List中和c重复的所有元素。
    boolean  retainAll(Collection<?>  c)    //保留指定List中和c重复的所有元素。
    List<E>  subList (int from,int to)      //截取一个短的List集合,从from到to,包含头不包含尾。
    Object  [] toArray()                    //返回按适当顺序排列的数组。
    T  [] toArray (T []  a)                 //返回指定类型的数组。
    Iterator<E> iterator()                  //按适当顺序在列表的元素上进行迭代的迭代器。Iterator只能对元素判断,修改,取出。
    ListIterator<E> listIterator            //返回列表元素的列表迭代器。功能比Iterator多。
    
  2. ArrayList
    它是数组集合。
    ArrayList实现了List接口,它可以实例化。
    构造时,
      ArrayList()   默认构造一个初始容量10的列表,
      ArrayList(int n)构造一个初始容量为n的列表。

    ArrayList**常用方法**基本与List相同。

    举例: ArrayList 常见方法使用示例

    import java.util.*;
    class Demo {
        public static void main(String [] args) {
            ArrayList<String> arrlist=new ArrayList<String>();
            arrlist.add("java01");  //添加元素
            arrlist.add("java02");
            arrlist.add("java03");
            System.out.println(arrlist);  //直接打印集合。[java01, java02,java03]
            System.out.println(arrlist.get(1)); //获取角标1上的元素。
            int L=arrlist.size();         //L指arrlist的长度,3.
    
            System.out.println(arrlist.remove(1));   //删除1角标上的元素,并返回此元素。打印java02 。
            System.out.println(arrlist.indexOf("java02")); //获取对象角标。
            System.out.println(arrlist.remove("java01"));    //删除指定元素。返回是否删除成功,true。
            System.out.println(arrlist.contains("java01"));//已经移除,不包含,返回false。
            System.out.println(arrlist);         //元素只剩下:[java03]
            arrlist.add(0,"JAVA");             //指定位置添加元素
            System.out.println(arrlist);     //打印数组:[JAVA,java03]
            //由此可见移除元素时,后面元素的角标会改变。
    
            arrlist.clear();                    //清空元素
            System.out.println(arrlist.size());  //元素个数0.
            System.out.println(arrlist.isEmpty());  //ArrayList为空,返回true。
        }
    }
    

    迭代器的用法:
    举例: ArrayList 用迭代器取出元素

        Iterator<String> it=arrlist.iterator();
        while (it.hasNext())
        {
            System.out.println(it.next());
        }
    

    或者:

        for (Iterator it=arrlist.iterator();it.hasNext(); )
        {
            System.out.println(it.next()); 
        }
    

    注意:写成for循环可以不用在外部定义迭代器,节省内存。而且代码更简洁。

    ArrayList 特有的列表迭代器–ListIterator
      Iterator 只能对元素判断,取出,删除, ListIterator 更可以对元素添加和修改。

        ArrayList<String> al=new ArrayList<String>();
        al.add("01");
        al.add("02");
        al.add("03");
        for (ListIterator<String> lit=al.listIterator();lit.hasNext(); )
        {
            String s=lit.next();
            if (s.equals("02"))
            {
                lit.set("JAVA2");
                lit.add("java02");  //这两句不可以换位 
            }
        }
    

    注意: ListIterator 只能先修改再添加,不可以先添加再去修改。
    因为如果先添加元素,元素后的角标都会变,再去修改就出现状态异常:IllegalStateException

    练习1: ArrayList集合 去除重复元素方法。
      定义好ArrayList后,新建一个临时数组集合,用于存储集合元素。
    然后迭代ArrayList的元素以判断是否包含的形式选择添加进临时数组集合,然后再迭代取出。

    import java.util.*;
    class Demo {
        public static void main(String [] args) {
            ArrayList<String> al=new ArrayList<String>();
            al.add("01");
            al.add("02");
            al.add("03");
            al.add("03");
            al = noRepeat(al);
            System.out.println(al);
        }
        public static ArrayList<String> noRepeat(ArrayList<String> al) {
            ArrayList<String> arrlist = new ArrayList<String>();
            for (Iterator<String> it=al.iterator();it.hasNext(); ) {
                String s=it.next();
                if (!(arrlist.contains(s)))
                    arrlist.add(s);
            }
            return arrlist;
        }
    }
    

    练习2:集合中存储自定义对象的去重复方法:。
      集合中如果添加的是自定义的对象,集合中存储的是对象的引用,那么所有对象都不会相同。
    所以就要在对象类中重写equals方法以判断元素的内容是否相同,然后迭代取出。

    import java.util.*;
    class Person {
        private String name;
        private int  age;
        Person(String name,int age) {
            this.name=name;
            this.age=age;
        }
        public String getName() {
            return name;
        }
        public int getAge() {
            return age;
        }
        public boolean equals(Object oo) {
            if (!(oo instanceof Person))
                return false;
            Person p = (Person)oo;
            return this.name==p.name && this.age==p.age;
        } 
    }
    
    class Demo {
        public static void main(String [] args) {
            ArrayList<Person> al=new ArrayList<Person>();
            al.add(new Person("01",12));
            al.add(new Person("02",13));
            al.add(new Person("01",12));
            al.add(new Person("01",13));
            al=noRepeat(al);
            for (Iterator<Person> it=al.iterator();it.hasNext(); ) {
                Person p=it.next();
                System.out.println(p.getName()+" + "+p.getAge());
            }
        }
        public static ArrayList<Person> noRepeat(ArrayList<Person> al) {
            ArrayList<Person> arrlist = new ArrayList<Person>();
            for (Iterator<Person> it=al.iterator();it.hasNext(); ) {
                Person p=it.next();
                if (!arrlist.contains(p))
                    arrlist.add(p);
            }
            return arrlist;
        }
    }
    

    注意:
    (1)集合中存储的其实是对象的引用地址值。
    (2)元素取出时,要调用对象的方法取出元素值。
    (3)从太难受方法调用了equal是方法,所以对于对象引用的比较,应该重写equals方法。
    (4)注意equals方法比较的是Object类型,所以有向上转型和向下转型。

  3. LinkedList
    –链表集合。
      LinkedList集合的特点是,集合中的元素没有角标,每个元素会和它前一个元素形成关系,这样就组成了一个链表。
    当要对LinkedList中的元素查询的时候就要一个一个判断,速度慢。
    但是当要增删的时候就比较快,因为不需要改动后面所有元素的角标了,只需要改变指定元素周围的关系就可以。

    LinkedList 常用方法和List基本相同,

    LinkedList 特有的方法:

    void  addFirst (E  e)       //将元素插入到开头。
    void  addLast (E  e)        //将元素插入到末尾。
    
    //这几个方法如果列表为空会抛NoSuchElementException异常。
        E  getFirst ()      //获取第一个元素。
        E  getLast ()       //获取最后一个元素。
        E  removeFirst ()   //移除并返回第一个元素。
        E  removeLast ()    //移除并返回最后一个元素。
    

    从JDK1.6开始,出现了新方法,功能和以上一样,但是都不会再抛NoSuchElementException异常。

    void  offer (E  e)
    void  offerFirst (E  e)
    void  offerLast (E  e)
       E  peek ()
       E  peekFirst ()
       E  peekLast ()
       E  poll ()
       E  poolFirst ()
       E  pollLast ()
    

    举例: LinkedList 模拟堆栈的先进后出数据结构和队列的先进先出数据结构。

    import java.util.*;
    class Zhan {
        private LinkedList<Object> ll=new LinkedList<Object>();
        public void myAdd(Object oo) {
            ll.offer(oo);           //从末尾添加元素
        }
        public Object myGet() {
            return ll.pollLast();   //从末尾获取元素并移除
        }
        public boolean isNull() {
            return ll.isEmpty();    //判断集合是否为空
        }
    }
    class Dui {
        private LinkedList<Object> ll=new LinkedList<Object>();
        public void myAdd(Object oo) {
            ll.offer(oo);           //从末尾添加元素
        }
        public Object myGet() {
            return ll.pollFirst();  //从开头获取元素并移除
        }
        public boolean isNull() {
            return ll.isEmpty();    //判断集合是否为空
        }
    }
    class Demo {
        public static void main(String [] args) {
            Zhan z=new Zhan();
            z.myAdd("z1");
            z.myAdd("z2");
            z.myAdd("z3");
            while (!z.isNull())
                System.out.println(z.myGet()); 
    
            Dui d=new Dui();
            d.myAdd("d1");
            d.myAdd("d2");
            d.myAdd("d3");
            while (!d.isNull()) 
                System.out.println(d.myGet()); 
        }
    }

    注意: LinkedList 如果泛型写成占位符形式 LinkedList<?>那么就不能往集合中添加Object元素。

  4. Set
     Set集合不包含重复元素,包括null值也不可重复。
    元素是无序的。
    Set 继承自 Collection , 它也是一个接口,不可以直接实例化。

    Set集合的常用方法和Collection基本相同。

  5. HashSet
    HashSet 底层数据结构是哈希表数据结构。
    HashSet 是Set集合的一个子类,允许使用null元素。
    HashSet 集合存元素时,不可以存相同的元素,包括null元素都不可以重复。
    数据存储时不是按照元素顺序排列,而是内存中对象的哈希值顺序,元素取出时也是按照哈希表的顺序取出,所以是无序的。

    HashSet 构造方法:

    HashSet()               //构造一个默认初始容量16的Set集合
    HashSet(int len)        //构造一个指定初始容量的Set集合
    HashSet(Collection c)   //构造一个包含指定集合的Set集合
    

    Set 常用方法:

    int size()                  //返回集合长度
    void clear()                //移除集合中所有元素
    boolean add(E e)            //对集合添加一个元素并返回是否添加成功
    boolean isEmpty()           //判断集合是否为空
    boolean remove(Object oo)   //移除指定元素并返回是否移除成功
    boolean contains(Object oo) //返回集合中是否包含指定元素
    Iterator<E> iterator()      //返回对此Set集合中元素迭代的迭代器
    

    Set集合存入自定义对象时,实际存入的也是对象的引用。这时候系统会先判断对象的引用是否相同。
    所以就要覆盖对象的hashCode()方法,让对象的引用都相同。引用相同时,系统还会调用equals()方法再判断一次存入的对象的内容是否相同。
    所以也要重写equals方法。

    举例: Set 集合存储自定义对象。

    import java.util.*;
    class Person {
        private String name;
        private int age;
        Person (String name,int age) {
            this.name=name;
            this.age=age;
        }
        public String getName() {
            return name;
        }
        public int getAge() {
            return age;
        }
        public boolean equals(Object oo) {
        //已经限定集合类型为Person,所以不用判断类型
        //  if (!(oo instanceof Person))
        //      return false;
            Person p=(Person)oo;
            return this.name == p.name && this.age==p.age;
        }
        public int hashCode() {
            return 123*45;
        }
    }
    class Demo {
        public static void main(String [] args) {
            HashSet<Person> hs=new HashSet<Person>();
            hs.add(new Person("s1",12));
            hs.add(new Person("s2",13));
            hs.add(new Person("s1",12));
            hs.add(new Person("s4",13));
            for (Iterator<Person> it=hs.iterator(); it.hasNext(); ) {
                Person p=(Person)it.next();
                System.out.println(p.getName()+"    "+p.getAge());
            }
        }
    }

    注意:
    (1)Set集合存入元素时,会先给对象分配哈希值,重写hashCode方法是为了让各个对象的哈希值相同;如果哈希值相同,就比较元素内容。
    (2)重写equals方法是为了可以比较对象方法返回的内容是否相同。
    (3)判断元素是否在集合中存在,先调用hashCode方法判断元素的哈希值是否相等,再调用equals方法判断元素内容是否相等。
    (4)移除元素也是先判断哈希值,再判断元素内容。
    (5)Set集合和List集合判断元素是否相同差别在于List不判断哈希值。

  6. TreeSet
    特点: TreeSet 底层数据结构是二叉树结构。
    TreeSet 集合中存入的元素必须具备比较性。
    TreeSet 可以对Set集合中的元素进行自然排序。

    TreeSet常用方法和Set基本相同,

    TreeSet特有方法:
    (1)构造方法:

        TreeSet(Comparator<? super E> c)//此比较器可以接收TreeSet集合接受的类型或者它的父类
    

    (2)一般方法:

        E first()       //返回集合中第一个元素
        E last()        //返回集合中最后一个元素
        E pollFirst()   //获取并移除第一个元素
        E pollLast()    //获取并移除最后一个元素
        E ceiling(E e)  //返回集合中大于等于指定元素的最小元素,不存在则放回null
        E floor(E e)    //返回集合中小于等于指定元素的最大元素,不存在则返回null
    
        Comparator<? super E> comparator()  //返回对集合中元素排序的比较器,如果是自然排序就返回null
        Iterator<E> descendingIterator()    //返回集合中降序迭代的迭代器
    

    TreeSet集合元素手动排序的第一种方式:让元素自身具备比较性。
      需要实现 Comparable接口,并且覆盖接口中的compareTo方法。

    举例:

    import java.util.*;
    class Person implements Comparable<Person> {
        private String name;
        private int age;
        Person (String name,int age) {
            this.name=name;
            this.age=age;
        }
        public String getName() {
            return name;
        }
        public int getAge() {
            return age;
        }
        public int compareTo(Person p)
        {
            if (this.age<p.age)
                return -1;
            if (this.age>p.age)
                return 1;
            return this.name.compareTo(p.name);
        }
    }
    class Demo {
        public static void main(String [] args) {
            TreeSet<Person> ts=new TreeSet<Person>();
            ts.add(new Person("s1",12));
            ts.add(new Person("s2",13));
            ts.add(new Person("s1",12));
            ts.add(new Person("s4",13));
            for (Iterator<Person> it=ts.iterator(); it.hasNext(); ) {
                Person p=(Person)it.next();
                System.out.println(p.getName()+"++"+p.getAge());
            }
        }
    }

    注意: Comparable接口的compareTo方法参数类型是跟随Comparable的泛型的。

    TreeSet 集合手动排序的第二种方式:让集合自身具备比较性。
      当元素自身不具备比较性或者不是所需的比较性时,就要让集合自身具备比较性。
    先定义一个比较器,然后在集合初始化时,将比较其对象作为参数传递给TreeSet集合的构造函数。

    接口 Comparator 是用于强制对对象排序的比较器。
    它有两个抽象方法:

    equals(Object oo)
    compare(Object o1,Object o2)
    //注意不是compareTo,而是compare。
    

    定义比较器的示例

    class Com implements Comparator<Person>
    {
        public int compare(Person p1,Person p2)
        {
            int n = p1.getName().compareTo(p2.getName());
            if (n==0)
                return new Integer(p1.getAge()).compareTo(new Integer(p2.getAge()));
            return n;
        }
    }
    

    注意:
    这里不重写equals方法,是因为类继承Object,已经有equals方法。
    compare方法参数类型是跟随Comparator接口的泛型类型的。

    定义了比较器之后,就可以通过TreeSet的构造函数:TreeSet(Comparator<? super E> c);让集合自身具备比较性,然后通过传递参数的形式,在创建TreeSet对象时,添加参数:TreeSet<E> ts=new TreeSet<E>(new MyComparator());
    就可以对TreeSet集合中的元素进行排序。

    注意:
    当两种排序方法都存在时,比较器接口是对外提供的功能扩展,一般以比较器为主。

    举例: TreeSet 排序练习:按字符串长度排序。

    import java.util.*;
    class Demo
    {
        public static void main(String [] args)
        {
            TreeSet<String> ts=new TreeSet<String>(new MyCom());
            ts.add("aabsd");
            ts.add("aaasd");
            ts.add("vcx");
            ts.add("q");
            for (Iterator<String> it=ts.iterator();it.hasNext(); )
            {
                System.out.println(it.next());
            }
        }
    }
    class MyCom implements Comparator<String>
    {
        public int compare(String s1,String s2)
        {
             int n = new Integer(s1.length()).compareTo(new Integer(s2.length()));
             if (n==0)
                 return s1.compareTo(s2);
             return n;
        }
    }

    注意:
    String 类有compareTo方法,可以比较字符串并返回负数,零,正数。
    定义比较器比较时,往往需要比较两个内容,一个是两对象要比较的条件是否相等,一个是两对象是否是同一个。
    此例还可以写成匿名内部类的形式。

2—Map 集合

Map集合关系简表

一:Map集合简述

  1. Map集合:
    用于存储键值对,形成一个映射,Map集合反应的是键与值的映射关系,而且关系唯一。

    常用方法:

    int size()              //返回映射中的键值映射关系数。
    void clear()            //从映射中移除所有映射关系。
    int hashCode()          //返回此映射的哈希码值。
    boolean isEmpty()       //判断映射是否为空。
    V get(Object key)       //返回key对应的value值,如果不存在返回null。
    V put(K key,V value)    //添加一个映射关系,返回被覆盖的value值。
    V remove(Object key)    //如果存在键为key的映射关系,则将其移除,不存在返回null。
    
    boolean equals(Object oo)           //比较指定对象与此映射是否相等。
    boolean containsKey(Object key)     //返回映射是否包含指定key值。
    boolean containsValue(Object value) //返回映射是否包含指定value值。
    
    Set<K> keySet()                 //返回映射中包含的键的Set视图。
    Collection<V> values()          //返回映射中包含的值的Collection视图。
    Set<Map.Entry<K,V>> entrySet()  //返回映射中包含的映射关系的Set视图。
    

    举例: Map常用方法用法示例。

        import java.util.*;
        class Demo
        {
            public static void main(String [] args)
            {
                Map<String,String> map=new HashMap<String,String>();
                map.put("01","zhang01");
                map.put("02","zhang02");
                map.put(null,"zhang03");    //null可以作为键存在,但只能有一个null键。
    
                System.out.println(map.containsKey("02"));//判断是否包含"02"键。
                System.out.println(map.get("02"));      //返回"02"键对应的值并打印,不存在此键值就返回null。
                System.out.println(map.remove("02"));   //移除并返回"02"键的值,不存在此键就返回null。
                System.out.println(map);                //直接打印Map集合:{01=zhang01, 03=zhang03}
    
                System.out.println(map.values());       //打印Collection集合:[zhang01, zhang03]
    
                System.out.println(map.put("01","001"));//映射中存在同名键,所以会覆盖"01"键对应的值,并返回被覆盖的value值。
            }
        }
    
  2. Map 集合取出
    Map集合元素取出的第一种方式keySet方法。
    keySet 取出此映射中所有的键,存入一个Set集合。
    因为Set具备迭代器,所以可以迭代取出所有的键,然后get方法获取键对应的值。
    Map 集合的取出原理:将Map集合转成Set集合,再通过迭代器取出。Map集合本身不需要迭代器。

    举例: keySet方法取出映射中的键与值。

    import java.util.*;
    class Demo {
        public static void main(String [] args) {
            Map<String,String> map=new HashMap<String,String>();
            map.put("01","zhang01");
            map.put("02","zhang02");
            map.put("03","zhang03");
    
            Set<String> set=map.keySet();   //返回由Map集合中所有键值组成的Set集合。
            for (Iterator<String> it=set.iterator();it.hasNext(); ) {
                String key=it.next();
                System.out.println("key:"+key+" + value:"+map.get(key));
            }
        }
    }
    

    Map 集合取出的第二种方式entrySet方法。
    entrySet 返回的是一个键值映射关系Set视图,这种关系的数据类型是 Map.Entry。
    Map.Entry 是Map接口中的一个静态内部接口。

    常见方法:

    boolean equals(Object oo)   //比较两对象是否相等。
    int hashCode()              //返回对象哈希值
    K getKey()                  //获取对象的键。
    V getValue()                //获取对象的值。
    V setValue(V value)         //修改对象的值。
    

    举例: entrySet方法取出映射中的键与值。

    import java.util.*;
    class Demo {
        public static void main(String [] args) {
            Map<String,String> map=new HashMap<String,String>();
            map.put("01","zhang01");
            map.put("02","zhang02");
            map.put("03","zhang03");
    
            Set<Map.Entry<String,String>> set=map.entrySet();
            for (Iterator<Map.Entry<String,String>> it=set.iterator();it.hasNext(); ) {
                Map.Entry<String,String> entry=it.next();
                String key=entry.getKey();
                String value=entry.getValue();
                System.out.println(key+":"+value);
            }
        }
    }

    练习:
    学生具有属性:姓名,年龄;同时具有归属地。
    存入几个学生对象,以属性作为键,归属地作为值,并可以按学生年龄降序。

    import java.util.*;
    class Student implements Comparable<Student> {  //实现比较器,用于排序。
        private String name;
        private int age;
        Student(String name,int age) {
            this.name=name;
            this.age=age;
        }
        public String getName() {
            return name;
        }
        public int getAge() {
            return age;
        }
        public int hashCode() {
            return name.hashCode()+age*45;
        }
        public boolean equals(Object oo) {
            if (!(oo instanceof Student))
                throw new ClassCastException("!类型不匹配!");
            Student s=(Student)oo;
            return this.name.equals(s.name) && this.age==s.age;
        }
        public int compareTo(Student s) {
            int num=new Integer(s.age).compareTo(new Integer(this.age));
            if (num==0)
                return this.name.compareTo(s.name);
            return num;
        }
    }
    class Demo {
        public static void main(String [] args) {
            TreeMap<Student,String> tm=new TreeMap<Student,String>();
            tm.put(new Student("L1",21),"北京");
            tm.put(new Student("L2",20),"南京");
            tm.put(new Student("L2",20),"天津");
            tm.put(new Student("L3",25),"上海");
                //keySet方法取出Map集合元素。
            Set<Student> keySet=tm.keySet();        
            for (Iterator<Student> it=keySet.iterator();it.hasNext(); ) {
                Student s=it.next();
                System.out.println(s.getName()+"+"+s.getAge()+"<->"+tm.get(s));
            }
                //entrySet方法取出Map集合元素。
            Set<Map.Entry<Student,String>> entrySet=tm.entrySet();
            for (Iterator<Map.Entry<Student,String>> it=entrySet.iterator();it.hasNext(); ) {
                Map.Entry<Student,String> me=it.next();
                Student s=me.getKey();
                String str=me.getValue();
                System.out.println(s.getName()+" : "+s.getAge()+"<->"+str);
            }
        }
    }

    注意:
    Map集合必须存键值对象两个元素,可根据对象属性特点选择哪一个属性作为键。
    Map集合存入重复元素时,后存入的元素会覆盖之前的元素。
    TreeMap 也可以传入比较器用于对元素排序。此例如果要以姓名升序排列,可以自定义比较器。

    练习2:
    获取字符串中字幕出现次数。形式:a(2) b(4) c(1) …

    import java.util.*;
    class Demo {
        public static void main(String [] args) {
            String s="hcgngvsgjsbcgscbgsibscgjvjbjkbxkcjsbkjv";
            //可根据需要将字符串判断一次,确保字符串全是字母,没有数字或其他字符。
    
            printTime(s);
        }
        public static void printTime(String s) {
            char [] ch=s.toCharArray();
            TreeMap<Character,Integer> tm=new TreeMap<Character,Integer>();
            for (int x=0;x<ch.length;x++) {
                char c=ch[x];
                int i=0;
                if (tm.containsKey(c))
                    i=tm.get(c);
                tm.put(c,++i);
            }
            Set<Map.Entry<Character,Integer>> entrySet=tm.entrySet();
            for (Iterator<Map.Entry<Character,Integer>> it=entrySet.iterator();it.hasNext(); ) {
                Map.Entry<Character,Integer> me=it.next();
                char c=me.getKey();
                int i=me.getValue();
                System.out.print(c+"("+i+") ");
            }
        }
    }

    注意:
      泛型中接收的都是引用数据类型,不可以接受基础数据类型。

    练习3: Map集合的嵌套循环,打印学校中所有班级的学生信息。

    import java.util.*;
    class Demo {
        public static void main(String [] args) {
            //创建一个基础班
            HashMap<String,String> jichu=new HashMap<String,String>();  
            jichu.put("01","zhang");
            jichu.put("02","wang");
            //创建一个就业班
            HashMap<String,String> jiuye=new HashMap<String,String>();
            jiuye.put("001","zhao");
            jiuye.put("002","zhou");    
            //创建一个学校
            HashMap<String,HashMap<String,String>> school=
                new HashMap<String,HashMap<String,String>>();   
            school.put("基础班",jichu);
            school.put("就业班",jiuye);
    
            for (Iterator<String> it=school.keySet().iterator();it.hasNext(); ) {
                String roomName=it.next();
                System.out.println(roomName);
                HashMap<String,String> room=school.get(roomName);   
    
                    //取出班级里的学生
                for (Iterator<String> it2=room.keySet().iterator();it2.hasNext(); ) {
                    String id=it2.next();
                    String name=room.get(id);
                    System.out.println(id+"+"+name);
                }
            }
        }
    }

    注意:一般情况下,使用keySet更简便一些。它不涉及Map.Entry接口。

3—集合工具

一:Collections

Collections 是用于对集合进行操作的工具类。
该类没有构造函数,不需要创建对象。该类中所有方法都是静态的。
Collections 中的泛型比较复杂, 这里通过练习的形式只简单介绍方法的用法。

  1. Collections 的简单方法。

    import java.util.*;
    class Demo {
        public static void main(String [] args) {
            List<String> list=new ArrayList<String>();
            list.add("sss");
            list.add("aa");
            list.add("k");
            list.add("dddd");
            Collections.sort(list);          //对集合自然排序,没有返回值。
            System.out.println(list);
            Collections.sort(list,new Com());//对集合比较器排序,没有返回值。
            System.out.println(list);
    
            System.out.println(Collections.max(list));   //打印集合自然排序后的最大值。
            System.out.println(Collections.min(list,new Com()));//打印集合比较器排序后的最小值。
            System.out.println(Collections.binarySearch(list,"aa"));//打印二分查找元素的索引。
    
            Collections.fill(list,"A"); //将集合中所有元素替换成"A"。
            System.out.println(list);
            Collections.reverse(list);  //反转集合元素。
            System.out.println(list);
            Collections.replaceAll(list,"A","B");//将集合中所有"A"替换成“B”。
            System.out.println(list);
            Collections.swap(list,1,2); //置换两角标位的元素。
            System.out.println(list);
            Collections.shuffle(list);  //随机排列集合元素。
            System.out.println(list);
        }
    }
    class Com implements Comparator<String> {
            public int compare(String s1,String s2) {
            int num=new Integer(s1.length()).compareTo(new Integer(s2.length()));
            if (num==0)
                return s1.compareTo(s2);
            return num;
        }
    }

    注意:
     (1) ArrayList 不像TreeSet、TreeMap那样,它不可以传比较器作为参数。
     (2) 如果是自然排序,就直接 Collections.sort(list) ,如果是自定义排序,就需要加比较其对象参数:Collections.sort(list,new Com())
     (3)取最值时,元素在max方法中会重新排序,然后调用max方法会取出最右侧的值,调用min方法会取出最左侧的值。

  2. Collections 的reverseOrder方法:
    对于需要传入比较器的String类型集合对象,如TreeSet、TreeMap,
    如果传入比较器Com用于对字符串按长度排序,
    可以写成: TreeSet<String> ts=new TreeSet<String>(new Com());
    如果想要将排序改成长度降序,可以写成:
    TreeSet<String> ts=new TreeSet<String>(Collections.reverseOrder(new Com()));
    reverseOrder方法用于将顺序反转。

  3. Collections 的synchronizedCollection方法:
    集合中的很多方法都是线程不安全的,在多线程时容易出现安全问题。
    synchronizedCollection方法可以接受一个不安全的集合线程,返回一个安全的集合线程。
    和它类似的还有 synchronizedList方法,synchronizedMap方法,synchronizedSet方法。

二:Arrays 类

Arrays类中主要是对数组的操作方法,而且方法都是静态的。
例如,数组二分查找:binarySearch方法,数组排序:sort方法,数组转字符串:toString方法等。

  1. Arrays 中数组转集合的方法:asList方法。

    import java.util.*;
    class Demo
    {
        public static void main(String [] args)
        {
            String [] arr={"aa","cc","ff","acf"};
            System.out.println(Arrays.toString(arr));
            //将数组打印,形式如: [aa, cc, ff, acf]
    
            List<String> list=Arrays.asList(arr);
            System.out.println(list);
        }
    }

    注意:
     (1)Arrays 的asList方法将数组转成集合后,因为数组的长度是固定的,所以不支持使用集合的增删方法。
     (2)如果数组中的元素都是对象,数组转集合时,数组元素就可以直接转成集合中的元素。
      如果数组中的元素都是基本数据类型,数组转集合时,会将数组作为集合元素存入集合。
      所以数组转集合时,最好不是基本数据类型的数组。
     (3)数组编辑和就可以用集合中的一些方法操作数组。

  2. 集合转成数组:toArray(T [] t)方法。
    Collection接口中提供了toArray方法,可以将集合转成数组。
    toArray方法如果不带参数,就返回Object类型的数组,
    如果以一个数组为参数,就以参数类型为返回的数组类型。

    对于ArrayList集合: [“aa”,”cc”,”ff”,”acf”]
    可以返回一个String类型数组: String [] arr=list.toArray(new String [list.size()]);
    这个数组包含集合中的元素。
    注意:
     (1)toArray方法中传入一个新建的数组作为参数,这个数组的长度如果比集合长度小,
      该方法内部会自动新建一个长度刚好的数组。如果定义的数组长度比集合长度大,
      就不会新建数组,而是顺序存入元素,没有存值的角标位值为默认值null。
     (2)集合变数组是为了限制对元素的增删操作。

三:其他常见方法的应用
  1. 高级for循环:
    迭代器可以简写成高级for循环的形式。
    来看一个迭代器,

    Iterator<String> it=list.iterator();
    while (it.hasNext())
    {
        System.out.println(it.next());
    }
    

    此迭代器可以简写成:

    for (String s : list)
    {
        System.out.println(s);
    }
    

    这就是高级for循环的应用。
    高级for循环底层就是用的迭代器原理。

  2. 可变参数:
    方法中的参数数量可以变化。
    如:

    public static void show(int ... arr)
    {
        System.out.println(arr.length);
    }
    public static void main(String [] args)
    {
        show(3);        //打印1
        show(4,5,6,7,8);//打印5
    }
    

    此例中是往show方法中传入一个数组,并且自动将传入的int整数封装成一个数组。
    相当于

    int [] arr={4,5,6,7,8};
    show(arr);
    

    注意:在使用可变参数时,参数列表中可变参数要放在最后面,否则系统分不清哪些参数要封装进可变参数。

  3. 静态导入:
    导包后,调用方法可以不写类名调用,静态导包后,可以不写名字,直接用方法。
    形式:

    import static java.util.Arrays.*;
    class Demo
    {
        public static void main(String [] args)
        {
            int [] arr={4,2,3};
            sort(arr);      //Arrays.sort(arr);的简写
            System.out.println(Arrays.toString(arr));
        }
    }

    注意:
    (1) Arrays 类中有toString()方法,Object类中也有toString()方法,
      这时,就要表明是 Object.toString() 还是 Arrays.toString()。
    (2) import 后加static时,导入的是这个类的所有静态成员。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值