集合
1.集合的由来
由于数组的长度固定,不支持长度的不断变化,对于这种情况,java提供了一个集合框架
2.集合和数组的区别
1.长度区别
数组的长度固定,集合的长度是可以改变的
2.数据类型的区别
数组既可以存储基本数据类型,也可以存储引用数据类型
集合只能存储引用数据类型
3.内容区别
数组只能存储同一种类型的元素
集合可以存储多种不同类型的元素
3.Collection集合
Collection集合是一个超级接口,他的子接口有set和List
Collection中最基本的功能
boolean add(E e):给集合中添加元素
boolean remove(Object obj):移除一个集合中的某个元素
void clear() 暴力删除,删除一个集合中的所有元素
boolean contains (Objecr obj):判断当前集合中是否包含指定的元素
int size():获取集合的元素数
Object[] toArray() : 把集合中的元素,存储到数组中
2.集合中的高级功能
boolean addall(Collection c):将一个集合中的元素添加到另一个集合中
boolean remove(Collection c):删掉一个元素就算删掉,删掉的是集合中相同的元素
boolean containsAll(Collection c):包含集合中的所有元素返回 true
boolean retainAll(Collection c):交集功能 只要集合中的元素发生改变就为true 返回的是相同元素。一个集合中的元素为空,永远为true
4.collection集合以及他的子接口
collection集合中有两大子接口 List 和 Set
List集合中有三大类:(允许元素重复)
ArrayList:底层数据结构是数组数据,线程不同步,执行效率高,不安全,查询快,增删慢
LinkedList:底层是链接列表数据结构,线程不同步,不安全,执行效率高,增删快,查询慢
Vector:底层数据结构是数组数据,线程安全,线程同步额,执行效率低,查询快,增删慢
Set集合(元素唯一)
HashSet: 底层数据结构是哈希表,是不同步的,元素是唯一的,无序的,不能保证该顺序恒久不变
LinkedHashSet:底层数据结构是链接列表和哈希表,有序性和唯一性,有序通过链表实现,唯一性通过哈希列表实现
TreeSet:基于TreeMap,底层数据结构是一种红黑树结构,根据使用不同的构造方法,排序不同
5.接口Iterator 集合的遍历
在程序开发中,为了遍历集合中的元素,java提供了一个接口,Iterator
collection集合中有这样一个方法:
public Iterator iterator() 获取迭代器的方法
迭代器中的方法介绍:
hasNext() :如果仍有元素可以迭代,则返回 true。
next() :返回迭代的下一个元素。
remove() 从迭代器指向的 collection 中移除迭代器返回的最后一个元素(可选操作)。
示例,集合的遍历
public class CollectionTest {
public static void main ( String[ ] args ) {
List list = new ArrayList ( ) ;
list. add ( "nihao" ) ;
list. add ( "wobuhao" ) ;
list. add ( "nibuhao" ) ;
Iterator iterator = list. iterator ( ) ;
while ( iterator. hasNext ( ) ) {
String str = ( String) iterator. next ( ) ;
System. out. println ( str) ;
}
}
}
另外一种遍历方式:增强for
public class CollectionTest {
public static void main ( String[ ] args ) {
List< String> list = new ArrayList ( ) ;
list. add ( "nihao" ) ;
list. add ( "wobuhao" ) ;
list. add ( "nibuhao" ) ;
for ( String s : list) {
System. out. println ( s) ;
}
}
}
注意:
使用迭代器iterator对集合中的元素进行添加或者删除时会出现什么异常 出现的原因 解决办法
出现异常 并发修改异常 ConcurrentModificationException
原因: 这个异常是迭代器抛出的,出现异常的原因是集合中删除或者增加了元素会导致迭代器预期的迭代次数发生改变,导致迭代器的结果不准确
解决办法:使用break语句跳出循环,由于没有继续使用迭代器对集合中的元素进行迭代,因此,集合中删除或者增加元素对程序没有任何影响,或者使用迭代器本身的方法进行删除 it.remove()
6.List集合中的特有功能
void add(int index,Object element):在指定位置处添加一个新的元素element
Object remove(int index):删除指定位置处的元素
Object get(int index):获取指定位置处的元素
Object set(int index,Object element):在指定位置处设置(修改)元素
public class CollectionTest {
public static void main ( String[ ] args ) {
List< String> list = new ArrayList ( ) ;
list. add ( "nihao" ) ;
list. add ( "wobuhao" ) ;
list. add ( "nibuhao" ) ;
for ( int i = 0 ; i< list. size ( ) ; i++ ) {
System. out. println ( list. get ( i) ) ;
}
}
}
7. List的子实现类
1 ArrayList:
2 Vector :
特有功能
public void addElement(Object obj): 给Vector集合添加元素 -- 看成ArrayList add(Object obj)
public Object elementAt(int index) :通过角标获取元素-->遍历集合普通for循环中的Object get(int index)
public Enumeration elements() :获取向量组件枚举接口 相当于接口 iteractor
子类方法
boolean hasMoreElements 判断集合中是否有下一个元素
Object nextElements ;获取集合中的下一个元素
3 LinkdeList特有功能:
public void addFirst(Object Object):将元素添加到集合中的第一个位置
public addLast(Object Object):将元素添加到集合末尾
public Object getFirst():获取第一个元素
public Object getLast():获取最后一个元素
public Object Object removeFirst():删除第一个
public Object Object removeLast():删除最后一个
public class VectorTest {
public static void main ( String[ ] args ) {
Vector vector = new Vector ( ) ;
vector. addElement ( "woshishui" ) ;
vector. addElement ( "weileshui" ) ;
vector. addElement ( "wobuzhidao" ) ;
System. out. println ( vector. elementAt ( 1 ) ) ;
Enumeration elements = vector. elements ( ) ;
while ( elements. hasMoreElements ( ) ) {
System. out. println ( elements. nextElement ( ) ) ;
}
}
}
8.泛型
集合框架部分利用创建数组的方式,将类明确的工作提前到了创建对象或者是调用方法,明确集合存储数据类型
泛型的格式: <数据类型>只能是引用数据类型
特点: 1.将运行时期提前到了编译时期
2.避免了强制类型转换
3.提高了程序的安全性
在类上声明泛型
泛型定义在方法上:public <泛型类型> 方法名(泛型类型 );
泛型可以定义在接口上
泛型通配符<?>
规则:前后保持一致
任意类型 如果没有明确,那么就是Object 以及任意的Java类了
<?extends E> 向下限定 E及其子类
<?super E>: 向上限定 E及其父类
9.collections,操作集合的工具类
public static void sort(List list ) 对元素进行排序,根据元素的自然顺序排序
public static int binarySearch(List<?> list,T key) 二分搜索法:前提是元素必须有序,根据元素获取元素第一次在集合中出现的索引
public static T max (Collection <?> coll): 获取集合中的最大值
public static void reverse(list<?>list) :对集合中的元素进行反转
public static void shuffle (List<?>list) 对集合元素进行随机置换
public static <T> boolean addAll(Collection<? super T> c,
T... elements) 将所有指定元素添加到指定 collection 中。
10.Set集合
1.特点:不包含重复元素,由于他不能实例化,一般情况下使用子实现类实例化
A 2.HashSet :元素唯一的,存储和取出不一致(无序性),特别是他不能保证该顺序恒久不变。
3.HashSet 集合底层add方法依赖于HashMap的put方法
依赖于hashCode和equals方法(唯一性)
hashCode :保证唯一性(比较的是对象的地址值是否相同,如果地址值相同,还需要比较内容是否相同)
equals :默认比较的是地址值是否相同,要比较内容是否相同,必须在当前类中重写equals方法。
B 4.LinkedHashSet 是 HashSet 的子类:底层依赖于哈希表的链接列表实现
由哈希表保证元素唯一
由链表保证元素有序
特点: 有序性和唯一性
C 1.TreeSet
基于treeMap实现,底层数据结构是一种红黑树结构,根据使用不同的构造方法,排序不同
自然排序 :对于自定义的类实现comparable接口,重写 comparaTo方法
比较器排序:需要接口的子实现类对象
基本数据类型和String已经实现了Comparable接口
TreeSet集合 必须让当前集合的类型实现Comparable 接口,否则会出现ClassCastException 类转换异常
public class Student implements Comparable < Student> {
private int age;
private String name ;
public Student ( ) {
}
public Student ( int age, String name ) {
this . age = age;
this . name = name;
}
public int getAge ( ) {
return age;
}
public void setAge ( int age ) {
this . age = age;
}
public String getName ( ) {
return name;
}
public void setName ( String name ) {
this . name = name;
}
@Override
public String toString ( ) {
return "Student{" +
"age=" + age +
", name='" + name + '\'' +
'}' ;
}
@Override
public boolean equals ( Object o ) {
if ( this == o) return true ;
if ( ! ( o instanceof Student ) ) return false ;
Student student = ( Student) o;
if ( getAge ( ) != student. getAge ( ) ) return false ;
return getName ( ) != null ? getName ( ) . equals ( student. getName ( ) ) : student. getName ( ) == null;
}
@Override
public int hashCode ( ) {
int result = getAge ( ) ;
result = 31 * result + ( getName ( ) != null ? getName ( ) . hashCode ( ) : 0 ) ;
return result;
}
public int compareTo ( Student o ) {
return this . age - o. age;
}
}
package com. wcc. collection;
import java. util. TreeSet;
blic class SetTest {
public static void main ( String[ ] args ) {
TreeSet< Student> treeSet = new TreeSet < Student> ( ) ;
treeSet. add ( new Student ( 12 , "王子" ) ) ;
treeSet. add ( new Student ( 32 , "老王" ) ) ;
treeSet. add ( new Student ( 22 , "小王" ) ) ;
treeSet. add ( new Student ( 18 , "自己" ) ) ;
for ( Student student: treeSet) {
System. out. println ( student) ;
}
}
}
package com. wcc. collection;
blic class Teacher {
private int age ;
private String name ;
public Teacher ( int age, String name ) {
this . age = age;
this . name = name;
}
public int getAge ( ) {
return age;
}
public void setAge ( int age ) {
this . age = age;
}
@Override
public String toString ( ) {
return "Teacher{" +
"age=" + age +
", name='" + name + '\'' +
'}' ;
}
public String getName ( ) {
return name;
}
public void setName ( String name ) {
this . name = name;
}
}
package com. wcc. collection;
import java. util. Comparator;
import java. util. TreeSet;
blic class TreeSetComparaTo {
public static void main ( String[ ] args ) {
TreeSet< Teacher> treeSet = new TreeSet < Teacher> ( new Comparator < Teacher> ( ) {
public int compare ( Teacher o1, Teacher o2 ) {
return o1. getAge ( ) - o2. getAge ( ) ;
}
} ) ;
treeSet. add ( new Teacher ( 12 , "123" ) ) ;
treeSet. add ( new Teacher ( 22 , "789" ) ) ;
treeSet. add ( new Teacher ( 15 , "456" ) ) ;
for ( Teacher teacher: treeSet) {
System. out. println ( teacher) ;
}
}
}
11.Map集合
特点:Map集合的特点,储存的键值对(键映射到值的对象,一个映射不能包含重复的键;每个键最多只能映射到一个值。)
基本功能:
1.添加功能
V put (K key, V value):添加键和值元素
2.删除功能
V remove (K key)删除指定的键
3.暴力删除
void clear () 暴力删除
判断功能
1.boolean containsKey(Object key):判断是否包含指定的键
2.boolean containsValue(object Value):判断包含指定的值
3.boolean is Empty(): 判断集合是否为空
4. int size():获取 Map集合的键值对个数
获取功能
1. V get (object key) 根据键获取值
2.Set <K> keySet() 获取所有键的集合
3.Collection<V>values 获取所有值的集合
4.Set<Map.Entry<K,V>> entrySet() 获取键值对对象
Map集合的遍历 两种方式
1.通过Set<K> keySet() 获取所有键的集合 然后 通过 V get(object key) 根据键来获取值
2.通过Set<Map.Entry<K,V>> entrySet() 获取键值对对象 然后通过 K getKey() 来获取键 V getValue() 获取值
HashMap:
底层基于哈希表,不能保证顺序恒久不变
如果键是自定义类,成员信息相同 ,是同一个人,对于当前自定义的类需要重写hashCode方法和equals方法。
LinkedHashMap
底层由哈希表和链接列表实现,具有可预知的迭代顺序
哈希表: 元素唯一
链表 : 有序性
TreeMap :底层是红黑树结构
Map集合的遍历
package com. wcc. collection;
import java. util. HashMap;
import java. util. Map;
import java. util. Set;
blic class MapTest {
public static void main ( String[ ] args ) {
HashMap< String, String> map = new HashMap ( ) ;
map. put ( "wo" , "henhao" ) ;
map. put ( "xiexie" , "buqu" ) ;
map. put ( "yexu" , "jiuzheyang" ) ;
Set< String> set = map. keySet ( ) ;
for ( String s : set) {
System. out. println ( s+ map. get ( s) ) ;
}
Set< Map. Entry< String, String> > entries = map. entrySet ( ) ;
for ( Map. Entry< String, String> maps: entries) {
System. out. println ( maps. getKey ( ) + maps. getValue ( ) ) ;
}
}
}
HashMap和HashTable的区别
1.继承的父类不同
HashMap继承自AbstractMap类,而HashTable是继承自Dictionary,不过他们都实现了map,Cloneable(可克隆),Serializable(可序列化这三个接口)
2.对外提供的接口不同
Hashtable比HashMap多提供了contains()方法,作用与HashMap的containsValue()一致,而elments()则是返回Hashtable中的value枚举
3.对null值的支持
HashMap中允许null值,而HashTable如果有null值,都会抛出空指针异常
4.线程安全性
HashMap是线程不安全的,Hashtable是线程安全的,它的每个方法中都加入了Synchronize方法
当需要多线程操作的时候可以使用线程安全的ConcurrentHashMap。ConcurrentHashMap虽然也是线程安全的,但是它的效率比Hashtable要高好多倍。因为ConcurrentHashMap使用了分段锁,并不对整个数据进行锁定。
5.HashCode计算方式不同
6.初始容量和每次扩容量大小不同
HashMap初始为16,之后每次扩容,都会变为原来的2n,Hashtable初始大小为11,每次扩容都会变成原来的2n+1