Java容器(List、Map、Set、Iterator)

来源:互联网 发布:2016网购大数据 编辑:程序博客网 时间:2024/05/16 08:38

容器是一个Java 所编写的程序,原先必须自行编写程序以管理对象关系,现在容器都会自动帮您做好。

List特点:元素有放入顺序,元素可重复
Set特点:元素无放入顺序,元素不可重复(注意:元素虽然无放入顺序,但是元素在set中的位置是有该元素的HashCode决定的,其位置其实是固定的)
Map特点:元素按键值对存储,无放入顺序 。

一、List接口
ArrayList:线程不安全,效率高。 底层实现是数组,查询块,修改删除慢。
LinkedList: 线程不安全,效率高。 底层实现是链表,查询慢,修改删除快。
Vector:线程安全,效率低。底层实现是数组。

package Collection;import java.util.ArrayList;import java.util.Date;import java.util.List;import java.util.Map;@SuppressWarnings("all")public class Demo01 {       public static void main(String[] args) {        List list = new ArrayList();        list.add("dds");        list.add(new Date());        list.add(new Dog());        list.add(324);//包装类的自动装箱        System.out.println(list.size());        System.out.println(list.isEmpty());             list.remove("dds");        System.out.println(list.size());        System.out.println("---------------");        List list2 = new ArrayList();        list2.add("dsaf");        list2.add("fdsf");        list.add(list2);        System.out.println(list.size());        System.out.println("---------------");        String string;              for(int i=0;i<list.size();i++)        {            string=(String) list.get(i).toString();            System.out.println(string);        }    }}class Dog{    Dog(){    }}

运行结果:

4false3---------------4---------------Tue May 12 16:22:29 CST 2015Collection.Dog@15718f2324[dsaf, fdsf]
package Collection;/** * 自己实现ArrayList * @author liguodong * */public class MyArrayList {    private Object[] elementData;    private int size;    public int size(){        return size;    }    public MyArrayList(){        this(10);    }    public MyArrayList(int initialCapacity) {        if(initialCapacity<0)        {            try {                throw new Exception();            } catch (Exception e) {                // TODO: handle exception                e.printStackTrace();            }        }        elementData = new Object[initialCapacity];    }    //实现数组扩容和数据的拷贝    public boolean add(Object obj)  {        if(size>=elementData.length)//如果size大于初始的大小,进行扩容        {            Object[] newArray = new Object[size*2+1];            System.arraycopy(elementData, 0, newArray, 0, elementData.length);            elementData = newArray;        }           elementData[size] = obj;        size++;        return true;    }    public boolean isEmpty()    {        return size==0;    }    public Object get(int index)    {        rangeCheck(index);         return elementData[index];    }       //移除指定位置的对象     public Object remove(int index) {           rangeCheck(index);         Object oldValue = elementData[index];        int numMoved = size - index - 1;        if (numMoved > 0)            System.arraycopy(elementData, index+1, elementData, index,                             numMoved);        elementData[--size] = null; // Let gc do its work        return oldValue;    }    private void rangeCheck(int index)     {        if(index>=size){            try {                throw new Exception();            } catch (Exception e) {                e.printStackTrace();            }        }    }    public boolean remove(Object o) {        if (o == null) {            for (int index = 0; index < size; index++)                if (elementData[index] == null) {                    fastRemove(index);                    return true;                }        } else {            for (int index = 0; index < size; index++)                if (o.equals(elementData[index])) {                    fastRemove(index);                    return true;                }        }        return false;    }    private void fastRemove(int index) {        int numMoved = size - index - 1;        if (numMoved > 0)            System.arraycopy(elementData, index+1, elementData, index,                             numMoved);        elementData[--size] = null; // Let gc do its work    }    public static void main(String[] args) {        MyArrayList list = new MyArrayList(3);        list.add("324");        list.add("343");        list.add("3dsaf4");        list.add("3432");        list.add("3432");        System.out.println(list.size());        System.out.println(list.get(3));//第四个数据        list.remove(2);//第三个数据        System.out.println(list.size());        System.out.println("----------");        list.remove(new String("3432"));        String string;              for(int i=0;i<list.size();i++)        {            string=(String) list.get(i).toString();            System.out.println(string);        }    }}

运行结果:

534324----------3243433432
package Collection;/** * 自己写一个双向链表 * @author liguodong * */public class MyLinkedList{    /**     * 用来表示一个节点     */    private static class Node {        Node previous;//上一个节点        Object obj;        Node next;//下一个节点        public Node getPrevious() {            return previous;        }        public void setPrevious(Node previous) {            this.previous = previous;        }        public Object getObj() {            return obj;        }        public void setObj(Object obj) {            this.obj = obj;        }        public Node getNext() {            return next;        }        public void setNext(Node next) {            this.next = next;        }        public Node() {            super();        }       }    private Node first;    private Node last;    private int size;    //新增一个元素    public void add(Object obj)    {        Node node = new Node();        if(first == null)        {            node.setPrevious(null);            node.setObj(obj);            node.setNext(null);            first = node;            last = node;        }        else {            //直接往last后新增新的节点                        node.setPrevious(last);            node.setObj(obj);            node.setNext(null);            last.setNext(node);            last = node;        }        size++;    }    public int size()    {        return size;    }    //判断是否合法    private void rangeCheck(int index)    {        if(index>=size)        {            try {                throw new Exception();            } catch (Exception e) {                e.printStackTrace();            }        }    }       public Object get(int index)    {        rangeCheck(index);//判断是否合法              Node temp=iteratorNode(index);//遍历到指定节点        if(temp != null){            return temp.getObj();        }        return null;    }    //遍历到指定节点    public Node iteratorNode(int index)    {        Node tempNode = null;        if(first != null){            tempNode = first; //先指到链表头,很重要。            for(int i=0;i<index;i++)            {                tempNode  = tempNode.getNext();            }                       }        return tempNode;    }    //移除索引位置的对象    public Object remove(int index)    {        Node tempNode =iteratorNode(index);             if(tempNode != null)        {            Node up = tempNode.getPrevious();//tempNode.previous            Node down = tempNode.getNext();//tempNode.next            up.setNext(down);//up.next = down            down.setPrevious(up);//down.previous = up;                          }        size--;        return true;    }    public void add(int index,Object obj)    {        Node tempNode = iteratorNode(index);//指定位置节点        Node newNode = new Node();//新节点        newNode.setObj(obj);//newNode.obj = obj;        if(tempNode != null)        {            //上一个节点            Node upNode = tempNode.getPrevious();//tempNode.previous;            upNode.setNext(newNode);//upNode.next = newNode;            newNode.setPrevious(upNode);//newNode.previous = upNode;            newNode.setNext(tempNode);//newNode.next = tempNode;            tempNode.setPrevious(newNode);//tempNode.previous = newNode;            size++;        }    }    public void set(int index,Object obj)    {        Node tempNode = iteratorNode(index);        tempNode.setObj(obj);//tempNode.obj = obj;    }    public static void main(String[] args) {        MyLinkedList list = new MyLinkedList();        list.add("探险家");        list.add("齐天大圣");        list.add("风暴之怒");        list.add(1,"德玛西亚皇子");        list.set(3, "盲僧");        System.out.println(list.get(1));        System.out.println(list.size());        //System.out.println(list.remove(1));        for(int i=0;i<list.size();i++)                      System.out.println(list.get(i));    }   }

运行结果:

德玛西亚皇子4探险家德玛西亚皇子齐天大圣盲僧

二、Map接口
实现Map接口的类用来存储键值对(key-value)。
Map接口的实现类有HashMap和TreeMap等。
Map类中存储的键值对通过键来标识,所以键不能重复。

HashMap 效率高 线程不安全
Hashtable 效率低 线程安全
两则的用法都是一样的

package Collection;import java.util.HashMap;import java.util.Map;@SuppressWarnings("all")public class Demo02 {    public static void main(String[] args) {        Map map = new HashMap();        map.put("习大大", new Wife("彭麻麻"));        map.put("灰太狼", new Wife("红太狼"));        map.put("猪八戒", "嫦娥");        Wife wife = (Wife) map.get("灰太狼");        map.remove("灰太狼");//从容器中移除        System.out.println(wife.name);        System.out.println(map.containsKey("习大大"));        System.out.println(map.containsValue("彭麻麻"));        System.out.println(map.containsValue("嫦娥"));    }}class Wife{    String name;    public Wife(String name){        this.name = name;    }}

运行结果:

红太狼truefalsetrue
package Collection;public class MyMap{    //Map  HashMap Hashtable        MyEntry[] arr = new MyEntry[990];    int size;       public void put(Object key,Object value){        MyEntry entry = new MyEntry(key,value);        for(int i=0; i<size; i++){            //解决键值重复的处理            if(arr[i].key.equals(key)){                arr[i].value = value;                return;            }        }        arr[size++] = entry;            }    public Object get(Object key){        for(int i=0; i<size; i++){            if(arr[i].key.equals(key))            {                return arr[i].value;            }        }        return null;    }    public MyEntry remove(Object key){        for(int i=0; i<size; i++){            if(arr[i].key.equals(key))            {                MyEntry oldValue = arr[i];                              int numMoved = size - i - 1;                if (numMoved > 0)                    System.arraycopy(arr, i+1, arr, i,numMoved);                                arr[--size] = null; // Let gc do its work                               return oldValue;            }        }        return null;    }    public boolean containsKey(Object key)  {        for(int i=0;i<size;i++)        {            if(arr[i].key.equals(key))                return true;        }        return false;               }    public boolean containsValue(Object value)    {        for(int i=0;i<size;i++)        {            if(arr[i].value.equals(value))                return true;        }            return false;               }    public int Size(){        return size;    }    public static void main(String[] args) {        MyMap map = new MyMap();        map.put("习大大", new Wife("彭麻麻"));        map.put("灰太狼", new Wife("红太狼"));        map.put("猪八戒", "嫦娥");        MyEntry entry = map.remove("猪八戒");              System.out.println(map.Size());        System.out.println(entry.key+" "+entry.value);    }}//键值对class MyEntry{    Object key;    Object value;    public MyEntry(Object key, Object value) {        super();        this.key = key;        this.value = value;    }   }

存在问题:效率较低

Map的底层实现是数组+链表

package Collection;import java.util.LinkedList;/** *  升级版 *  提高查询效率  */@SuppressWarnings("all")public class MyMapNext{    LinkedList[] arr = new LinkedList[999];//Map的底层实现是数组+链表    int size;    public void put(Object key,Object value)    {        MyEntry e = new MyEntry(key, value);//键值对               int a = key.hashCode()%arr.length;        if(arr[a] == null){            LinkedList list = new LinkedList();            //将链表放进数组里面            arr[a] = list;            list.add(e);            size++;        }        else{            LinkedList list = arr[a];            for(int i=0;i<list.size();i++)            {                MyEntry entry = (MyEntry) list.get(i);                if(entry.key.equals(key))                {                    entry.value = value;//键值重复直接覆盖                }            }                       arr[a].add(e);        }       }       public Object get(Object key)    {        int a = key.hashCode()%arr.length;        if(arr[a] != null)        {            LinkedList list = arr[a];            for(int i=0;i<list.size();i++)            {                MyEntry entry = (MyEntry) list.get(i);                if(entry.key.equals(key))                {                    return entry.value;                }            }        }        else{            size--;        }        return null;    }    public int Size(){        return size;    }    public static void main(String[] args) {        MyMapNext map = new MyMapNext();        map.put("习大大", new Wife("彭麻麻"));        map.put("灰太狼", new Wife("红太狼"));        map.put("猪八戒", "嫦娥");        System.out.println(map.Size());        Wife wife = (Wife)map.get("灰太狼");        System.out.println(wife.name);    }}

运行结果:
3
红太狼

Collection类对象在调用remove、contains等方法时,需要比较对象是否祖等。这会涉及到对象类型的equals方法和hashCode方法;对于自定义类型,需要重写equals方法和hashCode方法以实现自定义的对象相等规则。
Java中规定,两个内容相同的对象应该具有相等的hashcode。即equals相等,则hashcode相等;hashcode相等,则equals不一定相等。

Object里面hashCode和equals的native与操作系统有关的解决方法。
String类有对它们重写。

hashCode和equals 可以通过eclipse自动生成。

重写equals方法和hashCode方法

package Collection;public class Student {    //Object String Integer Date    private int id;    @Override    public int hashCode() {        final int prime = 31;//一般是质数        int result = 1;        result = prime * result + id;        return result;    }    @Override    public boolean equals(Object obj) {        if (this == obj)            return true;        if (obj == null)            return false;        if (getClass() != obj.getClass())            return false;        Student other = (Student) obj;        if (id != other.id)            return false;        return true;    }}
package Collection;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;@SuppressWarnings("all")public class EqualsTest {    public static void main(String[] args) {        List list = new ArrayList();        String s1 = new String("lgd");        String s2 = new String("lgd");        list.add(s1);        list.add(s2);        System.out.println(list.size());        Map map = new HashMap();        //key不能重复,通过equals判断,如果重复,对其value进行覆盖。        map.put(s1, "NB");        map.put(s1,"SB");        System.out.println(map.get("lgd"));//判断是否相等,同样依赖于equals。    }}

运行结果:
2
SB

查询优化:遍历的时候可以先看要遍历的数的大小与size/2做比较 如果大于size/2遍历后面。否则,遍历前面。JDK源码如下:

/**     * Returns the (non-null) Node at the specified element index.     */    Node<E> node(int index) {        // assert isElementIndex(index);        if (index < (size >> 1)) {            Node<E> x = first;            for (int i = 0; i < index; i++)                x = x.next;            return x;        } else {            Node<E> x = last;            for (int i = size - 1; i > index; i--)                x = x.prev;            return x;        }    }

hashCode()算完之后有可能是负数,所以一般做完了应该
int a = key.hashCode()%arr.length;
hash = hash<0?-hash:hash;

三、Set接口
Set接口是Collection接口的子接口,Set接口没有提供额外的方法,Set接口的特性是容器类中的元素是没有顺序的,而且不可以重复
Set容器可以与数学中”集合”的概念相对应。
J2SDK API中所提供的Set容器类有HashSet,TreeSet等。

HashSet的底层是HashMap实现的。

package Collection;import java.util.HashSet;import java.util.Set;@SuppressWarnings("all")public class Demo03 {    public static void main(String[] args) {        Set set = new HashSet();        set.add("aaa");        set.add("bbb");        set.add(new String("aaa"));        System.out.println(set.size());        for (Object object : set) {            System.out.println(object);        }        System.out.println(set.contains("bbb"));    }}

运行结果:
2
aaa
bbb
true

package Collection;import java.util.HashMap;import java.util.Map;@SuppressWarnings("all")public class MyHashSet {    HashMap hashMap;    // Dummy value to associate with an Object in the backing Map    private static final Object PRESENT = new Object();    public MyHashSet() {        hashMap = new HashMap();    }    public Boolean add(Object o){        return hashMap.put(o, PRESENT)==null;//set的不可重复就是利用了map里面键对象的不可重复!    }    public boolean remove(Object o) {        return hashMap.remove(o)==PRESENT;    }    public void clear() {        hashMap.clear();    }    public int size() {        return hashMap.size();    }    public static void main(String[] args) {        MyHashSet myHashSet = new MyHashSet();        myHashSet.add("大宝");        myHashSet.add("吃饭");        myHashSet.add("傻瓜");        System.out.println(myHashSet.size());        myHashSet.clear();        System.out.println(myHashSet.size());    }}

运行结果:
3
0

四、容器存储数据综合实例

一个列对应一个属性,一个对象对应一行记录,一个类对应一个表结构。

1、List实现表结构

package Collection;import java.text.DateFormat;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Date;//JavaBean实体类public class Hero {    private int id;    private String name;    private int price;    private String tag;    private Date ontime;    public int getId() {        return id;    }    public void setId(int id) {        this.id = id;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public int getSalary() {        return price;    }    public void setSalary(int price) {        this.price = price;    }    public String getDepartment() {        return tag;    }    public void setDepartment(String tag) {        this.tag = tag;    }    public Date getHiretime() {        return ontime;    }    public void setHiretime(Date ontime) {        this.ontime = ontime;    }    public Hero(int id, String name, int price, String tag,            String ontime) {        super();        this.id = id;        this.name = name;        this.price = price;        this.tag = tag;        DateFormat format = new SimpleDateFormat("yyyy-MM");        try {            this.ontime=format.parse(ontime);        } catch (ParseException e) {            e.printStackTrace();        }    }    public Hero() {        super();    }   }
package Collection;import java.util.ArrayList;import java.util.List;@SuppressWarnings("all")public class Demo04 {    public static void main(String[] args) {        Hero hero1 = new Hero(1001,"九尾狐",3150,"请宠爱我吧","2012-10");        Hero hero2 = new Hero(1002,"探险家",4800,"是时候表演真正的技术了","2013-5");        Hero hero3 = new Hero(1003,"蛮王",1350,"我的大刀早已饥渴难耐","2014-8");        List list = new ArrayList();        list.add(hero1);        list.add(hero2);        list.add(hero3);        printHeroName(list);    }    public static void printHeroName(List<Hero> list){        for (int i = 0; i < list.size(); i++) {            System.out.println(list.get(i).getName());        }    }}

运行结果:
九尾狐
探险家
蛮王

2、Map-List实现表结构

package Collection;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;@SuppressWarnings("all")public class MapList {    public static void main(String[] args) {        Map map1 = new HashMap();        map1.put("id", 1001);        map1.put("name", "刀妹");        map1.put("salary", 3050);        map1.put("department", "项目部");        map1.put("hireDate", "2007-10");        Map map2= new HashMap();        map2.put("id", 1002);        map2.put("name", "战争女神");        map2.put("salary", 3050);               map2.put("department", "教学部");        map2.put("hireDate", "2006-10");        Map map3 = new HashMap();        map3.put("id", 1003);        map3.put("name", "苍井空");        map3.put("salary", 3050);        map3.put("department", "外交部");        map3.put("hireDate", "2009-10");        List<Map> list = new ArrayList<Map>();        list.add(map1);        list.add(map2);        list.add(map3);        printName(list);    }    public static void printName(List<Map> list){        for(int i=0; i<list.size(); i++)        {            System.out.println(list.get(i).get("name") + "--" + list.get(i).get("salary"));        }    }}

运行结果:
刀妹–3050
战争女神–3050
苍井空–3050

五、Iterator接口
所有实现了Collection接口的容器类都有一个iterator方法用以返回一
个实现了Iterator接口的对象。
Iterator对象称作迭代器,用以方便的实现对容器内元素的遍历操作。
Iterator接口定义了如下方法:
Boolean hasNext() //判断是否有元素没有被遍历
Object next() //返回游标当前位置的元素并将游标移动到下一个位置
void remove() //删除游标左边的元素。在执行完next之后,该操作只能执行一次

List/Set遍历

package Collection;import java.util.ArrayList;import java.util.HashSet;import java.util.Iterator;import java.util.List;import java.util.Set;@SuppressWarnings("all")public class Demo05 {    public static void main(String[] args) {        List list = new ArrayList();        list.add("spack");        list.add("storm");        list.add("mahout");        //通过索引遍历        for (int i = 0; i < list.size(); i++) {            System.out.print(list.get(i)+" ");        }           System.out.println();        //通过迭代器遍历        Iterator iterator01 = list.iterator();        while(iterator01.hasNext()){            String string = (String) iterator01.next();            System.out.print(string+" ");        }        System.out.println();        Set set = new HashSet();        set.add("嫦娥1号");        set.add("嫦娥2号");        set.add("嫦娥3号");        for (Object object : set) {            System.out.print(object + " ");        }        System.out.println();        Iterator iterator02 = set.iterator();        while(iterator02.hasNext()) {            String string = (String) iterator02.next();            System.out.print(string+" ");        }           System.out.println();        for (Iterator iterator03 = set.iterator(); iterator03.hasNext();) {            Object object = (Object) iterator03.next();            System.out.print(object+" ");                   }        System.out.println();    }}

运行结果:
spack storm mahout
spack storm mahout
嫦娥2号 嫦娥1号 嫦娥3号
嫦娥2号 嫦娥1号 嫦娥3号
嫦娥2号 嫦娥1号 嫦娥3号

Map遍历两种方式

package Collection;import java.util.HashMap;import java.util.Iterator;import java.util.Map;import java.util.Map.Entry;import java.util.Set;@SuppressWarnings("all")public class Demo06 {    public static void main(String[] args) {        Map map =  new HashMap();        map.put("赵信", "枪出如龙");        map.put("蛮王", "我的大刀早已饥渴难耐");        //方式一        Set keys = map.keySet();        for (Object key : keys) {                       System.out.println(key+"-->"+map.get(key));        }        for (Iterator iterator = keys.iterator(); iterator.hasNext();) {            String keyString = (String) iterator.next();            System.out.println(keyString+"-->"+map.get(keyString));        }        //方式二        //注意这个Entry是java.util.Map.Entry,导包不要出现错误。        Set entrySet = map.entrySet();        for (Iterator iterator = entrySet.iterator(); iterator.hasNext();) {            Entry entry = (Entry) iterator.next();            String key = (String)entry.getKey();            String value = (String)entry.getValue();            System.out.println(key + "----->" + value);        }        Iterator entryIte = entrySet.iterator();        while (entryIte.hasNext()) {            // 通过迭代返回的是一个entry            Entry entry = (Entry) entryIte.next();            String key = (String) entry.getKey();            String value = (String) entry.getValue();            System.out.println(key + "----->" + value);        }    }}

运行结果:

蛮王-->我的大刀早已饥渴难耐赵信-->枪出如龙蛮王-->我的大刀早已饥渴难耐赵信-->枪出如龙蛮王----->我的大刀早已饥渴难耐赵信----->枪出如龙蛮王----->我的大刀早已饥渴难耐赵信----->枪出如龙
0 0
原创粉丝点击