Java之------集合

集合

一、集合的概念

书面解释:集合是包含多个对象的简单对象,所包含的对象称为元素。集合里面可以包含任意多个对象,数量可以变化;同时对对象的类型也没有限制,也就是说集合里面的所有对象的类型可以相同,也可以不同。集合:数量不限、类型不限;数组:定长、类型单一。

个人理解:集合是数组的一种扩展,集合里面可以存放多种数据类型和对象,同时集合可自由扩充,也就是自由添加元素,而数组不能,这一点就远比数组强大。还可以借助数学中的集合来理解集合,集合中的元素不能重复。

二、数据存储结构分类

数组是顺序存储方式,而集合的存储方式就较为丰富强大,有:(1)顺序存储 (2)链式存储(3)树形存储(4)散列存储Hash   (5)Map映射存储

三、集合框架

图中“实现”中的六中集合使用的比较多的,“历史集合类”的现在用的就比较少了。

1、集合框架中各接口的特点

1)Collection接口 

Collection接口 是一组允许重复的对象

Collection接口用于表示任何对象或元素组。想要尽可能以常规方式处理一组元素时,就使用这一接口。

它还使用了Iterator接口,也就是Iterator迭代器,来枚举集合中的元素。做过acm的就很好理解了,简单的可以理解为:将集合中所有的元素都放在迭代器中(一个特写的容器),然后遍历里面所有的内容

实现类:HashSet、ArrayList、LinkedLis

例:

package cn.hncu.collection;  

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;  

public class CollectionDemo {  

    public static void main(String[] args) {
        Collection<Object> col=new ArrayList<Object> ();
        //此处使用ArrayList()来做的话添加是什么顺序那么他存储就是什么顺序  

//      Collection col=new HashSet();
        //此处使用HashSet()来做的话则存储方式是按照其hash值来的,位置不定,
        //但是总体排序还是:数字之间按照大小顺序排,字符串也按照字符的编码排;对象也同样适用  

        //增
        col.add(1);
        col.add(2);
        col.add(6);
        col.add("Jack");
        col.add("Tom");  

        //※注意,如果实现类是hashSet,那么所加入元素的存储位置是由各元素的hashCode值来定的
        //此时,当Perosn类不覆盖hashCode时,person对象的位置是不定,因此这样它的hashCode是对象的内存地址。
        //综上,想当对象的位置确定,则需要覆盖hashCode()方式
        //如果元素是类对象,那么它的hash值就是hashCode()方法的返回值,
        //因此如果你写的hashCode()方法返回相同的值,则认为是相同的元素,加不进的
        col.add(new Person("John", 21));
        col.add(new Person("Jane", 19));  

        //删
//      col.remove(2);
//      col.add("aa");  

        //改1
//      col.remove(1);col.add(1);  

        //改2
        //这种修改方式,假如使用的是HashSet的话不管怎么改还会是按照hashcode值进行排序存储,
        //而如果使用的是ArrayList的话需要修改的元素原来在什么地方修改后还会是在什么地方;
        //对于上面的改1同样适用次原理
        Object objs[]=col.toArray();
        col.clear();
        for (int i=0;i<objs.length;i++){
            if (objs[i].equals(1)){
                objs[i]="100";
            }
            col.add(objs[i]);
        }  

        Iterator<Object> it=col.iterator();
        while (it.hasNext()){
            Object obj=it.next();
            System.out.println(obj);
        }
    }
}  

2)set接口

按照定义,Set接口继承Collection接口,而且它不允许集合中存在重复项。所有原始方法都是Collection中现成的,没有引入新方法。具体的Set实现类依赖添加的对象的equals()方法来检查等同性。

Set添加元素时,一定会执行被添加元素的hashCode()方法,凭此来排序。

实现类:HashSet、TreeSet

3)List接口

List接口继承了Collection接口以定义一个允许重复项的有序集合。该接口不但能够对列表的一部分进行处理,还添加了面向位置的操作。面向位置的操作包括插入某个元素或Collection的功能,还包括获取、除去或更改元素的功能。在List中搜索元素可以从列表的头部或尾部开始,如果找到元素,还将报告元素所在的位置(这个功能很强大,可以进行位置的操作)。

对List及其实现类的对象进行增删改查时可直接进行位置操作指定对具体位置进行操作。如e.add(1,800);为在1位置插入整数800,原来的1位置及后面的元素会全部往后移动一个位置;还如e.removeFirst();和e.removeLast();为在最前面和最后面移除一个元素(这里的remove是有返回值的,若要使用则需要定义一个变量接收),进行完增删改查操作后都要重新进行排序。

A)使用List(如ArrayList)时,不会自动调用hashCode()方法。因为在List中,重复了就重复了,不需判断。

B)List中添加了下标index的功能,这样对List的修改可以利用set方法对指定位置的元素直接进行替换,不需要像Set那么复杂(要转换成数组才能修改,之后还要转换回去)。

C)Collection用Iterator迭代器,而List可以用ListIterator列表迭代器。前者只能next(),后者不但包含next()方法,还包含previous()方法。因此,如果要用List做类似书的翻页功能,不但可以向后翻,还可以向前翻。

实现类:ArrayList、LinkedList

4)Map接口

Map接口不是Collection接口的继承。而是从自己的用于维护键-值关联的接口层次结构入手。按定义,该接口描述了从不重复的键到值的映射。

可以把这个接口方法分成三组操作:改变、查询和提供可选视图。

改变操作允许从映射中添加和除去键-值对。键和值都可以为null。但是,不能把Map作为一个键或值添加给自身。

Map.Entry接口(Entry就是Map接口中的内部类):Map的entrySet()方法返回一个实现Map.Entry接口的对象Set集合,其中每个对象都是底层Map中一个特定的键-值对。

实现类:HashMap、TreeMap

2、实现类

1)ArrayList、LinkedList

使用两种List实现的哪一种取决于特定的需要:如果要支持随机访问,而不必在除尾部的任何位置插入或除去元素,那么,ArrayList提供了可选的集合。

但如果要频繁的从列表的中间位置添加和除去元素,而只要顺序的访问列表元素,那么LinkedList实现更好。

boolean       add(E e)

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

void add(int index,E element)

将指定的元素插入此列表中的指定位置。

 E get(int index)

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

boolean isEmpty()

如果此列表中没有元素,则返回 true

 E remove(int index)

移除此列表中指定位置上的元素。

 E set(int index,E element)

用指定的元素替代此列表中指定位置上的元素。

int size()

返回此列表中的元素数。

注:此外,LinkedList添加了一些处理列表两端元素的方法,使用这些方法,可以轻松地把LinkedList当作一个堆栈、队列或其它面向端点的数据结构。

void           addFirst(E e)

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

void addLast(E e)

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

 E getFirst()

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

 E getLast()

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

 E removeFirst()

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

 E removeLast()

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

2)HashMap、TreeMap

使用哪种实现取决于特定需要:

在Map中插入、删除和定位元素,HashMap是最好的选择。但如果要按顺序遍历键,那么TreeMap会更好。使用HashMap要求添加的键类明确定义了hashCode()实现(助理解:Map.keySet返回的是键的Set集合,而Set集合对hashCode实现有限制,因此作为键的类也要遵守该限制)。有了TreeMap实现,添加到映射的元素一定是可排序的。

注意:HashMap和TreeMap都实现Cloneable接口。

当需要遍历当中的元素时,key视图和entrySet视图遍历前都需要先获得Map的映射放入到集合中去再使用迭代器去遍历,下面以keySet视图为例贴小块代码(entrySet视图也类似):

Set<Object> entries=map.entrySet();

Iterator<Object> it2=entries.iterator();

while (it2.hasNext()){

Entry<Object, Object> entry=(Entry)it2.next();

System.out.println("key="+entry.getKey()+",value="+entry.getValue());

}

而value视图则不同,它用的是Collection接口,下面也贴小块代码:

Collection<Object> value=map.values();

Iterator<Object> it3=value.iterator();

while (it3.hasNext()){

Object obj=it3.next();

String str=obj.toString();

System.out.println(str);

}

3)HashSet类和TreeSet类

“集合框架”支持Set接口两种普通的实现:HashSet和TreeSet。在更多情况下,会使用HashSet存储重复自由的集合。考虑到效率,添加到HashSet的对象需要采用恰当分配散列码的方式来实现hashCode()方法。当需要从集合中以有序的方式抽取元素时,TreeSet实现会有用处。为了能顺利进行,添加到TreeSet的元素必须是可排序的。

因为TreeSet是排序的,而排序就要用到被排序元素的排序方法(compareTo)----Comparable接口中的抽象方法,因此使用TreeSet,那么加入它当中的对象元素必须实现该接口(而非对象的元素的hashCode为元素本身),而因为HashSet不排序所以加入集合的元素不用实现Comparable接口。

补充(注意):TreeSet调用add()方法时,会让新添加的元素调用compareTo(obj)方法,依次把已有的元素作为参数传入,进行决定大小,由上一句,决定放在TreeXXX集合当中的元素要实现Comparable接口。但当添加的元素和已有的元素类型不一致时,新添加的元素的compareTo(obj)方法会强制将已有的元素转换成它的类型来比较,就会出现ClassCastException异常。

如(Employee为已经写好的类):

set.add(111);

set.add("aaa");

set.add("bbb");

set.add( new Employee("张三", 22));

set.add( new Employee("李四", 25));

set.add( new Employee("Jack", 23));

四、集合排序

方法1:

java.lang.Comparable接口适用于一个类有自然顺序的时候。假定对象集合是同一类型,该接口允许把集合排序成自然顺序。

该接口中的int compareTo( T obj )方法: 比较当前实例对象与对象obj,如果位于对象obj之前,返回负值;如果两个对象在排序中位置相同,则返回0;如果位于对象obj后面,则返回正值。

该排序方法的实现要点:让被放置到容器的对象类实现Comparable接口。由其中所实现的方法compareTo( )决定对象之间的排列顺序。

方法2:

java.util.Comparator接口适用于一个类有自然顺序的时候。假定对象集合是同一类型,该接口允许把集合排序成自然顺序。

该接口中的compare ( T o1, To2)方法: 比较用来排序的两个参数。根据第一个参数小于、等于或大于第二个参数分别返回负、零或正整数

◆该排序方法的实现要点:让容器在构造时加入比较器对象。

◆中文排序问题:

比较函数对于英文字母与数字等ASCII码中的字符排序都没问题,但中文排序则明显不正确。这主要是Java中使用中文编码GB2312或GBK时,char型转换成int型的过程出现了比较大的偏差。这偏差是由compare方法导致的,因此我们可以自己实现Comparator接口。另外,国际化问题可用Collator类来解决。

java.text.Collator类,提供以与自然语言无关的方式来处理文本、日期、数字和消息的类和接口。

下面是关于Comparator的例子:

package cn.hncu.sort3;  

import java.util.Comparator;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.Map.Entry;
import java.text.CollationKey;
import java.text.Collator;
import java.util.Comparator;  

public class Sort3Demo {  

    public static void main(String[] args) {
        Comparator<Object> comparator2=new MyCmp2();
        TreeMap<Object, Object> map=new TreeMap<Object, Object>(comparator2);
        map.put("周军", "1001");
        map.put("张军", "1002");
        map.put("李fg军", "1003434");
        map.put("刘一军", "1004555");  

        Set entries=map.entrySet();
        Iterator<Object> it=entries.iterator();
        while (it.hasNext()){
            Map.Entry entry=(Entry) it.next();
            System.out.println("key="+entry.getKey()+",value="+entry.getValue());
        }
    }
}  

class MyCmp2 implements Comparator{  

    @Override
    public int compare(Object o1, Object o2) {
        Collator collator=Collator.getInstance();
        CollationKey key1=collator.getCollationKey(o1.toString());
        CollationKey key2=collator.getCollationKey(o2.toString());
        return key1.compareTo(key2);
//      return key2.compareTo(key1);//反向
    }  

}  

集合排序的应用场合:

在JDK1.2中,有14个类实现了Comparable接口,这些类中指定的自然排序如下:

1、BigDecimal,BigInteger,Byte,Double,Float,Integer,Long,Short按数字大小排序

2、Character 按Unicode值的数字大小排序

3、CollationKey 按语言环境敏感的字符串排序

4、Date 按年代排序

5、File 按系统特定的路径名的全限定字符的Unicode值排序

6、ObjectStreamField 按名字中字符的Unicode值排序

7、String 按字符串中字符Unicode值排序

如果一个类不能或不便于实现java.lang.Comparable接口,则可以用实现比较器Comparator接口的方法提供自己的排序行为。同样,如果缺省Comparable行为满足不了工程需要,也可以提供自己的Comparator。

时间: 2024-10-08 22:51:44

Java之------集合的相关文章

六:Java之集合

集合包含的内容很多,我发现一个很好的博客,感觉自己都没有写的必要了! 链接献上  Java集合 六:Java之集合,布布扣,bubuko.com

Java复习-集合

Java的集合大致分为以下几类 map set list queue set代表无序,不可重复的集合 list代表有序,重复的集合 map代表了映射关系的集合 queue代表的是一种队列集合 从上面的图我们可以看出,访问set集合的时候我们只能根据元素本身来访问,访问list集合的时候可以直接根据元素的索引来访问,如果访问map集合中的元素,可以根据每项的key值访问元素,collection是list map queue的父接口,该接口里定义的方法,可以操作set map queue pack

java的集合框架之一

java是一套很成熟的东西,很多商用的东西都喜欢用它,用的人多,稳定.不过一般也不怎么说起它,因为太常见了,私下里说,写java应用层得就像农民工,每一处都是搭积木,根据设计师的东西如何优雅地搭好积木,当然美其名曰,论农民工搭积木的艺术修养.不难,但是东西很多,经验在里面是一个相当重要的东西.以上纯属每天扯淡,笑看即可,毕竟我目前就是个渣java程序员. java的集合框架以collection接口当作基础,这个接口定义了基本框架,包括size.hashcode.iterator.add.add

【Java】集合_学习笔记

一.集合 1.集合类也称容器类,主要负责保存.盛装其他数据. 2.集合可以保存数量不确定的数据,保存具有映射关系的数据(也称关联数组). 3.Java5后提供一些多线程安全的集合类,放在java.util.concurrrent.(utility的缩写,意为多用途的,实用的) 4.集合只能保存对象(实际是对象的引用,习惯称对象). 5.Java的集合主要由Collection和Map两个接口派生而出,Map接口的实现类用于保存关联数组,Set集合元素不可重复,通过元素本身访问,Map集合可以通过

Java基础——集合(三)——泛型、增强for、工具类

         接上篇,<Java基础--集合(二)--迭代器.Map集合> 六.泛型 (1)定义: 泛型是一种把明确类型的工作放在了创建对象或者调用方法时候才去明确的特殊的类型. (2)格式: <数据类型> ArrayList<String> aList=new ArrayList<String>(); <String> 即表示的是泛型 (3)好处:(掌握) A:解决了黄色警告线问题 B:把运行期间的转换异常给提前到了编译期间 C:优化了程序

Java中集合与数组的切换

在Java开发中常常遇见集合与数组的互相切换,如何实现呢,呵呵呵,很简单: import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; public class Test { /** * 将Set集合转换为数组 * * @author GaoHuanjie */ private static void setT

java之集合概述

集合也称容器:从大的类别分成两类:Collection和Map,也即:单列和双列列表. java编程思想中一张图说明该体系的整体结构:其中黑色着重的类是经常使用的类. 1 Collection Collection:作为单列集合的根接口.该类集合的继承体系如下: Collection分为两大类:List和Set 1)List: 特点:有序的 collection(也称为序列):列表通常允许重复的元素.       List 接口提供了特殊的迭代器,称为 ListIterator,除了允许 Ite

java初识集合(list,set,map)

java的集合有三类:list,set,map.list和set继承了collection接口.区别(list可以添加重复对象,且按照索引位置排序:set没有这两种特点). map是通过key操作里面的value,操作的是成对的对象.put放入对象,get取出对象. 另外:colletion没有随机访问的get()方法,因为collection还包括set,而set有自己的内部顺序.所以,要检查collection元素,必须使用iterator对象. 1.list中有ArrayList(类似数组

谈谈Java的集合组件

让我们一起谈谈Java的集合组件 我们在使用Java的时候,都会遇到并使用到Java的集合.在这里通过自己的理解和网上的资源对Java的集合方面的使用做一个简单的讲解和总结. Java主要分为3个集合组件:Set(集).List(列表).Map(映射). Collection接口:Collection是最基本的集合接口,声明了适用于Java集合的通用方法.Set和List都继承了Collection,Map. Collection接口的方法: boolean add(Object o):向集合中

Java基础——集合(二)——迭代器、Map集合

接上篇,<Java基础--集合(一)--集合体系和Collection> 四.迭代器的使用 使用步骤: 1.通过集合对象获取迭代器对象. 2.通过迭代器对象判断. 3.通过迭代器对象获取. 迭代器原理 由于多种集合的数据结构不同,所以存储方式不同,所以,取出方式也不同. 这个时候,我们就把判断和获取功能定义在了一个接口中,将来,遍历哪种集合的时候,只要该集合内部实现这个接口即可. 迭代器源码 public interface Iterator { publicabstract boolean