容器
数组远远不能满足我们的需求。我们需要一种灵活的,容量可以随时扩充的容器来装载我们的对象。这就是
我们今天要学习的容器类,或者叫集合框架。
集合框架的简单的体系结构如下:
Collection 接口是一组允许重复的对象。
Set 接口继承 Collection,无序不允许重复,使用自己内部的一个排列机制。
List 接口继承 Collection,有序允许重复,以元素安插的次序来放置元素, 不会重新排列。
Map 接口是一组成对的键值对象,即所持有的是 key-value pairs。Map 中不能有重 复的 key。拥有自己的内部排列机制。
容器中的元素类型都为引用类型,不能放置原生数据类型(使用装箱即可),使用泛 型保留类型
实际上关于容器的体系结构是非常复杂的
Collection 接口
Collection 表示一组对象,它是集中,收集的意思,就是把一些数据收集起来,Collection 接口的两个子接口:
Set 中的数据没有顺序,不可重复
List 中的数据有顺序,可重复
实例如下:
<>
把类型明确的工作推迟到创建对象或调用方法的时候才去明确的特殊的类型
为什么需要泛型?
JDK1.4 以前类型不明确:
装入集合的类型都被当作 Object 对待,从而失去自己的实际类型。
从集合中取出时往往需要转型,效率低,容易产生错误。
泛型的好处:
增强程序的可读性和稳定性。
使用泛型,保留了容器中元素的类型,安全省心的使用容器。注意:没有必要引入泛型 的复杂性。
Iterator 接口
所有实现了Collection接口的容器类都有一个iterator方法用以返回一个实现了Iterator接口的对象。Iterator对象称作迭代器,用以方便的实现对容器内元素的遍历操作。
Iterator接口定义了如下方法:
使用迭代器时,分三步走策略:
第一步:获取对象
第二步:判断是否存在下一个
第三步:获取元素
List 接口
List接口,位置有序允许元素重复。多了一些关于位置(顺序)的方法
ArrayList
ArrayList 是 List 的子类,它和 HashSet 想法,允许存放重复元素,因此有序。集合中元 素被访问的顺序取决于集合的类型。如果对 ArrayList 进行访问,迭代器将从索引 0 开始, 每迭代一次,索引值加 1。然而,如果访问
HashSet 中的元素,每个元素将会按照某种随机 的次序出 现。虽然可以确定在迭代过程中能够遍历到集合中的所有元素,但却无法预知元 素被访问的次序。
List集合遍历
普通for循环方式
增强for循环方式
迭代器
Stream流遍历
LinkedList
LinkedList 是一种可以在任何位置进行高效地插入和删除操作的有序序列。
**LinkedList:**底层用双向链表实现的 List。特点:查询效率低,增删效率高,线程不安全。 **ArrayList:**底层用数组实现的 List。特点:查询效率高,增删效率低,线程不安全。
Set接口
Set 接口中的元素无序不可重复:不包含重复元素,最多包含一个 null,元素没有顺序 。
HashSet
HashSet 是 Set 接口的一个子类,主要的特点是:里面不能存放重复元素,而且采用散 列的存储方法,所以没有顺序。这里所说的没有顺序是指:元素插入的顺序与输出的顺序不 一致。 使用重写 equals 和 hashcode 来实现自
定义的类型的去重。
Java 中规定,两个内容 相同的对象应该具有相等的 hashcode
class Food {
private String name;
private double price;
public Food() { }
public Food(String name, double price) { this.name = name;
this.price = price;
}
//alt+shif+s ->h 按业务更改
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
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;
Food other = (Food) obj;
if (name == null) {
if (other.name != null)
return false; } else if (!name.equals(other.name))
return false;
return true;
}
}
Collection 类对象是否相等对象在调用remo
ve、contains 等方法时需要比较,这会涉及 到对象类型的 equals 方法和 hashCode 方法;对于自定义的类型,需要重写 equals 和 hashCode 方法以实现自定义的对象相等规则。
Map接口
实现Map接口的类用来存储键(key)-值(value) 对。
Map 接口的实现类有HashMap和TreeMap等。
Map类中存储的键-值对通过键来标识,所以键值不能重复。
HashMap: 线程不安全,效率高. 允许key或value为null
**HashTable:**线程安全,效率低. 不允许key或value为null
Properties: HashTable的子类,key和value都是string
Object put(Object key, Object value);
Object get(Object key);
Object remove(Object key);
boolean containsKey(Object key);
boolean containsValue(Object value);
int size();
boolean isEmpty();
void putAll(Map t);
void clear();
HashMap例子
Map m1 = new HashMap();
Map m2 = new HashMap();
m1.put("one", new Integer(1));
m1.put("two", new Integer(2)); m1.put("three", new Integer(3));
m2.put("A", new Integer(1));
m2.put("B", new Integer(2)); System.out.println(m1.size()); System.out.println(m1.containsKey("one")); System.out.println(m2.containsValue(new Integer(1)));
if (m1.containsKey("two")) {
int i = ((Integer)m1.get("two")).intValue(); System.out.println(i);
}
Map m3 = new HashMap(m1);
m3.putAll(m2);
System.out.println(m3);
Properties
Properties为Hashtable的子类,要求键与值只能为字符串 ,不能为null,长与 配置文件(与外界交互 的信息) 即内存与存储介质(文件、数据库、网络、服务器内存等)交互。