zoukankan      html  css  js  c++  java
  • JAVA基础知识:容器

      JDK所提供的容器都在java.util包里面,下面开始讨论的都是JDK1.4版本的,只讲述基本知识,不涉及泛型

      容器API的类图结构如下图所示

      Set:元素无顺序且不可重复      List:元素有顺序且可以重复

      所谓的重复,值得是两个元素equals

      Collection接口中所定义的方法:

      

    package com.collectiontest.demo;
    
    public class Name {
    
        private String fistname,lastname;
    
        public String getFistname() {
            return fistname;
        }
    
        
    
        public String getLastname() {
            return lastname;
        }
    
        
        public Name(String fistname, String lastname) {        
            this.fistname = fistname;
            this.lastname = lastname;
        }
    
    
    
        @Override
        public String toString() {
            return "fistname"+" "+"lastname";
        }
    
    
    
        
    
    
        
    }
    定义一个Name类
    package com.collectiontest.demo;
    
    import java.util.ArrayList;
    import java.util.Collection;
    
    public class BasicContainer {
    
        /**
         * @param args
         */
        @SuppressWarnings("unchecked")
        public static void main(String[] args) {
            // TODO 自动生成的方法存根
    
            @SuppressWarnings("rawtypes")
            Collection c=new ArrayList();
            c.add("hello");        
            c.add(new Name("f1", "f2"));
            c.add(new Integer(100));
            c.remove("hello");
            c.remove(new Integer(100));
            System.out.println(c.remove(new Name("f1", "f2")));
            System.out.println(c);
        }
    
    }
    Main方法

      容器的remove方法移除的也是能够equals成功的对象,在Main()方法的前两个remove操作中,String类和Integer类都已经覆写了Object类的equals方法了,所以可以移除成功并且返回True,而Name类默认继承Object类,也就继承了它的equals方法,Object的这个方法和“==”是一样,表示指向的是同一个对象,所以移除Name类会返回false

      注:两个对象如果equals,那么他们的hascode()返回值应该也是相同的,容器类对象在调用remove、contains等方法时需要比较对象是否相等,这会涉及到对象类型的equals方法和hascode方法,对于自定义的类,需要重写equals和hascode方法以实现自定义的对象相等规则,一般比较对象的时候主要用的eqauls,当用Map接口的容器类时,如果对象作为键,那么就用的是hascode方法,因为这个效率更高,比如两个对象已经equals了,那么hascode方法就只需要返回某个字段的父类的hascode方法值就可以了

    package com.collectiontest.demo;
    
    public class Name {
    
        private String fistname,lastname;
    
        public String getFistname() {
            return fistname;
        }
    
        
    
        public String getLastname() {
            return lastname;
        }
    
        
        public Name(String fistname, String lastname) {        
            this.fistname = fistname;
            this.lastname = lastname;
        }
    
    
    
        @Override
        public String toString() {
            return "fistname"+" "+"lastname";
        }
    
    
    
        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result
                    + ((fistname == null) ? 0 : fistname.hashCode());
            result = prime * result
                    + ((lastname == null) ? 0 : lastname.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;
            Name other = (Name) obj;
            if (fistname == null) {
                if (other.fistname != null)
                    return false;
            } else if (!fistname.equals(other.fistname))
                return false;
            if (lastname == null) {
                if (other.lastname != null)
                    return false;
            } else if (!lastname.equals(other.lastname))
                return false;
            return true;
        }
    
    
    
        
    
    
        
    }
    重写equals方法和hascode方法后的Name类

      

    Iterator接口

    package com.collectiontest.demo;
    
    import java.util.Collection;
    import java.util.HashSet;
    import java.util.Iterator;
    
    public class BasicContainer {
    
        /**
         * @param args
         */    
        public static void main(String[] args) {
            // TODO 自动生成的方法存根
    
            @SuppressWarnings("rawtypes")
            Collection c=new HashSet();     
            c.add(new Name("f1", "l1"));
            c.add(new Name("f2", "l2"));
            c.add(new Name("f3", "l3"));
            c.add(new Name("f4", "l4"));
            Iterator i=c.iterator();
            while (i.hasNext()) {
                //next()返回值为object类型,需要转换为相应类型,1.5之后有泛型
                Name n=(Name)i.next();
                System.out.println(n.getFistname()+" ");
            }
        }
    
    }
    用iterator迭代元素

      再来看一个删除元素的例子

    package com.collectiontest.demo;
    
    import java.util.Collection;
    import java.util.HashSet;
    import java.util.Iterator;
    
    public class BasicContainer {
    
        /**
         * @param args
         */    
        public static void main(String[] args) {
            // TODO 自动生成的方法存根
    
            @SuppressWarnings("rawtypes")
            Collection c=new HashSet();     
            c.add(new Name("f1", "l1"));
            c.add(new Name("f2", "l2"));
            c.add(new Name("f3", "l3"));
            c.add(new Name("f4", "l4"));
            Iterator i=c.iterator();
            for (Iterator iterator = c.iterator(); iterator.hasNext();) {
                Name name = (Name) iterator.next();
                if(name.getFistname()=="f1")
                {
                    iterator.remove(); //name的remove方法会将该元素锁定
                    //如果换成c.remove(name); 会产生例外
                }
                
            }
        }
    
    }
    用iterator删除元素

    Set接口

      Set接口是Collection接口的子接口,Set接口没有提供额外的方法,但实现Set接口的容器类中的元素是没有顺序的,而且不可以重复

      J2SDK API中所提供的Set容器类有HashSet,TreeSet等

    package com.collectiontest.demo;
    
    import java.util.Collection;
    import java.util.HashSet;
    import java.util.Iterator;
    import java.util.Set;
    
    public class BasicContainer {
    
        /**
         * @param args
         */    
        public static void main(String[] args) {
            // TODO 自动生成的方法存根
            Set s=new HashSet();
            s.add("hello");
            s.add(new Name("f1", "l1"));
            s.add("hello");  //不会添加进去
            System.out.println(s);
        }
    
    }
    添加元素并且遍历
    package com.collectiontest.demo;
    
    import java.util.Collection;
    import java.util.HashSet;
    import java.util.Iterator;
    import java.util.Set;
    
    public class BasicContainer {
    
        /**
         * @param args
         */    
        public static void main(String[] args) {
            // TODO 自动生成的方法存根
            Set s1=new HashSet();
            Set s2=new HashSet();
            s1.add("a");s1.add("b");s1.add("c");
            s2.add("d");s2.add("b");s2.add("a");
            //set和list容器类都具有Constructor(Collection c)构造方法用以初始化容器类
            Set sn=new HashSet(s1);
            sn.retainAll(s2);
            Set su=new HashSet(s1);
            su.addAll(s2);
            System.out.println(sn);
            System.out.println(su);
        }
    
    }
    set的另外一些方法

    List接口

     List接口是Collection接口的子接口,实现List接口的容器类中的元素是有顺序的,而且可以重复

     List容器中的元素都对应一个整数型的序号记载其在容器中的位置,可以根据序号存取容器中的元素

     J2SDK API中所提供的Set容器类有ArrayList,LinkedList等,接口中的方法(当然,这是JDK1.4的版本)如下图

      List常用算法:类Java.util.Collection提供了一些静态方法实现了基于List容器的一些常用算法

    Comparable接口

      上面的算法根据什么确定容器中对象的“大小”顺序?

      所有可以“排序”的类都实现了java.lang.Comparable接口,Compare接口中只有一个方法

      public int compareTo(Object obj); 该方法:

      返回0表示 this==obj

      返回正数表示 this>obj

      返回负数表示 this<obj

      实现了Comparable接口的类通过实现compareTo方法从而确定该类对象的排序方式,比如我们在之前的Name类中实现该方法

        public int compareTo(Object object)
        {
            //先比较姓,如果姓一样就比较名
            Name n=Name(object);
            int lastcmp=lastname.compareTo(n.lastname);
            return (lastcmp!=0)?lastcmp:fistname.compareTo(n.fistname);        
        }

    如何选择数据结构

      衡量标准:读的效率和改的效率

      Array读快改慢Linked改快读慢Hash两者之间

      

    Map接口

      实现Map接口的类用来存储键值对,接口的实现类有HashMap和TreeMap等,接口的方法如图

      在JDK1.5之前,Map接口中的方法还不具有自动装箱拆箱功能,例如添加一个数字1,必须这样写put("one",new Integer(1))

      获得这个元素  int i=(Integer)map.get("one").intValue()

      在JDK1.5之后,就可以直接这样写:put("one",1);  int i=(Integer)map.get("one")

      

  • 相关阅读:
    CString与 char *之间的转换
    linux命令行打开图片
    CentOS7 NFS配置
    vs2010 Visula C++ 把CString 转换为string 类型
    1>LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏
    mount 命令
    Centos7.0 Vmware10.0.3 网络桥接配置
    Notepad++ 连接远程 FTP 进行文件编辑
    安装PHP的mongodb驱动速记
    CentOS上安装MongoDB速记
  • 原文地址:https://www.cnblogs.com/SamFlynn/p/4604795.html
Copyright © 2011-2022 走看看