Java集合框架
来源:互联网 发布:普通话翻译闽南话软件 编辑:程序博客网 时间:2024/06/15 17:03
一、Java集合类综述
Java集合类(位于java.util包中)主要有两个接口Collection和Map派生出来,大致分为Set、List、Queue、Map四种体系。
注意:集合中只可以保存对象,不可以保存基本数据类型。
二、Collection
1. Collection和Iterator接口
1.1 Collection中的方法
boolean add(Object o):向集合中添加一个元素。
boolean addAll(Collection c):把集合c中所有元素添加到指定集合中。
void clear():清除集合中所有元素。
boolean remove(Object o):删除集合中指定元素o。
int size():返回集合中元素个数。
boolean contains(Object o):返回集合中是否包含指定元素o。
boolean containsAll(Collection c):返回集合中是否包含集合c中的所有元素。
boolean isEmpty():判断集合是否为空。
boolean retainAll(Collection c):返回两个集合是否有交集。
Object[] toArray():把集合转化为数组。
Iterator iterator():返回一个Iterator对象,用于遍历集合中的元素。
1.2 Iterator遍历数组
迭代器:集合取出元素的方式。
取出方式定义在集合内部,可以直接访问集合中的元素。
Collection接口extends了Iterable接口,Iterable接口提供了iterator()方法获取Iterator类型对象,来遍历集合。
Iterator接口方法:
boolean hasNext():判断被迭代的集合中是否还有下一个元素。
Object next():返回集合中的下一个元素。
void remove():删除集合中上一次next方法返回的元素(直接修改了集合)。
代码实现:
ArrayList al=new ArrayList();al.add("java01");al.add("java02");al.add("java03");Iterator it=al.iterator();while(it.hasNext()){ System.out.println(it.next());}
2.List
2.1 List介绍
元素是有序的,元素可以重复。因为该集合类有索引。
2.2 List特有方法
增:
add(int index , Object element)
addAll(int index , Collection c)
删:
remove(int index)
改:
set(int index,Object element)
查:
get(int index)
subList(int from , int to)
listIterator()
获取位置:
indexOf(Object obj)
lastIndexOf(Object obj)
……………………………..可爱的分割线………………………………………..
List集合类中特有的迭代器:ListIterator
ListIterator时Iterator的子接口,与Iterator相比,另外实现了增加、修改、反向遍历功能。
代码实现:
ArrayList<String> arrayList=new ArrayList<String>();arrayList.add("zhao");arrayList.add("gao");arrayList.add("qiao");ListIterator<String> li=arrayList.listIterator(); System.out.println("正向遍历:");while(li.hasNext()){ //获取某个元素的值 Object obj=li.next(); System.out.println(obj); if(obj.equals("qiao")){ //修改某个元素值 li.set("zhu"); }else if(obj.equals("gao")){ //删除某个元素 li.remove(); } //增加某个元素 li.add("duan");}System.out.println("逆向遍历:");while(li.hasPrevious()){ Object obj=li.previous(); System.out.println(obj);}
2.3 ArrayList
底层的数据结构为数组结构。线程不同步。’
去除Arraylist集合对象中重复元素的代码实现:
import java.util.ArrayList;import java.util.Iterator;class Person{ private String name; private int age; Person(String name,int age){ this.name=name; this.age=age; } public String getName() { return name; } public int getAge() { return age; } //实现部分(判断元素是否相同使用的是equals()方法) public boolean equals(Object obj){ if(!(obj instanceof Person)) return false; else{ Person p=(Person)obj; return this.name.equals(p.name) && this.age==p.age; } }}public class ArrayListTest { public static void main(String[] args) { ArrayList<Person> al=new ArrayList<Person>(); al.add(new Person("zsw", 23)); al.add(new Person("gnf", 24)); al.add(new Person("gzb", 25)); al.add(new Person("lxg", 26)); al.add(new Person("gzb", 25)); al=singleElement(al); Iterator<Person> li=al.iterator(); while(li.hasNext()){ Person p=li.next(); System.out.println(p.getName()+"....."+p.getAge()); } } public static ArrayList<Person> singleElement(ArrayList<Person> al){ ArrayList<Person> newAl=new ArrayList<Person>(); Iterator<Person> li=al.iterator(); while(li.hasNext()){ Object obj=li.next(); if(!newAl.contains(obj)){ newAl.add((Person)obj); } } return newAl; }}
2.4 LinkedList
底层的数据结构是链表结构。
同时实现了Deque接口,既可以当做栈也可以当做队列使用。
使用LinkedList模拟队列的代码实现:
import java.util.LinkedList;class Duilie{ private LinkedList<String> ll; Duilie(){ ll=new LinkedList<String>(); } public void add(String str){ ll.addFirst(str); } public String get(){ return ll.removeLast(); } public boolean isEmpty(){ return ll.isEmpty(); }}public class LinkedListTest { public static void main(String[] args) { Duilie d=new Duilie(); d.add("aa"); d.add("bb"); d.add("cc"); d.add("dd"); while(!d.isEmpty()){ System.out.println(d.get()); } }}
2.5 Vector
底层数据结构是数组结构。线程同步。
枚举时Vector中特有的取出方式。
代码实现:
Vector<Integer> v=new Vector<Integer>();v.add(new Integer(11));v.add(new Integer(12));v.add(new Integer(13));Enumeration<Integer> e=v.elements();while(e.hasMoreElements()){ System.out.println(e.nextElement());}
2.6 Stack
Vector的子类。
表示后进先出(LIFO)的对象堆栈。
方法:
push(Object obj):入栈。
pop():出栈。
peek():取栈顶元素。
empty():测试堆栈是否为空。
search(Object obj):返回对象在堆栈中位置。
2.7 List实现类性能分析
①数组作为底层的ArrayList在随机访问时效率高。
②链表作为底层的LinkedList插入、删除操作时效率高。
③遍历List集合元素,对于ArrayList、Vector使用随机访问方法(get)来遍历;对于LinkedList使用迭代器(Iterator)来遍历。
④多个线程同时访问List中元素,考虑使用Collections工具类将集合包装成线程安全的集合。
3.Set
3.1 Set介绍
元素是无序的,元素不可以重复
3.2 HashSet
底层数据结构是哈希表,线程是非同步的。
HashSet是如何保证元素唯一的??
通过两个方法:hashCode()和equals(Object obj)。
如果两个元素的hashCode()值相同,才会判断equals(Object obj)是否为true;
如果两个元素的hashCode()值不同,不会调用equals(Object obj)。
HashSet复写hashCode()和equals(Object obj)的代码实现:
import java.util.HashSet;import java.util.Iterator;class Person{ private int age; private String name; Person(String name,int age){ this.name=name; this.age=age; } public int getAge() { return age; } public String getName() { return name; } public int hashCode(){//复写hashCode()方法 return this.name.hashCode()+age*19; } public boolean equals(Object obj){//复写equals()方法 if(!(obj instanceof Person)) return false; else{ Person p=(Person)obj; System.out.println(this.name+"."+p.name); return p.name.equals(this.name)&&p.age==this.age; } }}public class HashSetTest { public static void main(String[] args) { HashSet<Person> hs=new HashSet<Person>(); hs.add(new Person("zsw", 23)); hs.add(new Person("zsw", 23)); hs.add(new Person("gzb", 26)); hs.add(new Person("cya", 18)); Iterator<Person> it=hs.iterator(); while(it.hasNext()){ Person p=it.next(); System.out.println(p.getAge()+"......"+p.getName()); } }}
重写hashCode()一般方法:
①把对象中每一个实例变量计算出一个int类型的hashCode值。
hashCode=int(l^(l>>>32));longhashCode=(int)(f^(f>>>32)); 引用类型hashCode=f.hashCode();
②各个实例变量的hashCode值乘以一个质数后相加。
例:f1.hashCode()*31+int(f2)*19;
3.3 TreeSet
底层数据结构是二叉树,线程是非同步的。
可以对集合中的元素进行排序:
方法1:让元素自身具备比较性。
元素需要实现Comparable接口,覆盖compareTo()方法。这种方法称为元素的自然排序。
方法2:让集合自身具备比较性。
定义了比较器,将比较器作为参数传给TreeSet集合的构造函数。
定义一个类,实现Comparator接口,覆盖compare()方法。
代码实现:
import java.util.Comparator;import java.util.Iterator;import java.util.TreeSet;//第一种方法:实现Comparable接口class People implements Comparable{ private int age; private String name; public People(int age, String name) { this.age = age; this.name = name; } public int getAge() { return age; } public String getName() { return name; } public int compareTo(Object obj){ if(!(obj instanceof People)) throw new RuntimeException("不是人物类型对象"); else{ People p=(People)obj; if(this.age>p.age) return 1; else if(this.age==p.age) return this.name.compareTo(p.name); else { return -1; } } }}//第二种方法:定义一个比较器实现Comparator接口class MyCompare implements Comparator{ public int compare(Object obj1,Object obj2){ People p1=(People)obj1; People p2=(People)obj2; int num=new Integer(p1.getAge()).compareTo(new Integer(p2.getAge())); if(num==0) return p1.getName().compareTo(p2.getName()); return num; }}public class TreeSetTest { public static void main(String[] args){ TreeSet<People> ts=new TreeSet<People>(new MyCompare()); ts.add(new People(17,"zsw")); ts.add(new People(14, "gzb")); ts.add(new People(19, "cya")); ts.add(new People(17, "zln")); ts.add(new People(22, "qyf")); Iterator<People> it=ts.iterator(); while(it.hasNext()){ People p=it.next(); System.out.println("main:"+p.getAge()+"....."+p.getName()); } }}
注意:当两种排序都存在时,以比较器为主。
3.4 LinkedHashSet
线程非同步。
与HashSet相同,也是根据元素的hashCode()值确定元素位置;同时使用链表维护元素次序。
遍历时,会按照元素的添加顺序来访问集合中元素。
代码实现:
package com.zsw.set;import java.util.LinkedHashSet;public class LinkedHashSetTest { public static void main(String[] args){ LinkedHashSet<String> lhs=new LinkedHashSet<>(); lhs.add("zsw"); lhs.add("gzb"); lhs.add("qyf"); System.out.println(lhs);//输出[zsw,gzb,qyg] lhs.remove("gzb");//移除一个元素 lhs.add("lxg");//插入一个新元素 System.out.println(lhs);//输出[zsw,qyf,lxg] }}
3.5 EnumSet
专门为枚举类设计的集合类,线程非同步。
集合元素有序,EnumSet以枚举值在Enum类中的定义顺序来决定集合元素的顺序。
不允许加入null元素。
代码实现
package com.zsw.set;import java.util.Collection;import java.util.EnumSet;import java.util.HashSet;enum Season{ SPRING,SUMMER,FALL,WINTER}public class EnumSetTest { public static void main(String[] args) { //allOf()函数创建包含指定枚举类所有枚举值的集合 EnumSet es1=EnumSet.allOf(Season.class); //noneOf()函数创建一个指定枚举类的空集合 EnumSet es2=EnumSet.noneOf(Season.class); //of()函数创建包含一个或者多个枚举值的EnumSet集合 EnumSet es3=EnumSet.of(Season.SUMMER,Season.WINTER); //range(E from,E to)函数创建从from到to范围内所有枚举值的EnumSet集合 EnumSet es4=EnumSet.range(Season.SUMMER, Season.WINTER); //complementOf(EnumSet s)返回s集合中所没有的枚举值的集合 EnumSet es5=EnumSet.complementOf(es4); Collection c=new HashSet(); c.add(Season.SPRING); c.add(Season.FALL); //copyOf(Collection c)函数使用普通集合(集合中所有元素必须属于同一枚举类)创建EnumSet集合() EnumSet es6=EnumSet.copyOf(c); }}
3.6 Set实现类性能分析
①HashSet性能总比TreeSet好;因为TreeSet总需要额外的红黑树(二叉树)算法维护元素次序。
②当需要保持排序时,使用TreeSet.
③LinkedHashSet比HashSet稍微慢一点,因为链表维护的开销。
④EnumSet是Set实现类里性能最好的。
4.Queue
4.1 Queue介绍
Queue用于模拟“队列”,队列指”先进先出”(FIFO)的容器。
常见方法:
void add(Object e):将指定元素加入队列尾部
Object element():获取队列头部元素但不删除
boolean offer(Object e):将指定元素加入队列尾部。对于有容量限制队列效果好。
Object peek():获取队列头部元素但不删除。
Object poll():获取队列头部元素并删除。
Object remove():获取队列头部元素并删除。
4.2 PriorityQueue
PriorityQueue实现类保持队列元素的顺序按照队列元素的大小排序。
排序方法有两种:
自然排序:集合元素实现Comparable接口。
定制排序:队列传入Comparator比较器对象。
与TreeSet排序要求基本一致。
代码实现:
package com.zsw.queue;import java.util.PriorityQueue;public class PriorityQueueTest { public static void main(String[] args) { // TODO Auto-generated method stub PriorityQueue pq=new PriorityQueue(); pq.offer(6); pq.offer(3); pq.offer(-1); pq.offer(12); //依次输出-1,3,6,12 System.out.println(pq.poll()); System.out.println(pq.poll()); System.out.println(pq.poll()); System.out.println(pq.poll()); }}
4.3 Deque接口
代表一个双端队列,允许从两端操作队列的元素。
可以当做双端队列,也可以当做栈(推荐使用)使用。
4.4 ArrayDeque
Deque接口的实现类,底层数据结构是数组。
ArrayDeque作为”栈”代码展示:
package com.zsw.queue;import java.util.ArrayDeque;public class ArrayDequeTest { public static void main(String[] args) { ArrayDeque stack=new ArrayDeque(); stack.push("zsw"); stack.push("lxg"); stack.push("gzb"); stack.push("wrg"); System.out.println(stack.pop()); System.out.println(stack.pop()); System.out.println(stack.pop()); System.out.println(stack.pop()); }}
三、Map
1. Map介绍
基本方法:
Object put(Object key,Object value):添加一个键值对。
void putAll(Map m):复制指定Map中的键值对。
boolean containsKey(Object key):判断集合中是否包含指定key。
boolean containsValue(Object value):判断集合中是否包含指定value。
Object get(Object key):返回指定key对应的value值。
Object remove(Object key):删除指定key所对应的键值对。
void clear():删除所有键值对。
Set keySet():返回Map集合中所有key组成的Set集合。
Set entrySet():返回Map集合中所有key-value组成的Set集合。
Collection values():返回Map集合中所有value组成的Collection。
int size():返回Map集合的键值对个数。
2. Map集合的取出方式
2.1 keySet()
将Map中所有键存入Set集合;Set集合迭代器迭代取出所有key,使用get(Object key)方法取出value。
代码实现
package com.zsw.quchu;import java.util.HashMap;import java.util.Iterator;import java.util.Set;public class keySetTest { public static void main(String[] args){ HashMap<String, String> hm=new HashMap<>(); hm.put("zsw", "23"); hm.put("lxg", "24"); hm.put("gzb", "25"); Set<String> s=hm.keySet(); Iterator<String> it=s.iterator(); while(it.hasNext()){ String name=it.next(); String age=hm.get(name); System.out.println(name+"....."+age); } }}
2.2 entrySet
将Map集合的映射关系存储到Set集合,Set集合的数据类型是Map.Entry;使用Map.Entry的getKey()和getValue()方法获取key和value。
代码实现
package com.zsw.quchu;import java.util.HashMap;import java.util.Iterator;import java.util.Map;import java.util.Set;public class entrySetTest { public static void main(String[] args){ HashMap<String, Integer> hm=new HashMap<>(); hm.put("zsw", 23); hm.put("gzb", 25); hm.put("qyf", 24); hm.put("xxx", 12); Set<Map.Entry<String,Integer>> s=hm.entrySet(); Iterator<Map.Entry<String, Integer>> it=s.iterator(); while(it.hasNext()){ Map.Entry<String, Integer> me=it.next(); System.out.println(me.getKey()+"..."+me.getValue()); } }}
3. Map实现类
3.1 Hashtable
底层数据结构式哈希表,无序,线程同步。
key和value都不可以为null。
代码实现
package com.zsw.hashtable;import java.util.Hashtable;public class HashtableTest { public static void main(String[] args) { Hashtable ht=new Hashtable(); ht.put("zsw", "201511899"); ht.put("qyf", "201411777"); //key和value都不可以为null //ht.put(null, null); ht.put("lxg", "201411666"); System.out.println(ht); }}
3.2 Properties
Hashtable的子类。
键值都是字符串。通常用来处理属性文件。
代码实现
package com.zsw.hashtable;import java.io.FileInputStream;import java.io.FileOutputStream;import java.util.Properties;public class PropertiesTest { public static void main(String[] args)throws Exception { Properties prop=new Properties(); //load()从文件中加载键值对 prop.load(new FileInputStream("info.ini")); //getProperty()获取指定属性值 System.out.println(prop.getProperty("zsw")); //setProperty()设置键值对 prop.setProperty("gzb", "201311888"); //store()输出到指定文件 prop.store(new FileOutputStream("info.ini"), "my comment"); //list()列出属性值列表 prop.list(System.out); }}
3.3 HashMap
底层数据结构是哈希表 ,无序,线程不同步。
key和value可以为null。
对于HashMap和Hashtable:
①用作key的对象必须实现hashCode()和equals()方法。
②判断两个value值相等的标准:equals()函数返回true。
3.4 LinkedHashMap
是HashMap的子类。
使用双向链表维护键值对的次序;迭代顺序与插入顺序一致。
代码实现
package com.zsw.hashmap;import java.util.Iterator;import java.util.LinkedHashMap;import java.util.Set;public class LinkedHashMapTest { public static void main(String[] args) { LinkedHashMap<String, Integer> lhm=new LinkedHashMap<>(); lhm.put("zsw", 23); lhm.put("qyf", 24); lhm.put("lxg", 25); lhm.put("zln", 24); Set<String> s=lhm.keySet(); Iterator<String> it=s.iterator(); while(it.hasNext()){ String name=it.next(); System.out.println(name+"..."+lhm.get(name)); } }}
3.5 TreeSet
底层数据结构是二叉树(红黑树),有序,线程不同步。
两种排序方式:
与TreeSet两种排序方式类似。
代码实现
package com.zsw.treeset;import java.util.*;//定制排序class StuNameComparator implements Comparator<Student>{ public int compare(Student s1,Student s2) { int num=s1.getName().compareTo(s2.getName()); if(num==0) return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge())); return num; }}//自然排序class Student implements Comparable<Student>{ private String name; private int age; Student(String name,int age) { this.name = name; this.age = age; } public int compareTo(Student s) { int num = new Integer(this.age).compareTo(new Integer(s.age)); if(num==0) return this.name.compareTo(s.name); return num; } public int hashCode() { return name.hashCode()+age*31; } public boolean equals(Object obj) { if(!(obj instanceof Student)) throw new ClassCastException("类型不匹配"); Student s = (Student)obj; return this.name.equals(s.name) && this.age==s.age; }}class TreeSetTest{ public static void main(String[] args) { TreeMap<Student,String> tm = new TreeMap<Student,String>(new StuNameComparator()); tm.put(new Student("alisi0",21),"beijing"); tm.put(new Student("dlisi6",22),"shanghai"); tm.put(new Student("blisi5",23),"nanjing"); tm.put(new Student("elisi4",24),"wuhan"); Set<Map.Entry<Student,String>> entrySet = tm.entrySet(); Iterator<Map.Entry<Student,String>> iter = entrySet.iterator(); while(iter.hasNext()) { Map.Entry<Student,String> me = iter.next(); Student stu = me.getKey(); String addr = me.getValue(); System.out.println(stu+"......"+addr); } }}
3.6 WeakHashMap
WeakHashMap中每个key对象只持有对实际对象的弱引用,因此,当垃圾回收了该keys所对应的实际对象后,WeakHashMap会自动删除该key对应的键值对。
代码展示
package com.zsw.weakhashmap;import java.util.WeakHashMap;public class WeakHashMapTest { public static void main(String[] args) { WeakHashMap<String, String> whm=new WeakHashMap<>(); //两个key都是匿名字符串对象(没有其他引用) whm.put(new String("China"), new String("Chinese")); whm.put(new String("Japan"), new String("Japanese")); //字符串对象 whm.put("America", "English"); //垃圾回收 System.gc(); System.runFinalization(); //只会输出{America=English} System.out.println(whm); }}
3.7 IdentityHashMap
实现机制与HashMap类似。
key和value允许为null。
当且仅当两个key严格相等时(key1==key2),才可以认为两个key相等。
代码实现
package com.zsw.identityhashmap;import java.util.IdentityHashMap;public class IdentityHashMapTest { public static void main(String[] args) { IdentityHashMap<String, Integer> ihm=new IdentityHashMap<>(); //这两个key不满足严格相等 ihm.put(new String("math"), 89); ihm.put(new String("math"), 98); //字符串常量在常量池只有一份,满足严格相等 ihm.put("java", 93); ihm.put("java", 66); //输出{math=89, java=66, math=98} System.out.println(ihm); }}
3.8 EnumMap
所有key都必须是单个枚举类的枚举值。
内部以数组形式保存。
按照key自然顺序(枚举类中顺序)维护key-value顺序。
key不允许为null,value允许为null。
代码实现
package com.zsw.enummap;import java.util.EnumMap;import java.util.EnumSet;enum Season{ SPRING,SUMMER,FALL,WINTER}public class EnumMapTest { public static void main(String[] args) { EnumMap<Season, String> em=new EnumMap<>(Season.class); em.put(Season.SPRING, "chuntian"); em.put(Season.WINTER, "dongtian"); em.put(Season.SUMMER, "xiatian"); //自然顺序输出{SPRING=chuntian, SUMMER=xiatian, WINTER=dongtian} System.out.println(em); }}
3.8 性能分析
①Hashtable和HashMap比TreeSet要快,因为TreeSet使用红黑树。
②TreeSet的好处是有序。
③LinkedHashMap比HashMap慢一点,因为它需要链表保持键值对添加顺序。
③EnumSet性能最好。
四、Collections工具类
1.介绍
操作Set、List、Map等集合的工具类,都是静态方法。
2.排序
void reverse(List list):反转list集合中元素顺序。
void shuffle(List list):对list集合中元素随机排序。
void sort(List list):对list集合元素按照升序排序。
void sort(List list,Comparator c):根据比较器顺序对集合排序。
void swap(List list,int,int j):对list集合中i处和j处元素互换。
void rotate(List list,int distance):当distance为正数时,将list集合的后distance个元素移到前面;当distance为负数时,将list集合前distance个元素移到后面。
3. 查找替换
int binarySearch(List list,Object key):二分法搜索list集合中key的位置,必须list处于有序状态。
Object max(Collection coll):根据自然顺序返回最大元素。
Object min(Collection coll):根据自然顺序返回最小元素。
Object max(Collection coll,Comparator comp):按照比较器指定顺序返回最大元素。
Object min(Collection coll,Comparator comp):按照比较器指定顺序返回最大元素。
void fill(List list,Object obj):使用obj替换list中所有元素。
int frequenc(Collection coll,Object o):返回指定集合中指定元素出现次数。
boolean replaceAll(List list,Object new,Object old):使用新值替换指定集合所有旧值。
4.同步控制
Collections提供了了多个synchronizedXxx()方法,解决多线程并发访问的线程安全问题。
代码实现:
package com.zsw.collections;import java.util.*;public class CollectionsTest { public static void main(String[] args) { Collection c=Collections.synchronizedCollection(new ArrayList()); List list=Collections.synchronizedList(new ArrayList()); Set s=Collections.synchronizedSet(new HashSet()); Map m=Collections.synchronizedMap(new HashMap()); }}
********************************end************************************
- Java集合:集合框架
- 【Java】java集合框架
- [Java]Java集合框架
- JAVA集合框架和集合
- 【集合】Java集合框架介绍
- Java集合之集合框架
- [集合]Java的集合框架 Collection集合
- Java集合框架 (一)
- Java集合框架 (二)
- Java集合框架(三)
- Java集合框架
- 也来谈Java集合框架
- 也来谈Java集合框架
- Java集合框架 (一)
- Java集合框架
- 也来谈Java集合框架
- java集合框架
- Java集合框架总结
- ELK -分析nginx 日志
- Design Support Library相关
- hadoop2.2.0集群搭建
- VM12 PRO安装os x教程
- mysql+web项目(Springmvc+Spring+Mybatis)+ navicat 的中文乱码解决
- Java集合框架
- Linux中的c语言实现类似迅雷那样的下载
- windows程序设计(1)---第一个windows程序--MessageBox
- Editable与String有什么区别
- 安卓发送Get、Post请求,解决参数乱码问题
- scrollview的原理及一些属性
- php 设计模式
- 异常处理
- 用 pystun 获取局域网的NAT类型和公网IP