集合部分的总结

来源:互联网 发布:网络求职招聘 编辑:程序博客网 时间:2024/06/05 15:15

集合部分的总结

Java中有一些类,这些类有一些共同特点,这些类都是一个一个的容器,容器的特点是可以装东西,所以这些类就可以用来装东西(装对象),这些类就是集合类。根据不同的数据结构,集合分为单列集合和双列集合。

单列集合的顶层根接口是Collection,它拥有两个子接口,分别是List接口和Set接口。

其中List接口包含了2个常用的实现类,分别是:ArrayList、LinkedList.另外还有Vector,不过因为效率不高,使用的频率不是很多

Set接口包含了2个常用的实现类,分别是:HashSet、TreeSet

双列集合的顶层根接口是Map,Map下面有两个常用的实现类:HashMap、TreeMap

我总结的集合使用的一般步骤:

1、创建集合

2、创建元素对象

3、把创建好的元素对象添加到集合中去

4、开始遍历


1.单列集合

单列集合的结构关系如下图所示:


可见,Collections是顶层父接口,其他接口或实现类都是它的子民

Collections身上的方法有:

1、添加功能

      boolean add(Object obj):向集合中添加一个元素。

      boolean addAll(Collection c):向集合中添加一个集合的元素。

2、删除功能

      void clear():删除集合中所有的元素。

      boolean remove(Object obj):删除集合中指定的元素。

      boolean removeAll(Collection c):删除集合中指定的集合元素。

3、判断功能

      boolean isEmpty():判断集合是否为空。

      boolean contains(Object obj):判断集合是否包含指定的元素。

      boolean containsAll(Collection c):判断集合是否包含指定的集合中的元素。

4、遍历功能

      Iterator:迭代器。

      hasNext():判断是否还有元素

      next():获取下一个元素

5、长度功能

      int size():获得集合的元素个数。

6、交集功能

      boolean retainAll(Collection c):判断集合中是否有相同的元素。

7、转换功能

      Object[] toArray():把集合变成数组。

1.1 List的特点

List集合里面的元素是有序的,有索引的,可以重复的,一般要求元素可以是有序的,可以重复的,可以考虑使用List集合。

具体的应用场景:

如果实际需求要求要增删操作很多,并且要求效率要高,那么就使用LinkedList(因为LinkedList底层数据结构是链表数据结构)。

如果实际需求要求查询操作很多,并且要求效率高,那么就使用ArrayList(因为ArrayList底层数据结构是数组数据结构)

使用ArrayList的例子:

       //1 创建集合容器对象        ArrayList<String> al = newArrayList<String>();               //2创建元素对象        String s1 = "s1";        String s2 = "s2";        String s3 = "s3";               //3把创建好的元素对象,添加到集合当中        al.add(s1);        al.add(s2);        al.add(s3);               //4 遍历等操作        //第一种遍历方式(使用Iterator,单列集合通用方式)        Iterator<String> iterator =al.iterator();        while(iterator.hasNext()) {             String s = iterator.next();            System.out.println(s);        }               //第二种遍历方式,List集合特有        ListIterator<String> listIterator= al.listIterator();        while(listIterator.hasNext()) {            String s =  listIterator.next();            System.out.println(s);        }               //第三种遍历方式,List集合特有        for(intx=0;x<al.size();x++){            System.out.println(al.get(x));        }               //第四种遍历方式        for (String s: al) {            System.out.println(s);        }

使用LinkedList的例子

    

  //1创建集合容器对象        LinkedList<String> linkedList = newLinkedList<String>();               //2创建元素对象        String s1 = "s1";        String s2 = "s2";        String s3 = "s3";               //3把创建好的元素对象放到集合里面去        linkedList.add(s1);        linkedList.add(s2);        linkedList.add(s3);               //或者使用特有方法        linkedList.addFirst(s1);        linkedList.addFirst(s2);        linkedList.addFirst(s3);               //4遍历操作        Iterator<String> it =linkedList.iterator();        while (it.hasNext()){            String s =  it.next();            System.out.println(s);        }

1.2 Set集合的特点

Set集合的特点是,Set里面的元素是无序的,是不可重复的。无序的意思是:元素对象存进去和取出来的顺序不一致,而实际上元素存进去时,是按照一定的规则存放的。

一般如果要求元素不能重复,就可以使用Set集合。

具体的应用场景:

1、  如果仅仅是要求元素不能重复,那就可以直接使用HashSet

2、  如果要求元素不能重复,并且还要求能够排序,那就可以使用TreeSet

#HashSet

HashSet的底层数据结构是哈希表,HashSet存放元素时,想要存储唯一的元素,那么必须使得元素对象所属的类,重写两个方法:hashCode()和equals(Object obj)方法。

假设使用HashSet来存放Person对象,则代码如下:

定义一个Person类,这个类实现了hashCode()方法和equals方法,如下所示:

class Person{private String name;    private String weibo;    public String getName() {        returnname;    }      ……………………………………..……………………    @Override    publicinthashCode() {        finalint prime =31;        int result =1;        result = prime * result +getOuterType().hashCode();        result = prime * result + ((name == null) ? 0 : name.hashCode());        result = prime * result + ((weibo == null) ? 0 : weibo.hashCode());        return result;    }    @Override    public boolean equals(Object obj) {        if (this == obj)            return true;        if (obj == null)            return false;        if(getClass() != obj.getClass())            return false;        Person other = (Person) obj;        if(!getOuterType().equals(other.getOuterType()))            return false;        if (name == null) {            if (other.name != null)                return false;        } else if (!name.equals(other.name))            return false;        if (weibo == null) {            if (other.weibo != null)                return false;            } elseif (!weibo.equals(other.weibo))                return false;            return true;        }    private Demo getOuterType(){        return Demo.this;    }       }

使用HashSet的例子

        //创建HashSet集合容器        HashSet<Person> hashSet = newHashSet<Person>();               //创建元素对象        Person p1 = new Person("曾小贤", "zengxiaoxian@sina.com");        Person p2 = new Person("胡一菲", "huyifei@sina.com");        Person p3 = new Person("关谷", "guangu@sina.com");               //把创建好的元素对象,添加到HashSet里面去        hashSet.add(p1);        hashSet.add(p2);        hashSet.add(p3);               //遍历操作        Iterator<Person> iterator =hashSet.iterator();        while(iterator.hasNext()) {            Person person =  iterator.next();            System.out.println("姓名="+person.getName() + " 微博=" + person.getWeibo());        }    }

HashSet使用要点

之所以是使用HashSet,是因为要求存放的元素对象是不重复的,而且不必要排序,那么就使用HashSet。一般元素之间的属性值一样时,就认为是重复元素。所以,必须重写equals(Objectobj)方法,为了效率,还必须重写hashCode()方法。不过,工作中貌似我都是直接使用eclipse的自动生成代码功能~~~

#使用TreeSet的例子

实际上,TreeSet保证元素唯一,并不是靠元素对象的hashCode()方法和equals(Object obj)方法,而是靠下面两种办法来保证。

第一种方法:

使得元素对象对应的类,来实现一个接口:Comparable,并且实现Comparable接口的唯一的一个方法:compareTo方法

      这个方法返回值是0的话,就表示TreeSet里面有这个元素了,就不让存进去。返回值不是0,那就表示这个元素可以存进来,例如:返回值是1,和返回值是 -1,顺序刚好相反!

      要想在TreeSet里面存对象,使用第一种方法:1,使元素对象实现Comparable接口

class Person implements Comparable<Person>{        private String name;        private String weibo;             @Override        public int compareTo(Person o) {            int num1 = this.name.compareTo(o.name);            if (num1==0){  // 如果比较的姓名一样的话,继续比较微博                int num2 = this.weibo.compareTo(o.weibo);                return num2;            }else{  //如果比较的姓名不一样,那就直接返回即可                return num1;            }        }    } 开始使用TreeSet存放//创建TreeSet集合容器TreeSet<Person> treeSet = new TreeSet<Person>();       //创建元素对象<pre name="code" class="java"> Person p1 = new Person("曾小贤", "zengxiaoxian@sina.com"); Person p2 = new Person("胡一菲", "huyifei@sina.com");
//下面这个p3,实际上是存不进去的
<pre name="code" class="java"><pre name="code" class="java">Person p3 = new Person("曾小贤", "zengxiaoxian@sina.com");
//把创建好的元素对象,添加到TreeSet集合里面去treeSet.add(p1);treeSet.add(p2);treeSet.add(p3); //遍历操作Iterator<Person>iterator = treeSet.iterator();while(iterator.hasNext()) { Person person = iterator.next(); System.out.println("姓名="+person.getName() + " 微博=" + person.getWeibo());}

 

第二种方法:

使用第二种方法,不必要使元素对象实现什么接口,只需要在创建TreeSet对象的时候,使用带Comparator参数的构造函数即可,具体代码如下:

TreeSet<Person> treeSet = new TreeSet<Person>(new Comparator<Person>() {    public int compare(Person o1,Person o2) {        int n1 =o1.getName().compareTo(o2.getName());//如果姓名不一样,那就表示两个人是两个不同对象,可以直接存放进去        if (n1 != 0) {            return n1;//如果姓名一样,那就还要比较微博是否一样,把比较结果返回即可        }else{            return o1.getWeibo().compareTo(o2.getWeibo());                }            }        });

剩下的代码,和第一种方法的一样,这里就不重复写了

 

2. Map集合

Map集合是双列集合,里面存放的是键值对。Map是一个接口,Map接口下面有两个常用的实现类:HashMap和TreeMap。

     其实,只看名字,也能向导HashMap和之前学的HashSet有莫大的关联。HashMap可以保证键值对中的键唯一,那么键对应的类,必须重写hashCode()方法,和equals(Object obj)方法,没错,和HashSet一样的做法!这里要注意的是,Map只能存放引用类型的键值对,不能存放基本数据类型的键值对,之所以有时会看到的确存放了基本数据类型的键值对,那是因为JDK1.5之后的新特性,自动装箱了。

     还可以想象得到,TreeMap和之前学的TreeSet有莫大的关联,可以猜得到,TreeMap可以保证键值对中的键排序、唯一,那么键对应的类,必须实现Comparable接口,或者在使用TreeMap时,在创建TreeMap对象的时候,需要使用有Comparator参数的构造函数。

      关于Map有哪些方法,这里就不详述了,这里就写关键代码。

     

2. 使用HashMap的例子

       

        HashMap<Person,String> hashMap = new HashMap<Person, String>(); <pre name="code" class="java"><pre name="code" class="java">        Person p1 = new Person("曾小贤", "zengxiaoxian@sina.com");        Person p2 = new Person("胡一菲", "huyifei@sina.com");
hashMap.put(p1, "上班"); hashMap.put(p2, "休息"); //遍历1 Set<Person> keySet =hashMap.keySet(); Iterator<Person> iterator =keySet.iterator(); while(iterator.hasNext()) { Person person = iterator.next(); System.out.println("key="+person + "value=" + hashMap.get(person)); } //遍历2 Set<Entry<Person, String>>es = hashMap.entrySet(); Iterator<Entry<Person,String>> iterator2 = es.iterator(); while(iterator2.hasNext()) { Entry<Person,String> entry =iterator2.next(); System.out.println("key="+entry.getKey()+"value=" + entry.getValue()); }

注意:这里的Person如果想要保证唯一,必须重写Person类的hashCode()方法和equals(Object obj)方法。

使用TreeMap的例子

第一种方式

注意:这里用PersonKey了,并且Person类必须实现Comparable接口

    TreeMap<Person,String> treeMap = new TreeMap<Person,String>(); <pre name="code" class="java"><pre name="code" class="java"><pre name="code" class="java">    Person p1 = new Person("曾小贤", "zengxiaoxian@sina.com");    Person p2 = new Person("胡一菲", "huyifei@sina.com");
treeMap.put(p1, "上班"); treeMap.put(p2, "休息"); //遍历方式1 Set<Person> keySet = treeMap.keySet(); Iterator<Person> iterator =keySet.iterator(); while(iterator.hasNext()){ Person person = iterator.next(); System.out.println("key=" + person+ "value=" + treeMap.get(person)); } //遍历方式2 Set<Entry<Person, String>> es =treeMap.entrySet(); Iterator<Entry<Person, String>>iterator2 = es.iterator(); while(iterator2.hasNext()){ Entry<Person, String> entry =iterator2.next(); System.out.println("key="+entry.getKey()+ "value=" + entry.getValue());}

第二种方式

注意,这里的Person,不必实现Comparable接口,即使实现了,系统也不会调用Person类的comapreTo方法,但是,这里要求在创建TreeMap对象的时候,使用有参构造方法,参数为Comparator对象

    TreeMap<Person,String>treeMap = new TreeMap<Person,String>(newComparator<Person>() {    @Override    public int compare(Person o1, Person o2) {    int n1 =o1.getName().compareTo(o2.getName());    if (n1!=0) {        return n1;    }else{        returno1.getWeibo().compareTo(o2.getWeibo());        }    }    });  <pre name="code" class="java"><pre name="code" class="java"><pre name="code" class="java"><pre name="code" class="java">    Person p1 = new Person("曾小贤", "zengxiaoxian@sina.com");    Person p2 = new Person("胡一菲", "huyifei@sina.com");
treeMap.put(p1, "上班"); treeMap.put(p2, "休息"); //遍历方式1 Set<Person> keySet = treeMap.keySet(); Iterator<Person> iterator =keySet.iterator(); while(iterator.hasNext()){ Person person = iterator.next(); System.out.println("key=" + person+ "value=" + treeMap.get(person));} //遍历方式2 Set<Entry<Person, String>> es =treeMap.entrySet(); Iterator<Entry<Person, String>>iterator2 = es.iterator(); while(iterator2.hasNext()){ Entry<Person, String> entry =iterator2.next(); System.out.println("key="+entry.getKey()+ "value=" + entry.getValue());}

具体选择使用哪一种Map实现类?

如果数据是键值对,并且没什么特殊要求,那就使用HashMap,如果还要求能够排序,那就使用TreeMap

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


1 0