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); } }}
运行结果:
蛮王-->我的大刀早已饥渴难耐赵信-->枪出如龙蛮王-->我的大刀早已饥渴难耐赵信-->枪出如龙蛮王----->我的大刀早已饥渴难耐赵信----->枪出如龙蛮王----->我的大刀早已饥渴难耐赵信----->枪出如龙
- Java容器(List、Map、Set、Iterator)
- JAVA,List,Map,Set,容器
- JAVA,List,Map,Set,容器
- JAVA,List,Map,Set,容器
- JAVA,List,Map,Set,容器
- JAVA,List,Map,Set,容器
- Java中容器[Collection(List,Set,Queue),Map],迭代器(Iterator)和比较器(Comparator)及列表排序
- JAVA的容器---List Map Set
- JAVA的容器---List,Map,Set
- JAVA的容器---List,Map,Set
- [摘]JAVA的容器---List Map Set
- JAVA的容器---List,Map,Set
- JAVA的容器---List,Map,Set
- JAVA的容器---List,Map,Set
- JAVA的容器---List,Map,Set
- JAVA的容器---List,Map,Set
- JAVA的容器---List,Map,Set
- JAVA的容器---List Map Set
- DX 中的坐标变换
- 几个iOS工程通用模块介绍
- linux命令(7)——mv命令
- 表单一
- 四大组件 方便随时查阅
- Java容器(List、Map、Set、Iterator)
- HDOJ-1247Hat’s Words(Trie)
- OpenCV入门 - 调整图片尺寸
- servlet接收客户端传过来的图片,保留验证
- 开启root登陆
- 黑马程序员_76_FileReader类
- quick sort 简单C++实现
- easyui 大全
- [总结]FFMPEG视音频编解码零基础学习方法