集合
集合框架
- 可以动态保存多个对象,使用方便。
-
有多种方法,add/remove/set/get
单列集合
双列集合 kv键值
collenction
- collection实现子类可以存放多个元素,每个元素可以是Object
- 有些collection的实现类,可以存放重复元素,有些不可以
- 有些collection的实现类,有些是有序的List 有些不是有序的Set
- collection接口没有直接的实现子类,是能过它的子接口Set和List来实现
- Collection接口遍历元素方式使用Iterator 迭代器
- Iterator对象称为迭代器,主要用于遍历Collection集合中的元素。
- 所有实现了Collection接口的集合类都有一个iterator()方法,用以返回一个实现了Iterator接口的对象,即可以返回 一个迭代器。
- Iterator仅用于遍历集合,Iterator本身并不存放对象。
- List
- ArrayList 单线程用,线程不安全,但执行效率高。
- LinkedList 线程不安全 底层实现双向链表和双端队列特点。
- Vector 线程同步,线程安全。
- Set 无序,没索引,不允许重复,最多只能有一个null
- HashSet
- LinkedHashSet
- TreeSet
- 当我们使用无参构造器,创建TreeSet时,仍然是无序的
- 希望添加元素,按时一定方式排序,使用TreeSet 提供的一个构造器,可以传入一个比较器(匿名内部类)并指定排序规则。
-
在底层传给了TreeMap的一个属性comparator
TreeSet treeSet = new TreeSet(new Comparator(){
@override
public int compare(Object o1, Object o2){
return ((String) o1).compareTo((String) o2);
}
});
只能用生成器,与for-each遍历。
常用方法:
- add: 添加单个元素
- remove:删除指定元素
- contains:查找元素是否存在
- size: 获取元素个数
- isEmpty:判断是否为空
- clear:清空
- addAll: 添加多个元素
- containsAll:查找多个元素是否都存在
- removeAll: 删除多个元素。
public class Test07 {
public static void main(String[] args) {
Collection col = new ArrayList();
col.add(new Book("天龙八部", "Gorgage", 100.0));
col.add(new Book("天龙七部", "Gorgage1", 98.0));
col.add(new Book("天龙六部", "Gorgage2", 56.0));
for (Object book : col) {
System.out.println(book);
}
Iterator iterator = col.iterator();
while (iterator.hasNext()) {
Object next = iterator.next();
System.out.println(next);
}
}
}
class Book {
private String bookName;
private String name;
private double price;
public Book(String bookName, String name, double price) {
this.bookName = bookName;
this.name = name;
this.price = price;
}
public String getBookName() {
return bookName;
}
public void setBookName(String bookName) {
this.bookName = bookName;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
@Override
public String toString() {
return "Book{" +
"bookName='" + bookName + '\'' +
", name='" + name + '\'' +
", price=" + price +
'}';
}
}
如果是List接口 还可以增加一种for 循环里面使用get(索引)来遍历。
容量扩展一般按1.5倍来扩展。
底层结构 | 增删效率 | 改查效率 | |
---|---|---|---|
ArrayList | 可变数组 | 较低,数组扩容 | 较高 |
LinkedList | 双向链表 | 较高,通过链表追加 | 较低 |
- 如果我们改查的操作多,用ArrayList
- 如果我们增删的操作多,选择LinkedList
- 一般来说,在程序中。80%-90%是查询,因此大部分情况 下选择ArrayList
- 在一个项目中,根据业务灵活选择,也可能这样,一个模块 使用ArrayList,另外一个模块使用LinkedList
LinkedHashSet
- LinkedHashSet加入顺序和取出元素、数据的顺序一致
- LinkedHashSet 底层维护的是一个LinkedHashMap(是 HashMap 的子类)
- LinkedHashSet 底层结构(数组table + 双向链表)
- 添加第一次时,直接将 数据 table 扩容到16,存放的结点类型是LinkedHashMap$Entry类型
- 数组是 HashMapEntry类型
map
- Map与Collection并列存在。用于保存具有映射关系的数据:key-Value
- Map中的key和value可以是任何引用类型的数据,会封装到HashMap$Node对象中
- Map中的key不允许重复,
- Map中的value可以重复
- Map中的key 可以为null, value 也可以为null, 注意key最多只有一个为null,value可以多个
- 常用String类作为Map的key
- key 和 value之间存在单向一对一关系,即通过指定的key 总能找到对应的value
Map方法:
- put:添加
- remove:根据键删除
- get:根据键获取值
- size:获取元素个数
- isEmpty:判断个数是否为0
- clear:清除
-containsKey: 查找键是否存在
Map遍历方法:
public class Test08 {
public static void main(String[] args) {
Map map = new HashMap();
map.put("Gorgage","marry");
map.put("Gorgage1","marry1");
map.put("Gorgage2","marry2");
map.put("Gorgage3","marry3");
map.put(null,"marry4");
map.put("Gorgage5",null);
Set keySet = map.keySet();
System.out.println(map.keySet());
System.out.println("====for-each====");
for (Object key: keySet
) {
System.out.println(map.get(key));
}
System.out.println("====iterator====");
Iterator iterator = keySet.iterator();
while (iterator.hasNext()) {
Object next = iterator.next();
System.out.println(map.get(next));
}
System.out.println("====map.values====");
Collection values = map.values();
System.out.println(values);
System.out.println("====mmap.entrySet====");
Set set = map.entrySet();
for (Object entry:set
) {
//转Map.Entry,向下转型
Map.Entry m = (Map.Entry) entry;
System.out.println(m.getKey() + "++++"+m.getValue());
}
Iterator iterator1 = set.iterator();
while (iterator1.hasNext()) {
Object next = iterator1.next();
//转Map.Entry,向下转型
Map.Entry m = (Map.Entry)next;
System.out.println(m.getKey() + "++++"+m.getValue());
}
}
}
[null, Gorgage1, Gorgage2, Gorgage, Gorgage3, Gorgage5]
====for-each====
marry4
marry1
marry2
marry
marry3
null
====iterator====
marry4
marry1
marry2
marry
marry3
null
====map.values====
[marry4, marry1, marry2, marry, marry3, null]
====mmap.entrySet====
null++++marry4
Gorgage1++++marry1
Gorgage2++++marry2
Gorgage++++marry
Gorgage3++++marry3
Gorgage5++++null
null++++marry4
Gorgage1++++marry1
Gorgage2++++marry2
Gorgage++++marry
Gorgage3++++marry3
Gorgage5++++null
进程已结束,退出代码0
- HashMap
- Map接口的常用实现类:HashMap / Hashtable和Properties
- HashMap是Map接口使用频率最高的实现类。
- HashMap 是以 key-value对的方式 来存储数据
- key不能重复,但是值可以重复,允许使用null键和值
- 如果添加相同的key,则会覆盖原来的key-value,等同于修改
- 与HashSet一样,不保证映射的顺序,因为底层是以hash表的方式来存储的
- HashMap没有实现同步,因此是线程不安全的。
底层机制与HashSet相同,因为HashSet底层是HashMap
- HashMap底层维护了Node类型的数组table,默认为null
- 当创建对象时,将加载因子(loadfactor)初始化为0.75
- 当添加key-value时,能过key的哈希值得到在table的索引,然后判断该索引处是否有元素,如果没有元素直接添加。如果该索引处有元素,继续判断该元素的key是否和准备加入的key相等 ,如果相等,则直接替换value,如果不相等 要判断是树结果 还是链表结构,做出相应处理。如果添加时发现容量不够 ,则需要扩容。
- 第1次添加,则需要扩容table容量为16,临界值(threshold)为12
- 以后再扩容,则需要扩容table容量为16,临界值为原来的2倍,即24,依次类推。
- 在java8中,如果一条链表的元素个数超过TREEIFY_THRESHOLD默认是8,并且table的大小>= MIN_TREEIFY_CAPACITY(默认64),就会进行树化(红黑树)
- Hashtable
他继承Dictionary,实现Map接口。
- 存放的元素是k-v
- hashtable的键值都不能为null,否则会抛出NullPointerException
- hashtable使用方法基本和HashMap一样。
- hashTable是线性安全的,HashMap不安全
- hashtableEntry的方法。
- hashTable创建时会有11个空间。
- threshold = 8 = 11 * 0.75
- Properties
- Properties 继承Hashtable,并实现Map接口,也是使用一种键值对的形式保存
- 他的使用特点和Hashtable类似
- Properties 还可以用于从xxx.properties文件中,加载数据到Properties类对象,并进行读取和修改。
- xxx.properties文件通常作为配置文件,可参考
- LinkedHashMap
- TreeMap
是TreeSet的底层
collenctions
在开发中,选择什么 集合实现类,主要取决于业务操作特点,然后根据集合实现类特性进行选择
- 先判断存储类型(一组对象或一组键值对)
- 一组对象:Collection接口
2.1 允许重复:List
2.1.1 增删多:LinkedList底层维护了一个双向链表
2.1.2 改查多:ArrayList底层维护Object 类型的可变数组
2.2 不允许重复:Set
2.2.1 无序:HashSet 底层HashMap,维护了一个哈希表,即数组+链表+红黑树
2.2.2 排序:TreeSet
2.2.3 插入和取出顺序一致:LinkedHashSet, 维护数组+双向链表 - 一组键值对:Map
3.1 键无序:HashMap 底层哈希表 数组+链表+红黑树
3.2 键排序: TreeMap
3.3 键插入和取出顺序一致:LinkedHashMap
3.4 读取文件 Properties - Collections是一个操作 Set List Map等 集合的工具类
- Collections中提供了一系列静态方法对集合元素进行排序、查询和修改
5.1 reverse(List):反转List中元素顺序
5.2 shuffle(List): 对List集合元素进行随机排序
5.3 sort(List): 根据合元素的自然顺序对指定List集合元素按升序排序,
5.4 sort(List, Comparator): 根据指定的Comparator产生的顺序对List集合元素进行随机
5.5 swap(List, int, int):将指定List 集合中的i外元素和j 处元素进行交换。 - Object max(Collection)根据元素的自然顺序,返回给定集合中的最大元素
- Object max(Collection, Comparator)根据Comparator指定的顺序返回给定集合中最大元素
- Object min(Collection)
- Object min(Collection, Comparator)
- int frequency(Collection, Object):返回指定集合中指定元素的出现次数
- void copy(List dest, List src)将src中的内容复制到dest中
- boolean replaceAll(List list, Object oldVal, Object newVal)使用新值替换List 对象的所有旧值。