容器

数组是保存一组对象的最有效的方式,如果你想保存一组基本类型数据,也推荐这样方式 ,但是数据具有固定的尺寸,而在更一般的情况中,你在程序时并不知道将需要多少个对象, 或者是否需要更复杂的方式来存储对象,因此数组尺寸固定显得过于 受限了。 java实用类库提供了一套想当完整的容器类来解决这个问题,其中基本的类型 是List,Set,Queue和Map。
下图是简单的容器分类图:(下图来自《thinking in java》第十一章)

为了更加直观的记忆,简化上图:

java容器大致分为继承Collection接口和继承Map接口两大类。继承自Collection接口的容器,又分为Set,List接口:
1.
Interface List
Type Parameters:
E  - the type of elements in this list

是Collection的子接口,实现了List接口的容器类中的元素是有序的,且可以重复
List容器中的元素都对应一个整数型的序号记载其在容器中的位置,可以根据序号存取容器中的元素
JDK提供的实现List接口的容器类有AbstractList, AbstractSequentialList, ArrayList, AttributeList, CopyOnWriteArrayList, LinkedList, RoleList, RoleUnresolvedList, Stack, Vector

2.
Interface Set
Type Parameters:
E  - the type of elements maintained by this set

是Collection的子接口,实现了Set接口的容器类的元素是无序的,但是不可以重复,JDK提供的实现了Set接口容器类有AbstractSet, ConcurrentHashMap.KeySetView, ConcurrentSkipListSet, CopyOnWriteArraySet, EnumSet, HashSet, JobStateReasons, LinkedHashSet, TreeSet

Interface Map

Type Parameters: K - the type of keys maintained by this map V - the type of mapped values

实现Map接口的类用来存储键-值对
Map接口的实现类有HashMap和TreeMap等
Map类中存储的键-值对通过键来标识,所以键值不能重复
jdk提供实现Map容器类有:AbstractMap, Attributes, AuthProvider, ConcurrentHashMap, ConcurrentSkipListMap, EnumMap, HashMap, Hashtable,IdentityHashMap, LinkedHashMap, PrinterStateReasons, Properties, Provider, RenderingHints, SimpleBindings,TabularDataSupport, TreeMap, UIDefaults, WeakHashMap

具体可以参考官方API,有详细的说明。 http://docs.oracle.com/javase/8/docs/api/index.html

下面看一段代码:

点击(此处)折叠或打开

  1. public class Collection1 {
  2.   
  3.     private int i;
  4.     private String name;
  5.     
  6.     public Collection1(int i,String name) {
  7.         // TODO 自动生成的构造函数存根
  8.         this.i = i;
  9.         this.name = name;
  10.     }
  11.     
  12.     public int geti(){
  13.         
  14.         return i;
  15.     }
  16.     
  17.     public String getName(){
  18.         
  19.         return name;
  20.     }
  21.     
  22.      public String toString(){
  23.         
  24.         return i + "-" +name +" ";
  25.     }
  26. }

  27. public class Test {
  28.    
  29.     public static void main(String[] args){
  30.         
  31.         ArrayList<Collection1> c = new ArrayList<Collection1>();
  32.         c.add(new Collection1(1, "diy"));
  33.         c.add(new Collection1(2,"os"));
  34.         c.add(new Collection1(3, "Lios"));
  35.        
  36.         for(int i=0;i<c.size();i++){
  37.         System.out.print(c.get(i).geti() + " ");
  38.      }
  39.     /*
  40.     for(Collection1 cc :c){

        System.out.print(cc.geti() + " ");
    }
    */
  41.     }
  42. }
上面我们利用ArrayList容器类来盛放Collection1对象,如果要从容器中取出对象,只有上面的两种方式么?当然不是,还记得Object类中的toString()方法吧,通过重写该方法,也可以打印出我们想要的结果。下面介绍另一种:

点击(此处)折叠或打开

  1. public class Test {
  2.    
  3.     public static void main(String[] args){
  4.         
  5.         ArrayList<Collection1> c = new ArrayList<Collection1>();
  6.         c.add(new Collection1(1, "diy"));
  7.         c.add(new Collection1(2,"os"));
  8.         c.add(new Collection1(3, "Lios"));
  9.         
  10.         Iterator<Collection1> ite = c.iterator(); //ArrayList类中实现iterator()方法,作用:Returns an iterator over the elements in this list in proper sequence.

  11.         
  12.          while(ite.hasNext()){
  13.             
  14.              Collection1 t = ite.next();
  15.              System.out.print(t.geti() + " ");
  16.          }
  17.      }
  18.   }
Iterator是什么?那么查下API先:

Interface Iterator
Type Parameters:
E  - the type of elements returned by this iterator
原来它是接口,下面简单的介绍下:
Iterator对象称作迭代器,用以方便的实现对容器内元素的遍历操作
Iterator接口定义了以下的方法:
default void : forEachRemaining(Consumer action)
Performs the given action for each remaining element until all elements have been processed or the action throws an exception.
boolean hasNext():判断游标右边是否有元素
E next():返回游标右边的元素并将游标移动到下一个位置
default void remove():删除游标左面的元素在执行完next之后该操作只能执行一次

原来它是为了方便对容器内元素更好地遍历操作!关于更详细的内容,请读者参考API.

如果想删除容器中的元素怎么办呢,查看api文档发现,提供我们remove(Object o)方法,那就好办啊!

点击(此处)折叠或打开

  1. public class Test {
  2.    
  3.     public static void main(String[] args){
  4.         
  5.         ArrayList<Collection1> c = new ArrayList<Collection1>();
  6.         c.add(new Collection1(1, "diy"));
  7.         c.add(new Collection1(2,"os"));
  8.         c.add(new Collection1(3, "Lios"));
  9.         
  10.         c.remove(new Collection1(1,"diy"));
  11.         Iterator<Collection1> ite = c.iterator();
  12.         
  13.          while(ite.hasNext()){
  14.             
  15.              Collection1 t = ite.next();
  16.              System.out.print(t.geti() + " ");
  17.          }
  18.     }
  19. }
咦?怎么打印结果没有变化啊?不是删除了么? c . remove ( new  Collection1 ( 1 , "diy" ) ) ;我想有些朋友会这样疑问,其实在调用remove()时,系统会调用equals(Object o),如果容器中要删除的对象this,和remove(Object o)函数的参数o相等的话,equals()返回true,否则返回false。对于自定义类型,那么需要重写equals()方法和hashCode()方法,两个equals的对象,那么它们的hashcode也是相等的。上 述中remove(new Collection1(1,"diy")),传入的Collection1的对象,和add(new Collection1(1,"diy"))中添加的对象,在堆中是两片不同的内存区域,所以是不同的对象,当然不会删除!那么没有办法删除了么,当然不是,我们可以通过对象引用的方式来删除:

点击(此处)折叠或打开

  1. public class Test {
  2.    
  3.     public static void main(String[] args){
  4.         
  5.         ArrayList<Collection1> c = new ArrayList<Collection1>();
  6.         
  7.         Collection1 diy = new Collection1(1, "diy");
  8.         c.add(diy);
  9.         c.add(new Collection1(2,"os"));
  10.         c.add(new Collection1(3, "Lios"));
  11.         
  12.         c.remove(diy);
  13.         Iterator<Collection1> ite = c.iterator();
  14.         
  15.          while(ite.hasNext()){
  16.             
  17.              Collection1 t = ite.next();
  18.              System.out.print(t.geti() + " ");
  19.          }
  20.    }
  21. }


简单的修改Test.java:

点击(此处)折叠或打开

  1. public class Test {
  2.    
  3.     public static void main(String[] args){

  4.  HashSet<Collection1> c = new HashSet<Collection1>();
  5.         
  6.         Collection1 ss = new Collection1(1,"diy");
  7.         c.add(ss);
  8.         c.add(new Collection1(2, "os"));
  9.         c.add(new Collection1(3, "Lios"));
  10.         c.add(ss);
  11.         Iterator<Collection1> ite = c.iterator();
  12.         
  13.          while(ite.hasNext()){
  14.             
  15.              Collection1 t = ite.next();
  16.              System.out.print(t.geti() + " ");
  17.         
  18.          
  19.        }
  20.     }
  21. }
打印结果无序,而且不会出现重复对象,其中如何判断放入的是不是同一对象也是用equals(Object o)来实现。


简单的修改Test.java:

点击(此处)折叠或打开

  1. public class Test {
  2.    
  3.     public static void main(String[] args){

  4.     HashMap<String, Integer> A = new HashMap<String, Integer>();
  5.      A.put("One", 1);
  6.      A.put("Two", 2);
  7.      A.put("Three", 3);
  8.      System.out.println(A.get("One"));
  9. }
  10. }
上述 put ( K  key,  V  value)中,第二个参数是Integer类型,但是直接写int类型数字,无错误,这是Java自动打包解包缘由:
自动将基础类型转换为对象
自动将对象转换为基础类型

本文中没有提及LinkedList类,和Interface Queue及其子类,因为后续有文章提及Java中的算法数据结构,当然java封装了其中的算法,通过查阅API文档,可以很好地掌握。 
文中如有错误之处,请读者指正 !

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/29876893/viewspace-1819436/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/29876893/viewspace-1819436/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值