【java学习】集合框架

来源:互联网 发布:解压缩软件破解版 编辑:程序博客网 时间:2024/05/16 18:16

Collection接口

Object与集合
Collection继承树

1)Collector

java8新特性。stream里有一个collect(Collector c)方法,这个方法里面接收一个Collector的实例。可以将一个管道流的结果集到一个list种。

2)Collection和Collections区别

a.Collection:在Java.util下的一个接口,是所有集合的root接口.
b.Collections: Java.util下的一个专用静态类,它包含有各种有关集合操作的静态方法。

Arrays数组

1)Array与Arrays的区别

a.数组类Array:
提供了动态创建和访问 Java 数组的方法。其中的元素的类型必须相同。
效率高,但容量固定且无法动态改变。
它无法判断其中实际存有多少元素,length只是告诉我们array的容量。
b.静态类Arrays
此静态类专门用来操作array ,提供搜索、排序、复制等静态方法。
equals():比较两个array是否相等。array拥有相同元素个数,且所有对应元素两两相等。
sort():用来对array进行排序。
binarySearch():在排好序的array中寻找元素。

2)数组定义

 int[] a;//一开始不定义长度 int [] a = new int[10]; 

3)类似C语言中的memset()应用

char *p = new char[90];memset((void *)p, -2, 90);//把90个char都赋成-2,因为C++里的char是一个byte(8bit);

java写法:

java.util.Arrays.fill( float[], float) 

java里对于数组的处理有一个专门的工具类:java.util.Arrays
这个类提供了5个功能:
1,将数组转换成java.util.ArrayList类型;【asList()】
2,数组的排序;【sort()】
3,数组的二分查找;【binarySearch()】
4,两个数组的比较;【equals()】
5,给数组赋初值;【fill()】

4)数组名

数组名不等价于指针,只有数组名作为函数参数时,才退化为指针,此时数组名的sizeof()就是指针大小,除了这种情况外,均是整个指整个数组的大小。

char *string_a=(char *)malloc(100*sizeof(char));//对于64位机:sizeof(string_a)为8char string_b[100];//sizeof(string_b)为100.

5)概念

①数组A[0..4,-1..-3,5..7]表示三维数组,共有5*3*3=45个元素。

相关概念

1)快速失败(fail-fast)

fail-fast是Java集合的一种错误检测机制。当多个线程对集合进行结构上的改变的操作时,有可能会产生fail-fast机制。
例如:假设存在两个线程(线程1、线程2),线程1通过Iterator在遍历集合A中的元素,在某个时候线程2修改了集合A的结构(是结构上面的修改,而不是简单的修改集合元素的内容),那么这个时候程序就会抛出 ConcurrentModificationException 异常,从而产生fail-fast机制。

2)排序规则

①自然排序

排序对象通过实现java.lang.Comparable接口,并且重写comparaTo()方法(自然比较方法),返回0则表示是同一个对象,否则为不同对象。

package com.set;import java.util.Set;import java.util.TreeSet;class Student1 implements Comparable<Student1>{    int id;    public Student1(int id) {        this.id = id;    }    @Override    public String toString() {        return this.id+"";    }    @Override    public int hashCode() {        return this.id;    }    @Override    public boolean equals(Object obj) {        if (obj instanceof Student1){            Student1  stu = (Student1) obj;            if (stu.id == this.id)                return true;        }        return false;    }    public int compareTo(Student1 o) {        return (this.id-o.id);    }}public class TreeSetTest {    public static void main(String[] args) {        Set<Student1> set = new TreeSet<Student1>();        Student1 s1 = new Student1(5);        Student1 s2 = new Student1(1);        Student1 s3 = new Student1(2);        Student1 s4 = new Student1(4);        Student1 s5 = new Student1(3);        set.add(s1);        set.add(s2);        set.add(s3);        set.add(s4);        set.add(s5);        for (Student1 s : set) {            System.out.println(s);        }    }}

②客户排序

建立一个第三方类并实现java.util.Comparator接口。并重写方法。
Comparable接口将比较代码嵌入自身类中,而后者在一个独立的类中实现比较。然后排序:Collections.sort(list, new MySort ());的第二个参数返回一个int型的值,就相当于一个标志,告诉sort方法按什么顺序来对list进行排序。
如:定义集合形式为TreeSet ts = new TreeSet(new 第三方类());

package com.set;import java.util.Set;import java.util.TreeSet;class MySort implements java.util.Comparator<Student2>{    public int compare(Student2 o1, Student2 o2) {        return o2.id-o1.id;    }}class Student2{    int id;    public Student2(int id) {        this.id = id;    }    @Override    public String toString() {        return this.id+"";    }    @Override    public int hashCode() {        return this.id;    }    @Override    public boolean equals(Object obj) {        if (obj instanceof Student2){            Student2  stu = (Student2) obj;            if (stu.id == this.id)                return true;        }        return false;    }}public class TreeSetTest2 {    public static void main(String[] args) {        Set<Student2> set = new TreeSet<Student2>(new MySort());        Student2 s1 = new Student2(5);        Student2 s2 = new Student2(1);        Student2 s3 = new Student2(2);        Student2 s4 = new Student2(4);        Student2 s5 = new Student2(3);        set.add(s1);        set.add(s2);        set.add(s3);        set.add(s4);        set.add(s5);        for (Student2 s : set) {            System.out.println(s);        }    }}

Set

Java.util.Set。

1)特点:

①没有重复的元素。(作用:询问某个对象是否在某个Set)
②允许null值。
③顺序不定。

2)方法:

①新建实例:
Set set_titles = new LinkedHashSet();
②遍历:
Iterator setIterator = set_titles.iterator();
String Str_title = “”;
while (setIterator.hasNext()) {
Str_title = setIterator.next();
}
③删除:
移除的是值为”a”的项。不能按索引移除。
set_titles.remove(“a”);

3)HashSet

①特点

a.能够最快的获取集合中的元素,效率非常高(以空间换时间).
b.同一对象不能重复存放。
会根据hashcode和equals来庞端是否是同一个对象,如果hashcode一样,并且equals返回true,则是同一个对象,不能重复存放。
c.顺序不定。哈希表是通过使用称为散列法的机制来存储信息的,元素并没有以某种特定顺序来存放

4)SortedSet

特点:

有序。(存放对象不能排序则报错、可指定排序规则)

5)LinkedHashSet

以元素插入的顺序来维护集合的链接表,允许以插入的顺序在集合中迭代。

6)TreeSet

继承SortedSet。
提供一个使用树结构存储Set接口的实现,对象以升序顺序存储,访问和遍历的时间很快。

List

1)特点

①对象以线性方式存储(怎么存的就怎么取出来,顺序不会乱),没有特定顺序,只有一个开头和一个结尾。
②元素可重复。

2)ArrayList

底层的数据结构使用的是数组结构(数组长度是可变的百分之五十延长)(特点是查询很快,但增删较慢)线程不同步

①vector

vector是线程安全的ArrayList,在内存中占用连续的空间。
有一个初始大小,当数据条数大于这个初始大小后会重写分配一个更大的连续空间。如果Vector定义为保存Object则可以存放任意类型。

3)LinkedList

底层的数据结构是链表结构(特点是查询较慢,增删较快)

4)Vector

底层是数组数据结构,线程同步(数组长度是可变的百分之百延长)(无论查询还是增删都很慢,被ArrayList替代了)

5)ArrayList与Vector区别

①同步性:

Vector是线程安全的,也就是说是同步的,而ArrayList是线程序不安全的,不是同步的

②数据增长:

当需要增长时,Vector默认增长为原来一培,而ArrayList却是原来的一半

Queue

在jdk5.0以前,通常的实现方式是使用java.util.List集合来模仿Queue。Queue的概念通过把对象添加(称为enqueuing的操作)到List的尾部(即Queue的后部)并通过从List的头部(即Queue的前部)提取对象而从 List中移除(称为dequeuing的操作)来模拟。你需要执行先进先出的动作时可以直接使用Queue接口就可以了。
元素并没有以某种特定顺序来存放。

Map

Map的继承树

1)Map

①Map特点

a.Map提供了一种映射关系,其中元素以键值对(key-value)的形式存储。键和值都可以为null。
b.key值不可重复,value值可以重复。一个value值可以和很多key值形成对应关系,每个key最多只能映射到一个value。

②操作

a.添加:
Object put(Object key, Object value): 添加。若关键字已存在,那么取代旧值,返回关键字的旧值。若关键字原先不存在,则返回null
void putAll(Map t): 将来自特定映像的所有元素添加给该映像
b.移除
Object remove(Object key): 从映像中删除与key相关的映射
void clear(): 从映像中删除所有映射
c.查询
Object get(Object key): 获得值,返回相关的对象,如果没有在该映像中找到该关键字,则返回null。
boolean containsKey(Object key): 判断映像中是否存在关键字key
boolean containsValue(Object value): 判断映像中是否存在值value
int size(): 返回当前映像中映射的数量
boolean isEmpty() :判断映像中是否有任何映射
d.Entry
Map中的键值对以Entry类型的对象实例形式存在。Map的entrySet()方法返回一个实现Map.Entry接口的对象集合。集合中每个对象都是底层Map中一个特定的键/值对。通过这个集合的迭代器,您可以获得每一个条目(唯一获取方式)的键或值并对值进行更改。

2)Hashtable

不允许记录的键或者值为空;它支持线程的同步,即任一时刻只有一个线程能写Hashtable,因此也导致了 Hashtable在写入时会比较慢。

3)LinkedHashMap

a.有序:
保存了记录的插入顺序,在用Iterator遍历LinkedHashMap时,先得到的记录肯定是先插入的。也可以在构造时用带参数,按照应用次数排序。在遍历的时候会比HashMap慢,不过有种情况例外,当HashMap容量很大,实际数据较少时,遍历起来可能会比LinkedHashMap慢,因为LinkedHashMap的遍历速度只和实际数据有关,和容量无关,而HashMap的遍历速度和他的容量有关。
b.输出的顺序和输入的相同

4)HashMap

定义:

public class HashMap<K,V>    extends AbstractMap<K,V>    implements Map<K,V>, Cloneable, Serializable

基于哈希表实现。
根据键的HashCode 值存储数据,根据键可以直接获取它的值,具有很快的访问速度,遍历时,取得数据的顺序是完全随机的。

①特点

HashMap中的Entry对象是无序排列的。
Key值和value值都可以为null,但是一个HashMap只能有一个key值为null的映射(key值不可重复)。
HashMap不支持线程的同步。
根据键可以直接获取它的值,具有很快的访问速度。

②ConcurrentHashMap

ConcurrentHashMap 使用segment来分段和管理锁,segment继承自ReentrantLock。故ConcurrentHashMap使用ReentrantLock来保证线程安全。

5)TreeMap

实现SortMap接口,能够把它保存的记录根据键排序,默认是按键值的升序排序,也可以指定排序的比较器,当用Iterator 遍历TreeMap时,得到的记录是排过序的。

①特点:

a.有序。

6)HashMap与HashTable区别

hashmap的底层是数组加链表的结构,它的线程是不安全的,
而hastable是在hashmap的基础上,对整个哈希表(数组)加锁 sychronized实现线程安全。

方法访问数组中的数据,可能只涉及到数组的部分,对整个数组加锁会降低线程并发执行的效率,所以如果对数组分段加锁,使用segment分片锁,这样一个线程只会锁住数组的一片,其他线程仍可以访问数组的其他片进行写操作,具有这样的分片锁的机制是就是concurrenthashmap。

①同步性:

HashMap是线程序不安全的(所以效率高),不是同步的.
Hashtable是线程安全的(Synchronize),也就是说是同步的。

②值:

只有HashMap可以让你将空值作为一个表的条目的key或value

③快速失败:

迭代HashMasp采用快速失败机制,而HashTable不是。

快速失败”也就是fail-fast,它是Java集合的一种错误检测机制。当多个线程对集合进行结构上的改变的操作时,有可能会产生fail-fast机制。

④继承不同

都实现了Map接口。
HashMap继承AbstractMap类。
HashTable继承了Dictionary类。

⑤两个遍历方式的内部实现不同

都使用了Iterator。
由于历史原因,Hashtable还使用了Enumeration的方式。

⑥哈希值的使用不同

HashTable直接使用对象的hashCode;
HashMap重新计算hash值,用与代替求模。

⑦内部实现方式的数组的初始大小和扩容的方式不同。

HasnTable中的hash数组默认大小是11,增加的方式是old*2 + 1。
HashMap中的hash数组的默认大小是16,而且一定是2的指数。

7)ConcurrentHashMap

ConcurrentHashMap是一个线程安全的Hash Map,它的主要功能是提供了一组和HashTable功能相同但是线程安全的方法。
区别在于hastable是对整个代码块加锁,而concurrenthasmap是使用分片锁,粒度较小,不用对整个代码块加锁,提高了读写速率。

ConcurrentHashMap可以做到读取数据不加锁,并且其内部的结构可以让其在进行写操作的时候能够将锁的粒度保持地尽量地小,不用对整个ConcurrentHashMap加锁。

Iterator

Iterator支持从源集合中安全地删除对象(在Iterator上调用remove方法)。
java.util.Iterator其接口定义如下:

public interface Iterator {    boolean hasNext(); //判断容器内是否还有可供访问的元素   Object next();  //返回迭代器刚越过的元素的引用,返回值是Object,需要强制转换成自己需要的类型  void remove();  //删除迭代器刚越过的元素}  

Collection类的Iterator遍历list(Vector, ArrayList, LinkedList等集合元素):
Collection list= new Vector();

        Iterator iterator = list.iterator();          while(iterator.hasNext()){              String s = iterator.next();              if (s.contains("1")) {                iterator.remove();            }        }  
原创粉丝点击