浅谈Java集合
来源:互联网 发布:南风知我意1免费阅读 编辑:程序博客网 时间:2024/06/07 04:02
浅谈Java集合(个人学习时总结)
Java集合描述:
Collection和Map是Java集合框架的根接口。
Collection的子接口有:Set、Queue、List
Set的子类、接口都是线程不安全的,如果想要解决这个问题应作如下处理:
SortedSet s = Collection.synchronizedSortedSet(new TreeSet(…));
实现Map的类有:HashMap、Hashtable。EnumMap、IdentityHashMap、SortedMap、WeakHashMap
常用的有:HashSet、TreeSet、ArrayList、ArrayDeque、LinkedList、HashMap、TreeMap
HashMap和Hashtable比较:前者线程不安全,因为key和Value允许为空,后者线程安全,key和value不允许为空
Set中的值不能重复,因为他是无序的,如果add两个相同的元素,那么第二次的返回值为false,相当于数学中的集合。
接口Collection继承了Iterable接口,Iterable中定义了Interator
Iterator接口中的方法:hasNext(),next(),remove()
Set集合:
HashSet:
有很好的存取和查找性能。
特点:
1.不能保证元素的顺序;
2.HashSet不是同步的,如果多个线程同时访问一个HashSet,必须通过代码来保证其同步;
3.集合元素可以是null
HashSet存入元素值时,HashSet会调用该对象的hashCode()方法来得到该对象的hashCode值然后根据此值决定在HashSet中的位置。
HashSet判断两个对象相等的标准是通过equals()比较相等,并且所对应的hashCode值也相等。
为防止出现hashCode相同equals不同,我们要重写hashCode(),要求如下:
在程序运行过程中,同一个对象多次调用hashCode()方法应该返回相同的值;
当两个对象通过equals()方法比较返回true时,这两个对象的hashCode()应该返回相等的值
对象中用作equals()方法比较标准的实例变量,都应该用于计算hashCode值
LinkedHashSet:
能够不改变输入的次序,对里面的值进行输出。
这样做降低了性能。
TreeSet:是SortedSet的子类
自然排序:根据Unicode码或者数值大小,true大于false
定制排序:o1>o2返回+ o1
TreeSet例子
import java.util.*;public class Main { public static void main(String[] args) { TreeSet ts = new TreeSet(new Comparator() { @Override public int compare(Object o1, Object o2) { Integer a = (Integer)o1; Integer b = (Integer)o2; return a>b?-1:a<b?1:0; } }); ts.add(13); ts.add(15); ts.add(19); ts.add(11); ts.add(10); System.out.println(ts); }}
List集合:
- List集合代表一个元素有序,可重复访问的集合,在集合中每个元素都有其对应的顺序索引。
- List新增的方法:
- void add(int index,Object element):将元素element插入到LIist集合的index处;
- boolean add(index,Collection c):将集合c插入到list的index索引位置 [a,[1,2,3],b]
- Object get(int index):得到索引处的值
- int indexOf(Object o): 返回对象o第一次出现的索引值
- int lastIndexOf(Object o):返回对象o最后一次出现的索引值
- remove(int index)删除 set(int index,Object o) 替换
- Java8中新加removeAl(UnaryOperator operator) 根据operator指定的计算规则重新设置所有元素
sort(Comparator c) 根据c重新排序 - List中提供了一个特殊的listIterator()方法,此方法返回一个ListIterator,此接口下还有
hasPrevious();pervious();add(E e);三个新增方法 - Iterator和ListIterator的区别就在于后者多出的方法,Iterator不允许在遍历时修改Set中的值,而List则允许。
并且List和调用hasPrevious();pervious()操作上一个元素 - ArrayList和Vector实现类:
这两个类都实现了List接口,实现了List中的方法。
Vector是一个比较老的类,里面有一些很古老的方法,方法与ArrayList的相似,只是名字不同。
还有就是,Vector中的方法都是线程安全的,ArraysList都是线程不安全的,
最后一点就是,Stack(栈)继承了Vector。Stack也是一个很古老的类。性能太差。后边一般用ArrayDeque代替
Queue集合
- Queue集合:用于模拟队列这样的数据结构,先进先出。
- Queue定义了以下几个方法:
void add(Object e)添加指定元素到队尾
Object element()获取队头元素,但是不删除
boolean offer(Object e)将指定元素插入到队尾,使用有容量限制的队列时,性能比add好
Object peek()获取对头元素,不删除,如果为空队列,返回null
Object poll()获取队头元素并删除,若为空队列,返回hull
Object remove()获取对头元素,并删除 - Queue接口有一个PriorityQueue(优先队列)实现类,还有Deque(双端队列)的接口,可以当做栈,此接口下有两个实现类(ArrayDeque和LinkedList)
- PriorityQueue实现类:
这个类保存队列元素并不是按照进入队列的先后顺序,
而是自行排序,不能保证保存时是顺序的,但是能保证弹出队列时是顺序的。违反了队列的“先进先出”原则
PriorityQueue不允许元素为null,因为要对元素进行排序。
PriorityQueue有两种排序方式:自然排序和定制排序
例子:自然排序
PriorityQueue中元素必须实现Comparable接口,并重写compareTo方法。否则可能出现ClassCastException
import java.util.Iterator;import java.util.PriorityQueue;public class Main{ public static void main(String[] args) { PriorityQueue pq = new PriorityQueue(); pq.offer(new A(10)); pq.offer(new A(20)); pq.offer(new A(14)); pq.offer(new A(111)); pq.offer(new A(11)); Iterator it = pq.iterator(); while(it.hasNext()){ //输出10 11 14 111 20 由此可见,无法保证存储的顺序性 System.out.print(((A)(it.next())).getA()+" "); } System.out.println(); while(pq.size()>0){ //输出10 11 14 20 111 由此可见,可以保证出队列的顺序性 System.out.print(((A)(pq.poll())).getA()+" "); } }}class A implements Comparable<A>{ public int a; public A(int a){ this.a = a; } public int getA(){ return a; } //实现Comparable接口,重写compareTo方法 @Override public int compareTo(A a) { return this.a-a.a; }}
例子:定制排序
创建PriorityQueue队列时,传入一个Comparator对象,该对象对队列中的所有元素进行排序。
import java.util.Comparator;import java.util.Iterator;import java.util.PriorityQueue;public class Main{ public static void main(String[] args) { //PriorityQueue的构造器有点特殊,前面的int代表创建当前队列的大小, //后面的Comparator对compare进行重写 PriorityQueue pq = new PriorityQueue(7,new Comparator() { @Override public int compare(Object o1, Object o2) { A a1 =(A)o1; A a2 =(A)o2; return a1.getNumber()-a2.getNumber(); } }); pq.offer(new A(9)); pq.offer(new A(1)); pq.offer(new A(3)); pq.offer(new A(2)); pq.offer(new A(8)); Iterator it = pq.iterator(); while(it.hasNext()){ //输出1 2 3 9 8 System.out.print(((A)(it.next())).getNumber()+" "); } System.out.println(); while(pq.size()>0){ //输出1 2 3 8 9 System.out.print(((A)(pq.poll())).getNumber()+" "); } }}class A{ private int number; public A(){ } public A(int number){ this.number = number; } public int getNumber(){ return number; }}
Deque接口与ArrayDeque实现类:
- Deque接口是接口Queue的子接口,它代表一个双端队列。
- ArrayDeque实现了Deque接口,它是基于数组实现的双端队列,
- 创建ArrayDeque时可指定队列的长度,如果不指定,默认为16.
- 如果程序中要使用栈,那么推荐使用ArrayDeque,因为Stack是一个很古老的类。
LinkedList实现类:
- LinkedList类是List接口的实现类,这意味着他是一个List集合,可以根据索引来随机访问集合中的元素。
- LinkedList类还实现了Deque接口,可以被当做双向队列使用,因此,即可以当做栈也可以当做队列使用。
- LinkedList与ArrayList和ArrayDeque的实现机制完全不同,ArrayList和ArrayDeque以数组的形式保存元素,因此随机访问时有较好的性能;而LinkedList内部以链表的形式来保存集合中的元素,因此随机访问时性能较差,但是插入删除元素时性能较出色
注意:用随机访问ArrayList和ArrayDeque要比用Iterator访问性能高。因为随机访问会被影射城市族元素的访问。
Map集合:
- Map用于保存具有映射关系的数据,因此Map里保存key和value,key和value都可以是任何引用类型数据。
- Map中的key不允许重复。
- Set和Map之间的关系非常密切。
- Map接口中创建了Entry内部类,来实现key-value键值对
- Map中的方法
- void clear()
- boolean containsKey(Object key)
- boolean containsValue(Object value)
- Set entrySet() 返回Mao中包含的key-value对所组成的Set集合,每个集合都是Map.Entry对象
- Object get(Object key)
- boolean isEmpty()
- Set keySet() 返回Map中所有key组成的Set集合
- Object put(Object key,Object value)
- void putAll(Map m)
- Object remove(Object key)
- boolean remove(Object key,Object value) Java8中新增方法
- int size()
- Collection values() 返回Map里所有value组成的Collection
- 内部接口Entry中的方法:
- Object getKey()
- Object getValue()
- Object setValue(V value)
例子:Map
import java.util.*;public class Main { public static void main(String[] args) { Map map = new HashMap(); map.put(1,2); map.put(2,3); map.put(3,4); //通过Map接口中的entrySet返回Set(每个集合元素都是Entry)的特点。 //将Set转换成Entry,然后就可以调用内部接口Entry的方法了 Set set = map.entrySet(); Iterator it = set.iterator(); while(it.hasNext()){ Map.Entry me = (Map.Entry) it.next(); System.out.println(me.getKey()+"--"+me.getValue()); //System.out.println(it.next());//键值对1=2 2=3 3=4 } }}
HashMap和Hashtable实现类:
HashMap和Hashtable类似于ArrayList和Vector,Hashtable是一个很古老的类。
HashMap和Hashtable区别: ·Hashtable是一个线程安全的Map实现类,但是HashMap是一个线程不安全的Map实现类; ·Hashtable不允许key和value为null,如果为空,产生空指针异常;HashMap允许null作为key或value
- HashMap只允许有一对key为空的数据,允许有无数个value为null的数据
- 判断两个key相等的标准是:两个key通过equals()比较为true,并且hashCode也相等
判断两个value相等的标准是:两个value通过equals()比较为true
当使用自定义类最为key时,如果重写equals()和hashCode()方法,保证都相等。
LinkedHashMap是HashMap的子类:
- HashMap的缺点就是,不能维护元素的插入顺序。
- LinkedHashMap能维护元素的插入顺序,但是降低了性能。
Properties类是Hashtable是子类:
- 能将键值对保存到文件中,到时候在加载。
**
SortedMap接口和TreeMap实现类:
**
TreeMap和TreeSet一样,也能对key和value进行排序,分为自然排序和定制排序:
- 自然排序:所有key实现Comparable接口,重写compareTo方法。
- 定制排序:创建TreeMap时,传入一个Comparator对象。
例子:TreeMap
import java.util.*;public class Main { public static void main(String[] args) { TreeMap tm = new TreeMap(); tm.put(new K(16), "你好"); tm.put(new K(12), "你好"); tm.put(new K(15), "你好"); tm.put(new K(1123), "你好"); tm.put(new K(13), "你好"); System.out.println(tm); }}class K implements Comparable { private int key; public K(int key) { this.key = key; } public String toString() { return "key值是:" + key; } @Override public int compareTo(Object o) { K k = (K) o; return key > k.key ? -1 : key < k.key ? 1 : 0; }}
WeakHashMap实现类:
用法与HashMap相似,区别在于HashMap中的key保留了对实际对象的强引用,意味着,只要该HashMap对象不被销毁,该HashMa 的所有key所引用的对象就不会被垃圾回收,HashMaori也不会自动删除这些key所对应的key-value对;但WeakHashMaori的key只保留了对实际对象的弱引用,这意味着如果WeakHashMap对象的key所引用的对象没有被其他强引用变量所引用,则这些key所引用的对象可能被垃圾回收,WeakHashMaori对象的key所引用的对象没有自动删除这些key所对应的key-value对。
IdentityHashMap实现类:
在IdentityHashMap中,当且仅当两个key严格相等(key1==key2)时,IdentityHashMap带认为两个key相等对于普通的HashMap而言,只要key1.equals(key2)返回true,且它们的hashCode值相等即可。**例子:IdentityHashMap**
import java.util.*;public class Main { public static void main(String[] args) { IdentityHashMap ihm = new IdentityHashMap(); ihm.put(new String("语文"), "语文1"); ihm.put(new String("语文"), "语文2"); ihm.put("Java", "Java1"); ihm.put("Java", "Java2"); //输出{Java=Java2, 语文=语文1, 语文=语文2} System.out.println(ihm); }}
EnumMap实现类:
**key不能为null value可以为null。**
例子:EnumMap
import java.util.*;public class Main { public static void main(String[] args) { EnumMap em = new EnumMap(Season1.class); em.put(Season1.FALL, "太爽了"); em.put(Season1.SUMMER, "太热了"); em.put(Season1.SPRING, null); //输出{SPRING=null, SUMMER=太热了, FALL=太爽了} System.out.println(em); }}enum Season1 { SPRING, SUMMER, FALL, WINTER;}
操作集合的工具类:Collections
- Collections工具类提供大量方法对集合元素进项排序,查询,和修改等操作,还提供了将集合对象设置为可不变、对集合对象实现同步控制等方法。
排序操作:
void reverse(List list):反转指定List集合中元素的顺序。
void shuffle(List list ):洗牌操作
void sort(List list):升序排序
void sort(List list,Comparator c):根据Comparator产生的顺序排序
void swap(LIst list,int i,int j):将指定的List集合中的i处元素和j处元素进行交换
void rotate(List list,int distance):distance 为正,将后distance移到前面,为负将前distance移到后面查找,替换:…..同步控制:Collections中提供了synchronizedCollectionXxx()方法可以将指定集合包装成线程同步的集合,从而解决多线程并发访问集合时的线程安全问题
例子:Collection
import java.util.*;public class Main { 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()); //这样就获得了线程安全的集合对象 }}
设置不可变集合:
- emptyXxx():返回一个空的、不可变的集合对象。List、SortedSet、Set、Map、SortedMap等
- singletonXxx():返回一个只包含指定对象(只有一个或一项元素)的、不可变集合对象。List、Map
- unmodifiableXxx():返回指定集合对象的不可变视图。List、SortedSet、Set、Map、SortedMap等
- 浅谈JAVA集合框架
- 浅谈JAVA集合框架
- 浅谈JAVA集合框架
- 浅谈JAVA集合框架
- 浅谈Java集合框架
- 浅谈JAVA集合框架
- java 集合浅谈
- 浅谈java集合类
- 浅谈java集合接口
- 浅谈JAVA集合框架
- Java 浅谈集合框架
- JAVA--浅谈集合
- Java集合浅谈
- 浅谈Java集合
- 浅谈java中的集合
- 浅谈java集合
- 浅谈java中的集合类
- 浅谈java集合之间区别
- 牛顿迭代法(Newton's Method)
- 从零开始学JDBC--1.9 代码抽取--使用Properties读取配置文件
- 初识IntelliJ
- Mysql必知必会(笔记)【存储过程】
- Elasticsearch.The.Definitive.Guide学习笔记 -- 3. Data in, Data in
- 浅谈Java集合
- **[Lintcode]Majority Number III
- 111.苹果开发者账号和邓白氏编码申请总结
- muduo库Thread类剖析
- 【计算机视觉】背景建模之PBAS
- dirichlet process
- 营养与蛋白质
- 转战、
- 网页扫雷(简易版)(一)