java学习总结-集合(collection)

本人正在学习java基础知识,非常感恩能够看到毕向东老师的java视频,他引领了我去思考问题,而不是生硬的去记一些知识点,下面是我对集合学习的总结和思考。

01-常用对象API(集合框架-概述).avi

问题1:什么是集合框架?

首先要理解集合这个词,它有另一个更加形象的名词:容器,所谓容器就是装载事物的器皿,而在java中最大的特征就是面向对象,所以可以推断出其实它就是用来装载对象的,便于我们去遍历和处理这些对象,关于框架的含义,其实就是它不是一个单独对象,而是有很多对象,并且相互存在区别和关系。

下图是目前集合的框架图,其中实线是具体的实现类,而虚线是接口或者工具类。

集合框架图

这里要说明的是,原来集合并没有怎么庞大的“家族”,在jdk的api中查看,jdk1.0的时候只有两个类即:Vector和Hashtable,因为后期发展,他们已经不能满足需要,所以2.0以后出现以上的框架图,而主要的优化就是容器丰富了和更加高效。就好比我们以前煮东西只需要一个大铁锅,但是因为后面物质和需求的发展,必须进行精细化,出现更加针对性的炊具。至于它们的优点和区别后面总结。

问题2:java有许多可以装载其它数据的“容器”,比如类、字符串缓冲池等,尤其是数组,不仅可以装载基本数据类型,也可以装载对象,跟我们要学习的集合存在某种程度的冲突,那么他们的区别在哪里?

数组的长度是固定,而集合的长度是可变的,数组一旦初始化以后,它所能装载的对象个数是不能超出它的长度的,而集合创建以后,可以任意的装载对象;具备的现实意义就是,大多数我们的数据是动态的,比如论坛网站的会员信息,门户网站的新闻,社交网站的状态,所以无法在程序中指定一个固定长度数值去装载它,只能要这里的集合去装载。

02-常用对象API(集合框架-体系&共性功能).avi

整个集合框架的学习必须参考上面的集合框架图,首先需要的介绍是Collection,为什么呢?如果你仔细查看上图会发现,它下面有很多分支(向上的尖头指向它),而这正是java继承的特点,就是事物不断向上抽取共性(实际就是指方法),一般顶层都是接口,它包含了子类的共性方法。而我们发现其实集合框架顶层其实只有Collection、Map和Iterator,而Iterator其实不是容器,这一块后面具体介绍,所以首先我们要了解顶层接口有那些共性的方法,然后在去看看不同子类有那些特殊的方法。

而容器从字面来说,它会具备的方法,无非添加、修改、删除、取出等主要功能,翻看API中java.util.Collection的方法:

1、 添加

boolean add(E e);

E可以理解为Object,其它是element(元素)的缩写。

boolean addAll(Colllection<? extends E> c);

<? extends E>是泛型,后面介绍。

2、 删除

boolean remove(Object o);

boolean removeAll(Collection<?> c);

void clear();

移除collection中所有元素。

3、 取出

int size();

Iterator iterator();

迭代器。

4、 判断

boolean isEmpty();

容器中不包含元素,返回true。

boolean contains(object o);

boolean containsAll(Collection<?> c);

如果此collection 包含指定 collection 中的所有元素,则返回true

retainAll(Collection<?> c);

仅保留此 collection 中那些也包含在指定collection 的元素(可选操作),其实就是数学中的取交集。

03-常用对象API(集合框架-方法演示_1).avi

对上面介绍的collection方法的进行演示,我们需要寻找它的一个子类,这里就用ArrayList来演示。

import java.util.*;

class CollectionDemo {

         publicstatic void main(String[] args){
                   //创建容器1
                   ArrayList<String>coll = new ArrayList<String>();

                   method1(coll);

                   //创建容器2
                   ArrayList<Person>coll2 = new ArrayList<Person>();

                   method2(coll2);

                   //创建容器2
                   ArrayList<Person>coll3 = new ArrayList<Person>();

                   method3(coll2,coll3);

         }

         publicstatic void method1(Collection<String> coll){

                   //添加 字符串
                   coll.add("abc");
                   coll.add("123");
                   coll.add("efg");
                   //打印容器
                   System.out.println("size:"+coll.size()+","+coll);

                   //包含
                   System.out.println(coll.contains("123"));

                   //删除
                   coll.remove("123");

                   System.out.println("size:"+coll.size()+","+coll);

                   //清除
                   coll.clear();
                   System.out.println("isEmpty:"+coll.isEmpty()+","+coll);
                   System.out.println("============method1=================");

         }
         publicstatic void method2(Collection<Person> coll){

                   coll.add(newPerson("zhangsan",23));
                   coll.add(newPerson("xiaoming",24));
                   coll.add(newPerson("lisi",25));
                   coll.add(newPerson("wangwu",26));              

                   System.out.println(coll);
                   //输出集合中每一个元素的字符串表现形式,即调用toString();

                   //包含
                   System.out.println(coll.contains(newPerson("lisi",25)));
                   System.out.println(coll.contains("123"));
                   //删除
                   coll.remove(newPerson("lisi",25));
                   //打印
                   System.out.println(coll);
                   System.out.println("============method2=================");
         }

         publicstatic void method3(Collection<Person> coll,Collection<Person>coll2){

                   coll2.add(newPerson("zhangsan",23));
                   coll2.add(newPerson("xiaoming",24));
                   //包含-容器
                   System.out.println(coll.containsAll(coll2));
                   //删除
                   //coll.removeAll(coll2);
                   //System.out.println(coll);
                   //合集
                   coll.retainAll(coll2);
                   System.out.println(coll);

                   System.out.println("============method3=================");

         }
}

class Person {
         privateString name;
         privateint age;

         Person(Stringname,int age){
                   this.name= name;
                   this.age= age;
         }

         publicString toString(){
                   returnname +":"+ age;
         }

         publicboolean equals(Object obj) throws ClassCastException{
                   if(!(obj instanceof Person))
                            thrownew ClassCastException("不是Person类");
                   Personp = (Person)obj;
                   returnname.equals(p.name) && age == p.age;
         }
}

注意:在contains和remove方法使用的时候,这里面包含了判断元素是否相等的前提,其实它是调用元素的equals方法,而我们自定义的类是从Object类中继承过来,它比较对象的地址,一般需要根据我们实际情况进行复写。

05-常用对象API(集合框架-迭代器使用).avi

1、 什么是迭代器?

可以看着获取容器中元素的方法。

2、 迭代器的获取?

Collection中调用iterator()方法。

import java.util.*;

class IteratorDemo {
         publicstatic void main(String[] args){
                   ArrayList<Person>coll = new ArrayList<Person>();

                   coll.add(newPerson("李四",23));
                   coll.add(newPerson("王五",24));
                   coll.add(newPerson("张三",22));

                   Iterator<Person>it = coll.iterator();
                   while(it.hasNext()){
                            System.out.println(it.next());
                   }
                   System.out.println("===================================");
                   for(Iterator<Person>it2 = coll.iterator();it2.hasNext();){
                            System.out.println(it2.next());
                   }
         }
}

06-常用对象API(集合框架-迭代器的原理).avi

1、 为什么要使用迭代器?

集合框架中包含List、Set分支,List下面有(ArrayList、LinkedList),Set下面有(HashSet、TreeSet、LinkedHashSet),它们是不同的容器,最本质的区别就是数据结构不同,即在内存中存放数据的规则不一样。这导致的一个问题,不同容器获取数据的方法是不一样的,比如AarryList是顺序的,可以按角标获取元素get(int index),而set是无序的,不能根据角标去获取元素;在容器使用上是非常不方便的,这时候就需要考虑建立一个统一方法解决这个问题,这就是迭代器的由来。

2、 迭代器的原理?

首先建立统一的方法供调用,实现方式就是让Collection继承了一个Iterable<E>接口,该接口包含iterator()方法,返回一个Iterator<T>接口,这样需要在Collection子类中实现iterator()方法,而实现这个方法最关键的是返回一个Iterator对象,应该怎么做:通过内部类继承Iterator接口,复写它的hasNext()next()方法,分别表示“如果仍有元素可以迭代,则返回
true”、“返回迭代的下一个元素。”而怎么实现这两个方法,需要根据自身的数据结构。

07-常用对象API(集合框架-List和Set的特点).avi

List:有序,元素可以重复的,元素都有角标。

Set:  无序,元素不可以重复。

08-常用对象API(集合框架-List集合的常见方法).avi

最重要的就是元素含有角标,所以可以按角标进行添加、删除、修改和获取。

1、  添加

void add(intindex, E element);

在列表的指定位置插入指定元素

voidadd(int index,Collection<? Extends E> c);

将指定 collection 中的所有元素都插入到列表中的指定位置

2、  删除

E remove(intindex);

移除列表中指定位置的元素。注意:方法返回被移除的元素。

3、  修改

E set(intindex,E element);

用指定元素替换列表中指定位置的元素;注意:返回替换前的元素。

4、  获取

E get(intindex);

返回列表中指定位置的元素。

intIndexOf(Object o);

返回此列表中第一次出现该指定元素的索引;如果此列表不包含该元素,则返回-1.

intlastIndexof(Object o);

返回比列表中最后出现该指定元素的索引;如果列表中不包含此元素,则返回-1.

List<E>subList(int fromIndex,int toIndex);

返回列表中指定的fromIndex和toIndex之间的部分视图。

importjava.util.*;

class ListDemo {

         public static void main(String[] args){
                   ArrayList<Person> coll= new ArrayList<Person>();

                   coll.add(new Person("王大",18));
                   coll.add(new Person("张三",20));
                   coll.add(new Person("王五",22));
                   coll.add(new Person("张三",20));
                   System.out.println(coll);

                   //添加
                   coll.add(1,new Person("李二",19));
                   System.out.println(coll);

                   //删除
                   System.out.println(coll.remove(1));
                   System.out.println(coll);

                   //修改
                   System.out.println(coll.set(0,newPerson("李大",17)));//返回替换前的元素
                   System.out.println(coll);

                   //获取
                   for(int i = 0; i <coll.size(); i++){
                            System.out.println(coll.get(i));
                   }

                   System.out.println(coll.indexOf(newPerson("小明",18)));
                   System.out.println(coll.indexOf(newPerson("张三",20)));
                   System.out.println(coll.lastIndexOf(newPerson("张三",20)));

                   System.out.println(coll.subList(1,3));
         }
}

09-常用对象API(集合框架-ListIterator接口).avi

import java.util.*;

class ListIteratorDemo {

     public static voidmain(String[] args){
              ArrayList<Person>coll = new ArrayList<Person>();

              coll.add(newPerson("王大",18));
              coll.add(newPerson("张三",20));
              coll.add(newPerson("王五",22));

              Iterator<Person>it = coll.iterator();
              while(it.hasNext()){
                       Person p= it.next();
                       if(p.age== 20){
                                 coll.add(newPerson("小明",23));
                       }
                       System.out.println(p);
              }
     }
}

如果在迭代器迭代的过程,集合操作列表元素,因为并发操作元素,这是会出现异常“ConcurrentModificationException”,这是需要Iterator的子接口ListIterator,该迭代器可以操作元素,只有List集合有。

import java.util.*;

class ListIteratorDemo {

     public static voidmain(String[] args){
              ArrayList<Person>coll = new ArrayList<Person>();

              coll.add(newPerson("王大",18));
              coll.add(newPerson("张三",20));
              coll.add(newPerson("王五",22));

              ListIterator<Person>it = coll.listIterator();
              while(it.hasNext()){
                       Person p= it.next();
                       if(p.age== 20){
                                 it.add(newPerson("小明",23));
                       }
                       System.out.println(p);
              }
     }
}

10-常用对象API(集合框架-List常用子类的特点).avi

List常用子类:

--Vector:数组接口,查询慢,增删慢,因为同步。

--ArrayList:数组结构,查询快,增删慢,非同步。

--LinkedList:链表结合,增删快,查询慢,非同步。

11-常用对象API(集合框架-数组和链表).avi

链表

而链表的区间不连续,查询数据时,索引的时间比数组会长。但是如上图所示,增删是比数组快,因为数值增删需要整体位移。

12-常用对象API(集合框架-Vector集合).avi

Vector是jdk1.0是推出的集合容器,在2.0以后即被其它容器取代,不做介绍。

13-常用对象API(集合框架-LinkedList集合).avi

LinkedList在使用上具有差异性:链表存在头和尾,所谓含有特有的方法可以对链表头和尾的元素进行操作。

1、  添加。

void addFirst(E e);

将指定元素插入此列表的开头。

void addLast(E e);

将指定元素添加到此列表的结尾。

boolean offer(E e);

将指定元素添加到此列表的末尾。

boolean offerFirst(E e);

在此列表的开头插入指定的元素。

boolean offerLast(E e);

在此列表的末尾插入指定元素。

两者的区别:在使用双端队列且有容量限制的时候,offer方法在遇到容量过小时,返回false,而add则抛出异常,建议使用offer。

2、  修改

E removeFirst();

移除并返回此列表的第一个元素。

E removeLast();

移除并返回此列表的最后一个元素。

3、  获取

E getFirst();

返回此列表的第一个元素。

E getLast();       

返回此列表的最后一个元素。

 E peek();

获取但不移除此列表的头。

 E peekFrist();

获取但不移除此列表的第一个元素;如果此列表为空,则返回null。

 E peekLast();

获取但不移除此列表的最后一个元素;如果此列表为空,则返回null。

E poll();

获取并移除此列表的头。

E pollFrist();

获取并移除此列表的第一个元素;如果此列表为空,则返回 null

E pollLast();

获取并移除此列表的最后一个元素;如果此列表为空,则返回 null

与remove的区别:当双端队列为空时remove抛出移除,而poll返回null。

14-常用对象API(集合框架-LinkedList集合-练习(堆栈和队列)).avi

import java.util.*;

class LinkedListDemo {

         publicstatic void main(String[] args){

                   DuiLie<String>duiLie = new DuiLie<String>();
                   duiLie.add("123");
                   duiLie.add("456");
                   duiLie.add("789");  

                  System.out.println(duiLie.size());

                   for(inti = 0;i < duiLie.size(); i++){
                            System.out.println(duiLie.get(i));
                   }

                   DuiZhan<String>duiZhan= new DuiZhan<String>();
                   duiZhan.add("123");
                   duiZhan.add("456");
                   duiZhan.add("789");       

                   System.out.println(duiZhan.size());

                   for(inti = 0;i < duiZhan.size(); i++){
                            System.out.println(duiZhan.get(i));
                   }
         }
}

class DuiLie<T> {

         privateLinkedList<T> coll ;
         DuiLie(){
                   coll= new LinkedList<T>();
         }
         publicvoid add(T obj){
                   coll.add(obj);
         }

         publicT get(int index){
                   returncoll.get(index);
         }

         publicint size(){
                   returncoll.size();
         }
}

class DuiZhan<T> {

         privateLinkedList<T> coll ;
         DuiZhan(){
                   coll= new LinkedList<T>();
         }
         publicvoid add(T obj){
                   coll.addFirst(obj);
         }

         publicT get(int index){
                   returncoll.get(index);
         }

         publicint size(){
                   returncoll.size();
         }
}
 

15-常用对象API(集合框架-ArrayList集合存储自定对象).avi

上面已经介绍,需要注意的是在涉及到元素比较的方法,如contains、indexOf、retainAll、remove(Oject obj)时,默认调用的是元素的equals方法。

16-常用对象API(集合框架-HashSet集合).avi

Set特点:无序,且不能重复的。

1、 Set集合怎么保证内部的元素是不重复的?

HashSet:首先比较元素的Hash码,即调用元素的hashCode()方法,如果不相同则元素不同;如果相同,则还需比较元素是否相同,即调用equals()方法,如果相同,则元素相同,不能装载,反之可以。

LinkedHashSet:同上。

TreeSet:调用元素的compareTo()方法或者是集合实现Comparator接口(优先compareTo()方法)。

2、  Set集合子类都有哪些?它们之间有什么区别?

--HashSet:无序,不重复。

--LinkedHashSet:有序,获取元素的顺序和存入一致。

--TreeSet:加载后的元素可以排序。

17-常用对象API(集合框架-哈希表_1).avi

哈希表是一种算法,HashSet集合就是按hashCode返回的结果去存储和查询数据。比如我们去查找数元素时,首先拿到元素的hashCode值,然后去查找此hashcode对应的内存。

18-常用对象API(集合框架-哈希表_2).avi

1、 为什么在jdk关于equlas方法的介绍时,建议equals相同时,hashcode也要相同?

因为部分集合HashSet、HashMap在添加元素时,调用equals的前提就是HashCode相同,如果equals()相同,反回来说明元素的HashCode一定是相同的。因为equals相同,而HashCode不同,存在的问题就是相同元素会添加到HashSet、HashMap中。

其实真正判读是否相同的依据还是equlas,只是从设计上来说,部分集合的逻辑是需要判断HashCode来存储数据的。

19-常用对象API(集合框架-HashSet存储自定义对象).avi

import java.util.*;

class HashSetDemo {
         publicstatic void main(String[] args){
                   HashSet<Person>coll = new HashSet<Person>();

                   coll.add(newPerson("小强",25));
                   coll.add(newPerson("小明",23));
                   coll.add(newPerson("小张",24));
                   coll.add(newPerson("小张",24));                    

                   for(Iterator<Person>it = coll.iterator();it.hasNext();){
                            System.out.println(it.next());
                   }
         }
}

class Person {
         Stringname;
         intage;

         Person(Stringname,int age){
                   this.name= name;
                   this.age= age;
         }

         publicString toString(){
                   returnname +":"+ age;
         }

         publicboolean equals(Object obj) {
                   if(!(obj instanceof Person))
                            thrownew ClassCastException("不是Person类");
                   Personp = (Person)obj;
                   returnname.equals(p.name) && age == p.age;
         }

         publicint hashCode(){
                   returnname.hashCode()+31*age;
         }
}

20-常用对象API(集合框架练习).avi

21-常用对象API(集合框架-LinkedHashSet集合).avi

特点:有序,hashSet的子类,就好像在hashSet基础上用一个链子根据元素存入的先后串联起来。

import java.util.*;

class LinkedHashSetDemo {
         publicstatic void main(String[] args){
                   //HashSet<String>hs = new HashSet<String>();

                   LinkedHashSet<String>hs = new LinkedHashSet<String>();

                   hs.add("xixi");
                   hs.add("hehe");
                   hs.add("haha");
                   hs.add("88");                    

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

22-常用对象API(集合框架-TreeSet集合).avi

特点:可以按照元素排序。

1、 TreeSet是怎么实现元素排序的?

有两种方式:

第一种,元素需要实现comparable接口,复写compareTo方法,该方法比较两个元素,返回值为int,如果大于1,则顺序;等于0表示相等;小于0,则倒序。这又叫元素的自然排序。

importjava.util.*;

classTreeSetDemo {
public static void main(String[] args){

           TreeSet<Person> ts = newTreeSet<Person>();

           ts.add(new Person("小强",25));
           ts.add(new Person("小明",23));
           ts.add(new Person("小张",24));
           ts.add(new Person("小李",23));                       

           for(Iterator<Person> it =ts.iterator();it.hasNext();){
                    System.out.println(it.next());
           }
}
}

classPerson implements Comparable{
String name;
int age;
Person(String name,int age){
           this.name = name;
           this.age = age;
}
public String toString(){
           return name +":"+ age;
}
public boolean equals(Object obj){
           if (!(obj instanceof Person))
                    throw newClassCastException("不是Person类");
           Person p = (Person)obj;
           return name.equals(p.name) &&age == p.age;
}
public int hashCode(){
           return name.hashCode()+31*age;
}
public int compareTo(Object obj){
           /*
           if (obj.getClass() != Person){
                    throws newClassCastException("类型错误");
           }
           */

           //健壮性判断
           if (!(obj instanceof Person))
                    throw newClassCastException("不是Person类");

           Person p = (Person)obj;
           //return age - ((Person)obj).age;
           int temp = this.age - p.age;
           return temp == 0?this.name.compareTo(p.name):temp;
}
}

第二种,是集合实现Comparator接口,实现compare()方法,传入两个元素,比较大小,规则如上。

importjava.util.*;

classTreeSetDemo {
public static void main(String[] args){

           TreeSet<Person> ts = newTreeSet<Person>(new MyComparator());

           ts.add(new Person("小强",25));
           ts.add(new Person("小明",23));
           ts.add(new Person("小张",24));
           ts.add(new Person("小李",23));                       

           for(Iterator<Person> it =ts.iterator();it.hasNext();){
                    System.out.println(it.next());
           }
}
}

classPerson {
String name;
int age;
Person(String name,int age){
           this.name = name;
           this.age = age;
}
public String toString(){
           return name +":"+ age;
}
public boolean equals(Object obj){
           if (!(obj instanceof Person))
                    throw newClassCastException("不是Person类");
           Person p = (Person)obj;
           return name.equals(p.name) &&age == p.age;
}
public int hashCode(){
           return name.hashCode()+31*age;
}
}

classMyComparator implements Comparator<Person> {
public int compare(Person o1,Person o2){
           int temp = o1.age -o2.age;
           return temp == 0?  o1.name.compareTo(o2.name) : temp;
}
}

24-常用对象API(集合框架-TreeSet集合-二叉树).avi

25-常用对象API(集合框架-TreeSet集合练习-字符串长度排序).avi

要点:集合自身的比较性优先于元素的比较性。

import java.util.*;

class TreeSetTest {
         publicstatic void main(String[] args){

                   TreeSet<String>ts = new TreeSet<String>(new ComparatorByLength());

                   ts.add("abc");
                   ts.add("adcdef");
                   ts.add("ac");
                   ts.add("abcd");                          

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

class ComparatorByLength implementsComparator<String> {
         publicint compare(String o1,String o2){
                   returno1.length() - o2.length();
         }
}

import java.util.*;

class TreeSetTest {
         publicstatic void main(String[] args){

                   TreeSet<String>ts = new TreeSet<String>(new ComparatorByLength());

                   ts.add("abc");
                   ts.add("adcdef");
                   ts.add("ac");
                   ts.add("ab");
                   ts.add("abcd");                          

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

class ComparatorByLength implementsComparator<Object> {
         publicint compare(Object o1,Object o2){
                   Strings1 = (String)o1;
                   Strings2 = (String)o2;
                   inttemp = s1.length() - s2.length();
                   returntemp == 0? s1.compareTo(s2) : temp;
         }
}
 

01-常用对象API(集合框架-Map集合特点&常用方法).avi

1、 Map集合的特点,与colllection的区别?

Map集合一次可以添加一对元素;collection一次添加一个元素。

Map称为双列集合;collection称为单列集合。

Map集合存放的是键值对,它们是映射关系,不能包含重复的键,一个键最多映射到一个值。

2、 有哪些常用方法?

1、 添加

V put(K key,V value);

返回前一个和key关联的值,如果没有则为null。

2、 删除

void clear();

清空Map集合。

V remove(K key);

根据键删除集合中的键值对。

3、 修改

4、 获取

V get(K key);   

通过键获取值,如果没有该键,则返回null。

it size();

获取键值对的个数。

5、 判断

boolean containsKey(k key);

集合中是否包含该键。

boolean containsValue(V value);

集合中是否包含该值。

boolean isEmpty();

集合是否为空。

02-常用对象API(集合框架-常用方法演示).avi

import java.util.*;

class MapDemo {

         public static voidmain(String[] args){
                   //创建容器
                   HashMap<Integer,String>hm = new HashMap<Integer,String>();

                   //添加
                   hm.put(1,"abc");
                   hm.put(3,"efg");
                   hm.put(2,"hij");
                   hm.put(4,"小李");           

                   System.out.println(hm);

                   System.out.println(hm.put(2,"小明"));

                   System.out.println(hm);

                   //删除
                   hm.remove(4);
                   System.out.println(hm);          

                   //判断
                   System.out.println(hm.containsKey(2));
                   System.out.println(hm.containsKey(4));
                   System.out.println(hm.containsValue("abd"));
                   System.out.println(hm.containsValue("abc"));
                   System.out.println(hm.containsValue(hm.isEmpty()));           

                   //获取
                   System.out.println(hm.size());
                   System.out.println(hm.get(1));
                   System.out.println(hm.get(4));
         }
}
 

03-常用对象API(集合框架-重点方法keySet演示图解).avi

1、 keySet()方法的介绍和使用?

Set<K> keyset();

返回此映射中所包含的键的Set视图。

获取到Set集合,然后通过迭代器的next()方法获取到每一个键值,再通过Map的get(K key)方法,根据每一个键获取到值。

import java.util.*;

class KeySetDemo {
         publicstatic void main(String[] args) {
                   //创建容器
                   HashMap<Integer,String>hm = new HashMap<Integer,String>();

                   //添加
                   hm.put(1,"abc");
                   hm.put(3,"efg");
                   hm.put(2,"hij");
                   hm.put(4,"小李");

                   //调用keySet()返回set集合
                   Set<Integer>set = hm.keySet();

                   //调用迭代器,遍历Set元素
                   for(Iterator<Integer>it = set.iterator();it.hasNext();){
                            Integerkey = it.next();
                            //通过Map的get(key)方法,再获取到值
                            Stringvalue = hm.get(key);
                            System.out.println(key+":"+value);
                   }
         }
}
 

04-常用对象API(集合框架-重点方法entrySet演示图解).avi

1、 entrySet()方法的介绍,与keySet()方法的区别?

Set<Map.Entry<K,V>>entrySet();

返回此映射所包含的映射关系的set视图。

与keySet()的区别:它返回的也是Set集合,但是集合中包含的元素却不是

由Map的key值组成,它是Map中key和value的映射关系,它是一个明确类型,类名为Map.Entry<k,v>,可以看出它是Map内部类,可以通过Set的迭代器来获取,在迭代过程中,它自身的方法可以获取key(getKey())和value(getValue()),也可以修改value值(setValue())。

Jdk中关于Map.Entry<k,v>的说明:映射项(键-值对)。Map.entrySet 方法返回映射的 collection 视图,其中的元素属于此类。获得映射项引用的唯一 方法是通过此 collection 视图的迭代器来实现。这些 Map.Entry 对象仅 在迭代期间有效;更确切地讲,如果在迭代器返回项之后修改了底层映射,则某些映射项的行为是不确定的,除了通过 setValue 在映射项上执行操作之外。

import java.util.*;

class EntrySetDemo {
          public static voidmain(String[] args) {
                   //创建容器
                   HashMap<Integer,String>hm = new HashMap<Integer,String>();

                   //添加
                   hm.put(1,"abc");
                   hm.put(3,"efg");
                   hm.put(2,"hij");
                   hm.put(4,"小李");

                   //调用keySet()返回set集合
                   Set<Map.Entry<Integer,String>>set = hm.entrySet();

                   //调用迭代器,遍历Set元素
                   for(Iterator<Map.Entry<Integer,String>>it = set.iterator();it.hasNext();){
                            Map.Entry<Integer,String>entry = it.next();

                            Integerkey = entry.getKey();

                            //修改
                            if(key==2)
                                      //hm.put(5,"++++++");迭代过程中集合不能操作元素
                                      entry.setValue("=======");

                            System.out.println(key+":"+entry.getValue());
                   }
          }
}

05-常用对象API(集合框架-方法values演示).avi

1、 values()方法介绍?

Collection<V> values();

返回此映射所包含的值的Collection视图。

它可以看做是keySet()对应的方法;keySet()返回的是key值的集合,因为Map中key值不能重复,所以返回的是Set集合;而values()返回的是Map中value值的集合,因为value可以重复,所以返回集合为Collection;而entrySet()返回的是两者的关系。

import java.util.*;

class ValuesDemo {
          public static voidmain(String[] args) {
                   //创建容器
                   HashMap<Integer,String>hm = new HashMap<Integer,String>();

                   //添加
                   hm.put(1,"abc");
                   hm.put(3,"efg");
                   hm.put(2,"hij");
                   hm.put(4,"小李");

                   //调用valuest()返回Collection集合
                   Collection<String>values = hm.values();

                   //调用迭代器,遍历Collection元素
                   for(Iterator<String>it = values.iterator();it.hasNext();){

                            System.out.println(it.next());
                   }
          }
}

06-常用对象API(集合框架-Map集合-常见子类对象).avi

1、 Map的常见子类对象及特点?

--HashTable:jdk1.0推出,内部结构哈希表,同步的,不允许null作为键,null作为值。

--Properties:用来存储键值对型配置文件的信息,可以和IO技术相集合。

--HashMap:内部结构是哈希表,不是同步的,允许null作为键,null作为值。

--TreeMap:内部结构是二叉树,不是同步的。

--LinkedHashMap:内部结构是链表,不是同步的。

不同Map容器在实际应用中,最大的区别就是可以对键值对不同的处理,比如HashMap会对键做是否相同的判断,即判断hashCode和equlas,和HashSet相同。

07-常用对象API(集合框架-Map集合-HashMap存储自定义对象).avi

特点:HashMap会对键做是否相同的判断,即判断hashCode和equlas,和HashSet相同。

importjava.util.*;

classHashMapDemo {
        public static void main(String[] main){
                  //创建容器,存放个人信息和所属城市
                  HashMap<Person,String>hm = new HashMap<Person,String>();

                  //添加
                  hm.put(new Person("小明",23),"上海");
                  hm.put(new Person("小李",22),"江苏");
                  hm.put(new Person("老王",44),"北京");
                  hm.put(new Person("小强",32),"浙江");
                  //修改
                  hm.put(new Person("小强",32),"海南");

                  //调用entrySet()返回set集合
                  Set<Map.Entry<Person,String>>entrySet = hm.entrySet();

                  //set迭代器
                  for(Iterator<Map.Entry<Person,String>>it = entrySet.iterator();it.hasNext();){
                           //获取set中元素
                           Map.Entry<Person,String>entry = it.next();
                           //获取key值
                           Person key =entry.getKey();
                           //获取value值
                           String value =entry.getValue();

                           System.out.println(key.name+":"+key.age+",地址:"+value);
                  }
        }
}

class Person {
        String name;
        int age;

        Person(String name,int age){
                  this.name = name;
                  this.age = age;
        }

        public String toString(){
                  return name +":"+age;
        }

        public boolean equals(Object obj){
                  if (!(obj instanceof Person))
                           throw newClassCastException("错误类型");
                  Person p = (Person)obj;
                  return name.equals(p.name)&& age == p.age;
        }

        public int hashCode(){
                  return name.hashCode()+31*age;
        }
}

08-常用对象API(集合框架-Map集合-TreeMap存储自定义对象).avi

特点:TreeMap会对键做大小判断,即元素中compareTo()方法的结果或者是TreeMap中Comparator接口compare()方法的结果,TreeMap相同。

import java.util.*;

class TreeMapDemo {
        public static voidmain(String[] main){
                  //创建容器,存放个人信息和所属城市
                  TreeMap<Person,String>tm = new TreeMap<Person,String>(new MyComparator());

                  //添加
                  tm.put(newPerson("小明",23),"上海");
                  tm.put(newPerson("小李",22),"江苏");
                  tm.put(newPerson("老王",44),"北京");
                  tm.put(newPerson("小强",32),"浙江");
                  tm.put(newPerson("小强",19),"北京");                          

                  //调用entrySet()返回set集合
                  Set<Map.Entry<Person,String>>entrySet = tm.entrySet();

                  //set迭代器
                  for(Iterator<Map.Entry<Person,String>>it = entrySet.iterator();it.hasNext();){
                           //获取set中元素
                           Map.Entry<Person,String>entry = it.next();
                           //获取key值
                           Personkey = entry.getKey();
                           //获取value值
                           Stringvalue = entry.getValue();

                           System.out.println(key.name+":"+key.age+",地址:"+value);
                  }
        }
}

class MyComparator implements Comparator<Person> {
        public intcompare(Person o1,Person o2){
                  int temp =o1.age -o2.age;
                  return temp== 0?  o1.name.compareTo(o2.name) : temp;
        }
}

09-常用对象API(集合框架-Map集合-LinkedHashMap&关联源码).avi

特点:有序,获取键值对的顺序和添加顺序一致。

import java.util.*;

class LinkedHashMapDemo {
        public static voidmain(String[] main){
                  //创建容器,存放个人信息和所属城市
                  //HashMap<Person,String>hm = new HashMap<Person,String>();
                  LinkedHashMap<Person,String>hm = new LinkedHashMap<Person,String>();

                  //添加
                  hm.put(newPerson("小明",23),"上海");
                  hm.put(newPerson("小李",22),"江苏");
                  hm.put(newPerson("老王",44),"北京");
                  hm.put(newPerson("小强",32),"浙江");       

                  //调用entrySet()返回set集合
                  Set<Map.Entry<Person,String>>entrySet = hm.entrySet();

                  //set迭代器
                  for(Iterator<Map.Entry<Person,String>>it = entrySet.iterator();it.hasNext();){
                           //获取set中元素
                           Map.Entry<Person,String>entry = it.next();
                           //获取key值
                           Personkey = entry.getKey();
                           //获取value值
                           Stringvalue = entry.getValue();

                           System.out.println(key.name+":"+key.age+",地址:"+value);
                  }
        }
}
 

10-常用对象API(集合框架-Map集合练习-记录字母次数思路).avi

练习:字符串“fdgavcbsacdfs“获取字符串中,每一个字母出现的次数;要求打印的结果是:a(2)b(1)…..;

11-常用对象API(集合框架-Map集合练习-记录字母次数代码).avi

import java.util.*;

class CharCountInString {

        public static voidmain(String[] main){

                  //待处理的字符串
                  String str ="fdgavcbsacdfs";

                  showCharCount(str);
        }

        public static voidshowCharCount(String s){
                  //首先需要遍历字符串每一个字符。放在数组中最好,当然也可以通过截取的方式。

                  //把字符串变成字符数组,便于遍历
                  char[] ch =s.toCharArray();

                  //创建Map集合,因为是从a开始的,所以是按键排序的,用TreeMap
                  TreeMap<Character,Integer>tm = new TreeMap<Character,Integer>();

                  //for循环遍历
                  for(int i=0;i<ch.length; i++){
                           /*接着是处理逻辑,遍历字符是否出现过,出现:在这个字符后面计数+1,这让我们想到键值对的概率,所以需要一个Map集合*/

                           //把遍历到的每一个元素添加到Map中,但是Map的性质就是出现重复key,是直接用新的value值覆盖。
                           //所以添加要判断集合是否已经有该key值
                           charkey = ch[i];

                           if (tm.containsKey(key) ){
                                    //如果有,则需要获取他的value值,value用来计数,需要在这个基础上+1,
                                    Integervalue = tm.get(key);
                                    value= value + 1;

                                    //把key和新的value值添加到集合中
                                    tm.put(key,value);
                           }else{
                                    //如果没有,则value为初始值1
                                    tm.put(key,1);
                           }

                  }

                  //遍历结束,拿到Map集合,根据要求的打印形式,把键和值打印出来
                  Set<Map.Entry<Character,Integer>>entrySet = tm.entrySet();

                  for(Iterator<Map.Entry<Character,Integer>>it = entrySet.iterator();it.hasNext();){
                           Map.Entry<Character,Integer>entry = it.next();
                           Characterkey = entry.getKey();
                           Integervalue = entry.getValue();

                           System.out.print(key+"("+value+")");
                  }

        }
}

12-常用对象API(集合框架-Map集合练习-Map查表法).avi

有映射关系,都可以用Map

时间: 2024-10-07 05:29:31

java学习总结-集合(collection)的相关文章

java学习之集合家族2

集合体系 一.数据结构 List集合储存数据结构 <1>堆栈结构 特点:先进后出 <2>队列结构 特点:先进先出 <3>数组结构 特点:查询快,增删慢 <4>链表结构 特点:增删快,查询慢 二.List接口 Java.util.List 接口(集合)extends Collection 接口 List接口的特点: 允许存储重复元素 是一个有序集合(存储元素的顺序和取出元素的顺序一致)存123 取出123 有索引,包含一些带索引的特有方法(有三种遍历方式:迭代

Java学习:集合双列Map

数据结构 数据结构: 数据结构_栈:先进后出 入口和出口在同一侧 数据结构_队列:先进先出 入口和出口在集合的两侧 数据结构_数组: 查询快:数组的地址是连续的,我们通过数组的首地址可以找到数组,通过数组的索引可以快速的查找某一个元素. 增删慢:数组的长度是固定的,我们想要增加/删除一个元素,必须创建一个新数组,把原数组的数据复制过来 例: int[] arr = new int[]{1,2,3,4}; 要把数组索引是3的元素删除 必须创建一个新的数组,长度是原数组的长度-1 把原数组的其它元素

java学习笔记—集合之Map集合

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; text-align: center; font: 12.0px Times } p.p2 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px "Songti SC" } p.p3 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Times } p.p4 { margin: 0.0px 0.0px 0.0px 0.0

Java学习关于集合框架的基础接口--Collection接口

 集合框架(Collection  Framework)是Java最强大的子系统之一,位于java.util 包中.集合框架是一个复杂的接口与和类层次,提供了管理对象组的最新技术.Java集合框架标准化了程序处理对象组的方式. 集合框架在设计上需要满足几个目标.首先,框架必须是高性能的.基本集合(动态数组.链表.树以及哈希表)的实现是高效率的.很少需要手动编写这些数据引擎中的某一个.其次,框架必须允许不同类型的集合以类似的方式进行工作,并且具有高度的互操作性.再次,扩展或改造必须易于实现.为了满

Java学习笔记----------集合Set

Java集合-----Set集合:就像一种容器,可以把多个对象放进该容器中.Java集合分为:Set.List.Map三种体系. Set:无序的,不可重复的: List:有序的,可重复的: Map:代表有映射关系的集合,Map保存的每一项数据都是key-value对.注意:Java 5后添加了Queue体系,代表一种队列集合实现. 集合和数组对比:1.数组一旦初始化,长度不可变:2.数组无法保存具有映射关系的数据,例如成绩表:语文---79:3.数组的元素可以是基本类型的值,也可以是对象,而集合

Java学习之集合框架(1) &lt;好程序员特训营&gt;

<A href="http://www.goodprogrammer.org/" target="blank">android培训</a>------我的java笔记,期待与您交流! 集合框架图: 1. Collection Collection定义了集合框架的共性功能. 1)添加  add(e);  addAll(collection); 2)删除  remove(e);  removeAll(collection);  clear();

java学习日记 集合框架

集合框架 有两大接口  一个是 Collection (类集 )与Map (映射): collection 下有两大接口  一个是List (列表) 另一个是Set(集合) List (列表):ArrayList 基于数组实现的动态列表    动态数组 : LinkedList 基于链表实现的列表      双向循环链表 Vector 向量   ------>stack栈           与线程相关: Set (集合) :TreeSet       通过树实现的集合  有序集合 HashSe

Java学习之集合框架(2) &lt;好程序员特训营&gt;

<A href="http://www.goodprogrammer.org/" target="blank">android培训</a>------我的java笔记,期待与您交流! 1.Set接口 Set集合不允许重复元素,是因为Set判断两个对象相同不是使用==运算符,而是根据equals方法.即两个对象用equals方法比较返回true,Set就不能接受两个对象. public class SetDemo { public static

Java学习日记 集合

一.接口Map<K,V>1.V put(K key, V value)2.int size()3.public class HashMap<K, V> implements Map<K, V>按键的哈希值存储,put时,key相同会发生替换,一个key值只能对应一个value4.Map的遍历Map没有迭代器,通过keyset()和values()遍历Set<K> keySet()Collection<V> values()//5.Set<M