一、引言
程序中那么多的数据。我们总是想把它们梳理的整齐一些,如有一个100个学生的对象,按照前面所学的数组,我们可以把他放到一个Student[] students = new Student[100]
的数组中。但是如果数组中某一个学生辍学了,那么怎样便于处理这个数组呢?怎么知道这100个学生多少个也是另一个培训机构的学生呢?
假设我们有这样一个容器,容器中保存了许多相同的对象。这个容器有一些方法,我们可以通过方法获取到当前容器的包含对象的数量,某一个对象是否在容器中,将某一个对象放到容器中,将另一个容器的对象全部放到此容器中,等等。想到要是这样的一个容器,管理对象就会很方便了。
Java为我们提供了这样的一些容器。
二、存储对象可以考虑数组,集合
优缺点:
- 数组:Student stu=new Student[20];
- 弊端:
1.一旦创建,长度不可变
2.数组真实存放对象个数不可知 - 优点:
1.内存占用少
- 弊端:
- 集合:Collection,其内部实现本质还是数组
- 弊端:内存占用较大
- 优点:管理方便
三、集合
3.1 整体结构:
- Collection接口:
- List接口(元素有序,可重复的集合):<—数组
- ArrayList(主要的实现类)(数据结构:顺序存储结构–>查找操作有优势)
- LinkedList(数据结构:链式存储结构–>对于频繁插入删除操作有优势)
- Vector(古老的实现类,一般不用,线程安全)
- Set接口(元素无序,不可重复的集合):<—集合
- HashSet(主要实现类)(插入操作优势)
- LinkedHashSet(使用链表维护了添加顺序)(遍历操作优势)
- TreeSet(指定属性进行排序)
- List接口(元素有序,可重复的集合):<—数组
- Map接口(“key-value对”)
- HashMap(主要实现类)(可以添加null键null值)
- LinkedHashMap(HashMap的子类,维护添加顺序)
- TreeMap(指定属性对key进行定制排序)
- Hashtable(子类:Properties:常用来处理属性文件)
3.2 Collection
工具类/接口
- 对象排序接口:Comparable Comparator
- Iterator迭代器接口:遍历集合中元素
- 注意重写方法:
- equals()
- hashCode()
- compareTo()
- compare()
Collection方法:
方法名 | 说明 |
---|---|
size() | 内部元素个数 |
toString() | 字符串描述 |
isEmpty() | 是否为空 |
clear() | 清空 |
equals(Object obj) | 判断是否相等 |
hashCode() | 用来判断内部元素是否重复 |
toArray() | 集合转数组,数组转集合:List p= Arrays.asList(“Larry”, “Moe”, “Curly”); |
retainAll(Collection coll) | 取交集,返回给发起者 |
增: | |
add() | 添加元素 |
addAll(Collection arg0) | 添加所有元素 |
删: | |
remove(Object obj) | 删除,成功返回true |
removeAll(Collection coll) | 做差集 |
查: | |
contains(Object obj) | 是否包含,根据元素所在类的equals()方法进行判断,如果元素是自定义类,要重写equals() |
containsAll(Collection coll) | 是否全部包含 |
iterator() | 返回一个Iterator接口实现类的对象,从而实现集合的遍历 |
遍历集合的两种方式:
//使用迭代器,i相当于位于第一个元素上面的指针,i.next(),把下一个元素输出,指针下移
Iterator i = coll.iterator();
while (i.hasNext()) {
System.out.println(i.next());
}
//增强for循环实现集合遍历(也可以遍历数组),从集合coll中取一个元素,赋给局部变量ob,输出,再取下一个。
//推荐使用
for (Object ob : coll) {
System.out.println(ob);
}
3.3 ArrayList
相对Collection中,List中新增的方法:
方法 | 说明 |
---|---|
void add(int index,Object ele) | 指定索引位置添加 |
boolean addAll(int index,Collection eles) | 添加 |
Object get(int index) | 指定索引位置获取 |
Object remove(int index) | 删除指定索引位置元素,并返回原元素 |
Object set(int index,Object ele) | 修改指定索引位置元素,并返回原元素.(调用了equals()方法) |
int indexOf(Object ele) | 返回ele在集合中首次出现位置,无则返回-1.(调用了equals()方法) |
int lastIndexOf(Object ele) | 返回ele在集合中最后出现的位置,无则返回-1.(调用了equals()方法) |
List subList(int fromIndex,int toIndex) | 取List中一段,左闭右开,toIndex-fromIndex-1个元素 |
3.4 HashSet(Set的主要实现类)
- 特性:
- 无序:元素在底层存储的位置是无序的(根据hashcode来存)
- 不可重复(需要重写equals()+hashCode()):已存在的元素,相同元素存不进去
- Set中元素如何存储:
使用了哈希算法,当向Set中添加元素是,首相调用对象所在类的hashCode()方法,计算此对象的哈希值,此哈希值决定了此对象在 - Set中的存储位置
若此位置之前没有对象存储,则此对象直接存到此位置,若此位置已有对象存储,再通过equals()方法比较这两个对象是否相同,
如返回为true,则此对象不能添加,如返回为false,都存储(不建议)。 所以,hashCode(),equals()方法要一致。 - 方法
使用Collection继承的方法。
3.5 LinkedHashSet:
- 相对于HashSet维护了添加顺序,在遍历的时候可能需要知道添加顺序。
3.6 TreeSet:
- TreeSet提供了内部对象的排序功能。
- 向TreeSet中添加的对象必须是同一个类的
- 可以指定遍历顺序
- 自然排序:
- String,包装类等默认按照从小到大的顺序
- 自定义类需实现Comparable接口或者创建一个实现了Comparator接口且重写了compare()方法的类对象,将此对象作为形参传给TreeSet的构造器
即需要对象可比较或者传入一个比较器 - 重写的compareTo()中可以设置某个属性的从大到小或从小到大
重写元素的compareTo():
//注:向TreeSet中添加元素时,先compareTo()比较,返回0时认为两个对象相等,
//可能造成错误:虽然只是这个属性相等,但程序认为两个对象相同,从而不能添加
//解决办法:层层比较
public int compareTo(Object arg0) {
if (arg0 instanceof Person) {
//先比较name的大小
int i = this.name.compareTo(((Person) arg0).name);
//name相同时,比较age的大小,层层递进
if (i == 0) {
return this.age.compareTo(((Person) arg0).age);
} else {
return i;
}
}
return 0;
}
实现Comparable接口:
TreeSet<Employee> set = new TreeSet<>(new Comparator<Employee>() {
@Override
public int compare(Employee arg0, Employee arg1) {
MyDate date0 = arg0.getBirthday();
MyDate date1 = arg1.getBirthday();
// 注意:if(date0.getYear()!=date1.getYear()),此语句比较的是两个Integer的地址值
if (date0.getYear().compareTo(date1.getYear()) != 0) {
return date0.getYear().compareTo(date1.getYear());
} else {
if (date0.getMonth().compareTo(date1.getMonth()) != 0) {
return date0.getMonth().compareTo(date1.getMonth());
} else {
return date0.getDay().compareTo(date1.getDay());
}
}
}
});
3.7 HashMap:
用来存放键值对数据。
由于其key为Set,其遍历是无序的。(LindedHashMap添加有序功能)
- key-value:key用Set存放,value用Collection存放,一个key-value为一个entry(Map.Entry),entry用set存放
- 取key:
Set set=map.keySet(); - 取value:
Collection coll=map.values(); - 取entry:
Set set2=map.entrySet(); - 添加,删除操作:
- Object put(Object key,Object value),添加一个entry,若为覆写,则返回被覆写value
- Object remove(Object key),按key移除一个entry,返回value
3 .void putAll(Map t),添加一个Map - void clear()
- 元视图操作:
1.Set keySet() ,用来遍历key
2.Collection values() ,用来遍历value
3.Set entrySet(),用来遍历entry - 元素查询操作:
- Object get(Object key),返回指定key的value值,若无此key则返回Null
- boolean containsKey(Object key) ,是否包含key
- boolean containsValue(Object value),是否包含value,需使用value类equals()方法
- int size()
- boolean isEmpty()
6 .boolean equals(Object obj)
3.8 LindedHashMap:
- 可以按照添加顺序实现遍历,其他与HashMap相同
3.9 TreeMap:
- 同TreeSet,需按照key定制排序,其他与HashMap相同