为了方便对多个对象的操作,java提供了集合类。
1.Collection
Collection层次结构的***根接口***。collection对象表示一组对象,这些对象也成为collection的元素。有两个子接口,Set和List,其本身不提供任何具体实现,所有的方法仅由其子接口的实现类实现。
功能:
功能 | 方法 |
---|---|
添加 | boolean add(E e) 、boolean addAll(Collection c) |
删除 | void clear() 、boolean remove(Object o) 、removeAll(Collection c) |
判断 | boolean contains(Object o) :判断集合中是否包含指定元素 ,containsAll(Collection c) |
获取 | Interator<E> iterator() :迭代器,用于遍历 |
长度 | int size() |
转化成数组 | Object[] toArray() |
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class myCollection {
public static void main(String[] args) {
//创建Collection集合的对象
//Collection本身是一个接口,无法实例化,故此通过其List子接口的ArrayList实现类来实例化(多态)
Collection<String> collection = new ArrayList<String>();
//给collection添加元素
collection.add("Hello");
collection.add("World");
//输出集合对象
System.out.println(collection);//ArrayList重写了toString()方法
//遍历
Iterator<String> it = collection.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
}
}
2.List
有序的Collection集合(也称序列),允许重复的元素。
特有功能:
添加:void add(int index,Object element)
在指定位置添加元素
获取:Object get(int index)
获取指定位置的元素
列表迭代器:ListIterator listIterator()
、ListIterator listIterator(index)
指定开始位置
删除:Object remove(index)
、Object remove(Object o)
修改:Object set(int index,E element)
用指定元素替换特定元素
listIterator
比起lterator迭代器,listIterator迭代器是lterator的子接口,新增了一下两种特有功能:
previous()
:前一个元素
hasPrevious()
:是否有前一个元素
迭代器的并发修改问题
迭代器是依赖于集合而存在的,如果在迭代器运行时修改集合,会发生并发修改异常。
迭代器遍历元素时,通过集合是不能修改元素的。
如何解决?
A:迭代器迭代元素,迭代器修改元素。
B:集合遍历元素,集合修改元素。(不使用迭代器)
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
public class myCollection {
public static void main(String[] args) {
//创建Collection集合的对象
//Collection本身是一个接口,无法实例化,故此通过其List子接口的ArrayList实现类来实例化(多态)
List list = new ArrayList();
//给collection添加元素
list.add("Hello");
list.add("World");
//输出集合对象
System.out.println(list);//ArrayList重写了toString()方法
//遍历
Iterator it = list.iterator();
while(it.hasNext()) {
if("World".equals(it.next())) {
list.add("add");
}
}
System.out.println(list);
}
}
2.1List子类概述
ArrayList
:底层数据结构是数组,查询快,增删满。线程不安全,效率高。
Vector
:底层数据结构是数组,查询快,增删满。线程安全,效率低。
LinkedList
:底层数据结构是链表,查询慢,增删快。线程不安全,效率快。
2.2 ArrayList
略
2.3 Vector
特有功能:
addElement(Object obj)
:添加元素
elementAt(int index)
:获取元素
Enumeration elements()
:返回枚举类型,类似于迭代器,有hasMoreElements()
和nextElement()
方法。
2.4 LinkedList
特有功能:
void addFirst(Object obj)
:在开头添加元素
void addLast(Object obj)
:在结尾添加元素
getFirst()
:获取开头元素
getLast()
:获取末尾元素
removeFirst()
:删除开头元素
removeLast()
:删除末尾元素
2.5 泛型
早期的Object类型可以接收任意的对象类型,但是在实际的使用中,会有类型转换的问题。也就存在着
隐患,所以Java提供了泛型来解决这个安全问题。
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
public class myCollection {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<String>();
//给collection添加元素
list.add("Hello");
list.add("World");
//输出集合对象
System.out.println(list);//ArrayList重写了toString()方法
//遍历
Iterator<String> it = list.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
}
}
2.5.1 泛型类
格式:public class ClassName<泛型类型1,...,泛型类型n>
public class ObjectTool<T> {
private T obj;
public T getObj() {
return obj;
}
public void setObj(T obj) {
this.obj = obj;
}
}
2.5.2 泛型方法
格式:public <泛型类型> 返回类型 方法名(泛型类型...)
public class ObjectTool{
public <T> void show(T t){
System.out.println(t);
}
}
public class myCollection {
public static void main(String[] args) {
ObjectTool obj = new ObjectTool();
obj.show("sss");
obj.show(13);
obj.show(null);
}
}
2.5.3 泛型接口
接口定义
public interface Inter<T> {
public abstract void show(T t);
}
接口实现
//已知实现时是String类型
public class InterImplement implements Inter<String> {
@Override
public void show(String t) {
System.out.println(t);
}
}
测试:
public class myCollection {
public static void main(String[] args) {
InterImplement imp = new InterImplement();
imp.show("sss");
}
}
改进:
//不知道是什么类型,即实现类使用了泛型类
public class InterImplement<T> implements Inter<T> {
@Override
public void show(T t) {
System.out.println(t);
}
}
2.5.4 泛型高级:通配符
注意:泛型如果明确的写的时候,前后必须一致
例如下面的情况不允许发生:
Collection<Object> c = new ArrayList<Animal>();
使用通配符可以解决此问题。
Collection<?> c = new ArrayList<Animal>();
Collection<?> c1 = new ArrayList<Dog>();
?
:任意类型,如果没有明确,那么就是Object以及任意的Java类了。
? extends E
:向下限定,E及其子类
? super E
:向上下定,E及其父类
Collection<? extends Animal> c1 = new ArrayList<Animal>();
Collection<? extends Animal> c2 = new ArrayList<Dog>();
Collection<? extends Animal> c3 = new ArrayList<Cat>();
Collection<? extends Animal> c11 = new ArrayList<Object>();//报错
Collection<? super Animal> c4 = new ArrayList<Animal>();
Collection<? super Animal> c5 = new ArrayList<Object>();
Collection<? super Animal> c41 = new ArrayList<Dog>();//报错
Collection<? super Animal> c42 = new ArrayList<Cat>();//报错
2.5.5 增强For
格式:
for(元素数据类型 变量:数组或Collection集合){
使用变量即可,该变量就是元素
}
例如:
int[] arr = {1,2,3,4,5};
for(int x:arr){
System.out.print(x);
}
注意:增强For的目标不能为null,使用之前必须手工判断。增强For的实质就是一个迭代器。
2.5.6 静态导入
格式:import static 包名...类名.方法名;
可以直接导入到方法的级别,因此导入之后可以直接像包内自定义方法一样使用方法名调用。
注意:
(1)方法必须是静态的。
(2)如果有多个同名的静态方法,容易造成混淆,此时不能使用静态导入。
import static java.lang.Math.abs;
import static java.lang.Math.pow;
2.5.7 可变长参数列表
public static int sum(int... a){//这里的变量其实是一个数组
int s=0;
for(int x:a){
s+=x;
}
return s;
}
注意:如果一个方法有可变参数,并且有多个参数,那么,可变参数肯定是最后一个。
3.Set:不包含重复元素,无序
3.1 HashSet
HashSet
不保证set的迭代顺序,特别是它不保证该顺序恒久不变。
HashSet
底层数据结构是哈希表(元素时链表的数组),哈希表依赖于哈希值存储。
3.2 LinkedHashSet:有序
具有可预知的迭代顺序,底层数据结构是链表和哈希表。
3.3 TreeSet
TreeSet能够对元素按照某种规则进行排序(自然排序、比较器排序)
空的构造方法默认对其元素进行自然排序。
4. Map
Map<K,V>
:可以存储键值对的元素,键不可以重复,值可以重复。
将键映射到值的对象,Map集合的数据结构针对键有效,跟值无关。
重要方法:
void clear()
:移除所有的键值对元素
boolean containsKey(Object key)
:判断集合是否包含指定的键
boolean containsValue(Object value)
:判断集合是否包含指定的值
V get(Object key)
:根据键获取值
isEmpty()
:判断集合是否为空
Set<K> keySet()
:获取集合中的所有键的集合
Collection<V> values()
:获取集合中所有值的集合
Set<Map.Entry<K,V>> entrySet()
:返回键值对对象的集合,Map.Entry<K,V>
为键值对对象。
V put(K key,V value)
:添加元素,若键存在,更新值并返回被更新的值
V remove(Obkect key)
:根据键删除键值对元素,并且将值返回
int size()
:返回集合中键值对的对数
4.1 HashMap
HashMap,Map的子类之一,Hash表结构的Map接口实现。
键唯一
与Hashtable的区别:Hashtable也是,Hash表结构的Map接口实现,不允许Null键和Null值,线程安全,效率低,Hashtable是同步的。其余地方与HashMap大致相同。
4.2 LinkedHashMap
LinkedHashMap
,Map接口的Hash表和链表实现,具有可预知的迭代顺序。
4.3 TreeMap
TreeMap
的键是红黑树结构,可以保证键的排序和唯一性。
5.Collections工具类
Collections类继承自Object类,此类完全由在collection上进行操作或返回collection的静态方法组成,是针对集合操作的工具类。
Collection和Collections的区别:
(1)Collection是单列集合的顶层接口,有子接口List和Set。
(2)Collections是针对集合操作的工具类,有对集合进行排序和二分查找的方法。
常用方法:
public static <T> void sort(List<T> list)
:排序,默认是自然排序。
public static <T> int binarySearch(List<?> list,T key)
:二分查找
public static <T> T max(Collection<?> coll)
:最大值
public static void reverse(List<?> list)
:反转
public staitc void shuffle(List<?> list)
:随机置换
6.综合案例:模拟斗地主发牌洗牌
不带排序功能的版本:
import java.util.ArrayList;
import java.util.Collections;
public class PokerDemo {
public static void main(String[] args) {
//创建牌盒
ArrayList<String> array = new ArrayList<String>();
//装牌
//花色
String[] colors = {"♠","♥","♣","♦"};
//点数
String[] points = {"A","2","3","4","5","6","7","8","9","10","J","Q","K"};
for(String color:colors) {
for(String point:points) {
array.add(color.concat(point));
}
}
//大小王
array.add("大王");
array.add("小王");
//打印新牌
System.out.println(array);
//洗牌
Collections.shuffle(array);
System.out.println(array);
//发牌(3个人)
ArrayList<String> player_1 = new ArrayList<String>();
ArrayList<String> player_2 = new ArrayList<String>();
ArrayList<String> player_3 = new ArrayList<String>();
ArrayList<String> bottomPoker = new ArrayList<String>();
for(int x=0;x<array.size();x++) {
if(x%3==0) {
player_1.add(array.get(x));
}else if(x%3==1) {
player_2.add(array.get(x));
}
else if(x%3==2) {
player_3.add(array.get(x));
}
}
//看牌
lookPoker("player_1",player_1);
lookPoker("player_2",player_2);
lookPoker("player_3",player_3);
}
public static void lookPoker(String player,ArrayList<String> array){
System.out.println(player+array);
}
}