走进Java中的持有对象(容器类)之一 容器分类

Java容器可以说是增强程序员编程能力的基本工具,本系列将带您深入理解容器类。

  1. 容器的用途

如果对象的数量与生命周期都是固定的,自然我们也就不需要很复杂的数据结构。

我们可以通过创建引用来持有对象,如

Class clazz;

也可以通过数组来持有多个对象,如

Class[] clazs = new Class[10];

然而,一般情况下,我们并不知道要创建多少对象,或者以何种方式创建对象。数组显然只能创建固定长度的对象,为了使程序变得更加灵活与高效,Java类库提供了一套完整的容器类,具备完善的方法来解决上述问题。

2.  容器的类别

观察上图,我们可以得出容器主要分为两种类型,两个接口Collection与Map定义了两类不同的对象存储方式。

Collection用以保存单一的元素,Map保存关联键值对。通过泛型来指定容器存放的数据类型。 Iterator 设计的目的是在未知容器具体的类型的情况下,用来遍历容器元素。剩下的容器类型都是继承了这两个接口。

在实际编码中,通过向上转型为接口,在其与代码中都使用这个接口是非常普遍的使用方式。如下:

import java.util.*;

public class TestCollection {

    public static void main(String[] args){

        Collection<Integer> c = new ArrayList<Integer>();

        for(int i = 0; i < 10; i++){

            c.add(i);    

        }

        for(Integer i : c){

            System.out.print(i + ", ");

        }

    }

}

注:由于List接口的方法比Collection更为丰富,所以 实际应用中,ArrayList向上转型为List更为合适。

刚刚接触容器的朋友们可能会只把Collection与Map当做接口,实际上并非如此,容器中的接口其实有六个。

3.  容器中的七大接口

  1. Collection接口
  2. Map接口
  3. Set接口
  4. List接口
  5. Queue接口
  6. Iterator接口
  7. Comparable接口

其中List, Queue和Set接口继承了Collection接口,剩下的接口之间都是相互独立的,无继承关系。List和Set接口主要是为了区分是否要包含重复元素,Iterater迭代器则是为了更灵活的迭代集合,与foreach一起使用。Comparable接口则用于比较。

4.  各类容器的功能(主要实现类分析)

  • Collection接口

    • List接口(相比Collection, 添加了新的方法)

      • ArrayList

实现List接口,类似于动态数组,适用于大量随机访问的情况。但插入和删除的代价非常高昂

  • LinkedList

      实现List接口,类似于链表,也提供了优化的顺序访问。在插入和删除方面代价低廉,随机访问代价较高

  • Set接口(方法与Collection完全相同)

    • HashSet

    HashSet使用了散列函数实现,极大的提高了访问速度。存入HashSet的对象必须定义hashCode()

                        import java.util.*;

                        public class IntegerSet{

                            private static Random rand;

                            public static void main(String[] args){

                                rand = new Random(47);

                                Set<Integer> intset = new HashSet<Integer>();

                                for(int i = 0; i < 10000; i++){

                                    intset.add(rand.nextInt(30));

                                }

                                System.out.println(intset);

                            }

                        }

      本例中,intset中插入了10000次,由于不保留重复元素最后输出结果数目<=30。

  • TreeSet

     TreeSet使用红黑树来实现存储元素, 红黑树的好处是可以插入之后维持集合的有序性

                        import java.util.*;

                        public class SortIntegerSet {

                            private static Random rand;

                            public static void main(String[] args) {

                                rand = new Random(47);

                                Set<Integer> sintset = new TreeSet<Integer>();

                                for(int i = 0; i < 10000; i++){

                                    sintset.add(rand.nextInt(20));

                                }

                                System.out.println(sintset);

                            }

                        }
  • LinkedHashSet

      顾名思义,LinkedHashSet使用了链表来保持插入顺序,不过为了提高查询效率,也使用了散列

  • Queue接口

    • LinkedList

     LinkedList实现了Queue接口,提供了方法支持队列的行为,在以后的系列我们会深入讲解如何用

     LinkedList实现队列。

  • PriorityQueue

     与普通队列不同,优先队列每次弹出的是优先级最高的元素。可以通过提供自己的Comparator来修改

    默认的优先级顺序。       

  • Map接口

    • HashMap

HashMap通过散列机制,用来快速访问

  • TreeMap

    TreeMap保持"key"处于排序状态,访问速度不如HashMap

  • LinkedHashMap

    LinkedHashMap保持元素插入时顺序,同时提供散列实现快速访问

关于Map的散列实现是非常重要的,实现Map的原理(关联数组等),hashCode()方法的理解,本系列后面会一一分析。

5.  总结

通过本文的学习,相信读者对容器的用途,分类,以及容器的层次结构与一些常用容器的基本功能和用法有了较为清晰地了解。然而,想要更好的使用容器类,还必须了解每种容器具体的方法,源码,以及线程安全的实现。在本系列的后续部分,将带大家继续深入讨论这些内容。

如果觉得本文对您有所帮助的话,就给俺推荐一个吧~

作者:I‘m coding
链接:http://www.cnblogs.com/ACFLOOD/
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

时间: 2024-08-28 13:08:48

走进Java中的持有对象(容器类)之一 容器分类的相关文章

java中Comparable实现对象的比较

/* class A implements Comaprable<A>{ } 那么 A x = new A(); 类关系图 Object o = A; Object Comparable c = A; | Comparable A 实现了 Comparable 接口嘛 |-----|-----A 所以有 o instanceof A == true; o instanceof Comparable == true; 例如ArrayList添加对象实例时,对象实例添加之后先向上转型为Object

Java中的null对象也可以访问static成员变量和方法

声明:本博客为原创博客,未经允许,不得转载!小伙伴们如果是在别的地方看到的话,建议还是来csdn上看吧(链接为 http://blog.csdn.net/bettarwang/article/details/26515271),看代码和提问.讨论都更方便. 一般来说,一个类的对象要在实例化之后才可以访问类中的成员变量和方法.如果它还是null,通常意义上我们就认为它不能访问类中的成员.实际上确实不提倡这样,而且null对象确实不能访问实例成员(变量和方法),否则会引发NULLPointerExc

Java中利用MessageFormat对象实现类似C# string.Format方法格式化

我们在写C#代码的时候常常会使用到string.Format("待格式化字符串{0},{1},....",参数1,参数2,...),来格式化字符串,特别是拼接字符的时候,这种方式使得代码更为直观清楚. 最近使用java时候却java的string.Format与c#重点string.Format用法不一样,java中的string.format更类似于C语言的sprintf()方法 例如: String str=null; str=String.format("Hello,%

Java中字节与对象之间的转换

近期公司里面用到了消息队列,而正如我们知道的是消息队列之间的是通过二进制形式的.以下就分享一下java中字节与对象之间的转换. 主要是用到了ByteArrayOutputStream和ObjectOutputStream两个输出流,以及ByteArrayInputStream和ObjectInputStream两个输入流. 废话不多说了,直接上代码吧! /** * @FileName: ByteToObject.java * @Package:com.test * @Description: T

Java中List&lt;E&gt;对象赋值问题(深浅拷贝)

Java中List<E>对象赋值操作问题 业务需求是:取2个集合中的交集对象并返回.如下代码,busMap中key值和stocks中Map中的key值相等的对象则返回继续操作,也就是说剔除stocks中的不存在于busMap中的对象,就是一个过滤操作. 实现代码 ① bug版报错:java.util.ConcurrentModificationException ; at java.util.ArrayList$Itr.checkForComodification(ArrayList.java

java中的特殊对象及其应用

/* * System:类中的方法和属性都市静态的. * out:标准输出,默认是控制台. * in:标准输入,默认是键盘. * Propperties getProperties():获取系统属性信息. */ import java.util.Properties; public class SystemDemo { public static void main(String[] args) { //Properties还hashtable中的子类,所以可以通过map的方法获取该集合的元素.

Java基础知识强化101:Java 中的 String对象真的不可变吗 ?

1. 什么是不可变对象?       众所周知, 在Java中, String类是不可变的.那么到底什么是不可变的对象呢? 可以这样认为:如果一个对象,在它创建完成之后,不能再改变它的状态,那么这个对象就是不可变的. 不能改变状态的意思是:不能改变对象内的成员变量,包括基本数据类型的值不能改变,引用类型的变量不能指向其他的对象,引用类型指向的对象的状态也不能改变. 2. 区分对象和对象的引用 对于Java初学者, 对于String是不可变对象总是存有疑惑.看下面代码: 1 String s =

Java中几种对象(PO,BO,VO,DTO,POJO,DAO,Entity,JavaBean,JavaBeans)

一.j2ee中,经常提到几种对象(object),理解他们的含义有助于我们更好的理解面向对象的设计思维. ORM是Object Relational Mapping[对象关系映射]的缩写 通俗点讲,就是将对象与关系数据库绑定,用对象来表示关系数据.在O/RMapping的世界里, 有一系列的重要对象,常见的有VO,PO,DTO,POJO,DAO,BO. 1.Java各种对象(PO,BO,VO,DTO,POJO,DAO,Entity,JavaBean,JavaBeans)的区分 (一).POJO(

java中变量、对象的存储

内容转自网上看到的一篇博文,讲的很不错. 1. 栈(stack)与堆(heap)都是Java用来在Ram中存放数据的地方.与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆.2. 栈的优势是,存取速度比堆要快,仅次于直接位于CPU中的寄存器.但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性.另外,栈数据可以共 享,详见第3点.堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,Java的垃圾收集器会自动收走这些不再使用的数据.但缺点是,由于要 在运行时动态分配