前言
Collection
public interface Collection<E> extends Iterable<E> {
//返回容器里对象的个数
int size();
//是否是空,不是null,篮子是空的篮子不是null
boolean isEmpty();
//篮子里是否有这个对象
boolean contains(Object o);
//迭代器
Iterator<E> iterator();
//把容器里的东西放到数组里
Object[] toArray();
<T> T[] toArray(T[] a);
//添加对象到篮子里
boolean add(E e);
//移除对象,不在篮子里,内存地址还有
boolean remove(Object o);
//是否包含你的容器里的所有元素
boolean containsAll(Collection<?> c);
//你的篮子里所有的都放到我这里
boolean addAll(Collection<? extends E> c);
boolean removeAll(Collection<?> c);
//取交集
boolean retainAll(Collection<?> c);
//清楚容器
void clear();
boolean equals(Object o);
int hashCode();
}
List
有人想有可以自动扩展的数组,所以有了List
Vector
底层是数组,线程安全,效率低。
ArrayList
底层是数组,起步价是10,自动扩容。
查询快,修改,插入,删除慢。线程不安全,效率高。
常用API
List list = new ArrayList();
list.add("aa");//添加对象
list.add(1,"ab");//第二个添加“ab”
list.size();//长度
list.isEmpty();//是否是空
list.remove("aa");//移除对象,底层调用的是equals方法而不是==,所以值相同的删除,就从第一个开始遍历,相同的删除后就return了。之后就算有一样的也不会删。
list.remove(0);//移除第一个,移除完后面的位置会补上来,第二个变成第一个,第三个变成第二个
list.get(0);//获得第0个元素
LinkedList
增删改快,查询慢,线程不安全,效率高。
底层是链表
Map
map.put("孙悟空","金箍棒");
map.get("孙悟空");
map.remove("孙悟空");//移除一对
map.put("孙悟空","紧箍咒");//把金箍棒改成紧箍咒,map长度不变,key一样,修改value
map2.putAll(map);//把map中的元素全部加载到map2中
map.containsKey("孙悟空");
map.containsValue("金箍棒");
map.clear();
map.isEmpty();
map.keySet();//获取key的集合,map没有Iterator,想要遍历必须借助set来遍历key,通过key取值
Map底层实现
hashcode是可以自己重写的,所以hashcode的值如果一样,那么这两个元素不一定是相同的。但是如果hashcode不一样,两个元素一定不是相同的。
Map先根据hashcode判断分组,再根据equals判断是否是相同元素。
class student {
private int id;
private String name;
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + getOuterType().hashCode();
result = prime * result + id;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
student other = (student) obj;
if (!getOuterType().equals(other.getOuterType()))
return false;
if (id != other.id)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
private myEntry getOuterType() {
return myEntry.this;
}
}
class myEntry {
//map中每一个键值对对象,构造方法和setget省略
private Object key;
private Object value;
}
public class MyMap {
//创建一个数组,里面每一个元素都是一个链表(LinkedList)
LinkedList[] arr = new LinkedList[999];
/*-----------------------------------------------
* 对key的哈希值取余数,例如key=张三 张三.hasecode = 122222
122222%999=344,把张三这一键值对放入arr[344]中的链表node0
key=李四 李四.hasecode = 121223
121223%999=344,把李四这一键值对放入arr[344]中的链表node1
*
*/
public void put(Object key, Object value) {
//创建键值对对象
myEntry e = new myEntry(key, value);
//对key的哈希值取余
int a = key.hashCode()%999;
//如果取余的数组位置为空
if(null == arr[a]) {
//在该位置创建链表,添加键值对对象
List list = new LinkedList<>();
list.add(e);
}else {
arr[a].add(e);
}
}
}
HashMap
效率高,线程不安全。key可以有一个null,只能有一个,值可以都是null
HashTable
效率低,线程安全。key和value都不可以是null。
properties是HashTable的子类
properties的键值对只能是字符串
Properties pro = new Properties();
pro.setProperty("driver","mysql.driver");
pro.setProperty("url", "http://");
TreeMap
确保key可以排序或者提供比较器
Set
有的人想有没有重复的数组,所以有了set
HashSet:哈希表是通过使用称为散列法的机制来存储信息的,元素并没有以某种特定顺序来存放;
LinkedHashSet:以元素插入的顺序来维护集合的链接表,允许以插入的顺序在集合中迭代;
TreeSet:提供一个使用树结构存储Set接口的实现,对象以升序顺序存储,访问和遍历的时间很快。
HashSet
无序的集合,不能有重复值。
底层是用map实现的
class set {
private transient HashMap<E,Object> map;
private static final Object PRESENT = new Object();
//利用map的key是不可重复的,来达到set是不可重复的目的
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
}
TreeSet
数据元素可以排序且不可重复
元素实现comperable或者提供comperator业务类
在数据添加的时候进行排序,之后你可以修改数据,即使数据重复也可以。为了防止数据重复,你可以把类中的元素final
迭代器Iterator
collection中有Iterator元素
@Test
public void myText() {
Set set = new HashSet<>();
set.add("tom");
set.add("jack");
set.add("rose");
Iterator iterator = set.iterator();
while(iterator.hasNext()) {
String str = (String) iterator.next();
System.err.println(str);
}
}
Collections
工具类
//反转顺序,反转后[5, 4, 3, 2, 1]
Collections.reverse(list);
//洗牌,随机分配,每次顺序不一样
Collections.shuffle(list);