Java里的容器 Collection 说明
发布时间:2021-12-10 13:36:56 所属栏目:PHP教程 来源:互联网
导读:容器也是Java面试经常问到的问题. 也是Java编程的其中1个难点,在一篇文章中很难全部讲清楚, 我打算分几篇逐步介绍。 一. 什么是容器 1.1 容器的定义 Java里的容器的定义很简单: 容器(Collection)也称为集合, 在java中就是指对象的集合. 这里可以看出1个特性
容器也是Java面试经常问到的问题. 也是Java编程的其中1个难点,在一篇文章中很难全部讲清楚, 我打算分几篇逐步介绍。 一. 什么是容器 1.1 容器的定义 Java里的容器的定义很简单: 容器(Collection)也称为集合, 在java中就是指对象的集合. 这里可以看出1个特性: 容器里存放的都只能是对象. 实际上是存放对象的指针(头部地址). 1.2 为何需要容器 在编程中我们通常需要将若干个对象进行集中处理. 当然. 通过数组也可以实现此需求. 但是数组也存在两个硬伤: 1. 数组中元素的元素必须相同. 2. 数组的长度难以扩充 这里解析一下: 假如A是1个类名, 那么 A arr_A[] = new A[10]; 标识在内存里分配了1个数组, 数组的长度是10. 首先这个数组的元素只能是A的对象, 这个肯定的了. 假如想扩充这个数组, 那么只能重新建立1个长度更长的数组, 并使用System.arraycopy() 函数把原数组的内容copy到新数组里. 这样的话十分耗费cpu资源和内存空间. 例子: package Collection_kng; class A{ private int i; public A(int i){ this.i = i; } public String toString(){ return "" + this.i; } } public class Collect1{ public static void f(){ A[] arr_A = new A[10]; int i; for(i = 0; i < 10; i++){ arr_A[i] = new A(i); } A[] arr_A2 = new A[11]; System.arraycopy(arr_A,0,arr_A2,0,10); arr_A2[10] = new A(11); for(i = 0; i < 11; i++){ System.out.println(arr_A2[i]); } } } 所以讲: 对于1个数组, 一旦分配内存, 如果你想改变内存长度, 则效率会很低. 而使用容器的话, 可以解决这个两个问题. 也就是讲: 一个容器可以存放不同类型的对象(实际上是对象的指针), 而且可以灵活扩充容器的长度. 例子: public static void g(){ ArrayList arr_l = new ArrayList(); int i; for(i = 0; i < 10; i++){ arr_l.add(new A(i)); } arr_l.add(new A(11)); for(i = 0; i < 11; i++){ System.out.println(arr_l.get(i)); } } 二. 容器的分类 在数学上, 我们可以把容器分为三种. 1.集(Set) Set相当于数学上的集合, Set中的所有元素是无序的, 而且不允许出现重复的元素. 2.列表(List) List相当于代数里的队列, 列表的元素是有序的, 而且允许包含重复成员. 当然, 在java中List也可以分为数组列表(ArrayList)和链表(LinkedList), 它们两者的使用方法类似, 但是内存存储机制是不同的. 3.映射(Map) Map保存所谓的'键值对'(Key - Value)信息, 映射中不能出现重复的键(key), 每个键最多只能映射一个值. 在java中, sun公司为上面三个容器类型设计了三个对应的接口(interface), 这个三个接口分别是 Set List Map. 框架图如下: 可以见到, 对于Set来讲, Set接口继承了Collection接口, HashSet这个容器(类)实现了Set接口. 而ArrayList和 LinkedList都实现了List接口, List接口也是继承自Collection接口. 而HashMap容器则是实现了Map接口, 而Map接口并不继承与Collection接口哦. 由此看出, Java里的容器类是基于接口(interface)构建的. * Collection 定义了存取一组对象的方法, 其子接口Set和List分别定义了存储方式. * Map接口定义了存储(key-value)映射对的方法. 很多时候, 大家还会见到另1中容器Vector, 其实Vector也是List容器一种, 但是Vector支持线程同步(里面的方法都是sycronized的), 也就是允许多个线程同时操作1个Vector容器而不丢失数据. 而Arraylist并不是同步的. 三. 容器的若干个常用的方法 容器作为1个类, 当然有若干个常用的成员方法, 为了叙述方便, 先介绍这一点. 3.1 int size(); 返回Collection中的元素个数. 3.2 boolean containsAll(collection c); 判断1个容器是否包含另1个容器的所有元素, 这里的元素指的的是对象的指针, 也就是对象的本身. 3.3 boolean add(Object e); 把1个对象添加到容器中, 这个方法是每种容器必有的方法. 3.4 boolean remove(Object e); 移除容器中首次出现的制定对象, 因为List容器根据次序不同允许存在重复的对象 3.5 get(int index); 获得容器中第index个元素, 这个方法在List容器中十分常用, 但是不并适用于Set容器, 因为Set容器的元素是无序的. 3.6 Iterator iterator(); 一些无序的容器很难通过循环来遍历元素, 这时我们可以利用迭代器来遍历容器元素. 3.7 Object[] toArray(); 容器不是数组, 不能用下标来访问容器的元素, 这个方法可以返回1个包含容器所有元素的数组. 3.8 重写容器元素的toString()方法 很多时候, 我们需要循环输出容器元素的对象. 例如: for(...){ System.out.println(arr1.get(i)); } 注意利用get()方法返回的是1个对象. 而println方法是输出对象的toString()方法. toString()方法在基类(Object)中被定义成输出对象的类名+hashcode(). 而很多时候我们需要的是输出对象的其他有用信息(例如关键成员的值) 所以强烈建议: 为所有有可能放入容器的类重写toString()方法. 四. Collections 类 上面提到了, Collection其实是1个接口, 但是Java里也存在1个类叫Collections, 而这个Collections也是跟容器有关的. 我们常用的容器, 例如Arraylist, HashSet, Linkedlist等都是基于Collection接口实现的. 所以 Collections并不是上述容器的超类. 实际上, 在java里的容器(例如Arraylist, Linklist)类只提供了一些简单的操作方法, 如add(), get(), size()等. 而一些复杂的功能, 例如排序(sort), 倒置(reverst),则没用提供. 所以Java提供了另1个类Collections, 集合了很多队容器进行复杂操作的静态方法. 这个就是Collections类的意义. 下面列举若干Collections类的常用方法 4.1 void sort(List); 对List容器内的元素排序, 前提是容器内元素的类已经实现Comparable 接口(可以比较的) 下一篇文章会详细提到. 4.2 void Shuffle(List); 对List容器的元素进行随机排序. 4.3 void reverst(List); 就是传说中的倒置, 队List容器内的元素进行逆排序, 一般没什么用.. 4.4 void Fill(List,Object); 把容器内的所有元素都替换为1个制定对象(object) 4.5 void Copy(List dest,List src); 把容器src里的内容复制到dest容器 4.6 int bianrySearch(List,Object); 对于已排序的容器, 利用折半查找法找出制定对象. (编辑:应用网_丽江站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |