任何对象没有使用泛型时加入集合类后,自动转变为Object类型,所以在取出的时候,需要进行强制类型转换。使用泛型之后不用强制转换。
- Java 集合框架主要包括两种类型的容器,一种是集合(Collection),存储一个元素集合,另一种是图(Map),存储键/值对映射。Collection 接口又有 3 种子类型,List、Set 和 Queue。
- ArrayList 实现了List的接口,实现了可变大小的数组,随机访问和遍历元素时,提供更好的性能。该类也是非同步的,在多线程的情况下不要使用。ArrayList 增长当前长度的50%,插入删除效率低。
- LinkedList
该类实现了List接口,允许有null(空)元素。主要用于创建链表数据结构,该类没有同步方法,如果多个线程同时访问一个List,则必须自己实现访问同步,解决方法就是在创建List时候构造一个同步的List。 - Vector
该类和ArrayList非常相似,但是该类是同步的,可以用在多线程的情况,该类允许设置默认的增长长度,默认扩容方式为原来的2倍。 - HashSet
该类实现了Set接口,不允许出现重复元素,不保证集合中元素的顺序,允许包含值为null的元素,但最多只能一个。 - HashMap
HashMap 是一个散列表,它存储的内容是键值对(key-value)映射。
该类实现了Map接口,根据键的HashCode值存储数据,具有很快的访问速度,最多允许一条记录的键为null,不支持线程同步。 - Properties
继承于Hashtable。表示一个持久的属性集,属性列表以key-value的形式存在,key和value都是字符串。在很多需要避免硬编码的应用场景下需要使用properties文件来加载程序需要的配置信息,比如JDBC、MyBatis框架等。
1.顺序容器ArrayList
ArrayList<String> notes = new ArrayList<String>();
容器类有两个类型:第一个尖括号中写容器的类型,第二个尖括号中写元素的类型,第一个尖括号后面是这个容器类的名字。
相关的功能:
- notes .add( s ); 添加元素,把元素依次往后面加
- notes .add( index , s ); 把某个元素加到指定位置,该位置原来的元素被推到下一个位置
- notes .size(); 统计里面有几个元素
- notes .get( index ); 得到容器里面对应下标的类容
- notes .remove( index ); 删除对应位置的内容,并返回被删除的内容,如果下标越界会报异常
- notes .toArray( a ); 自动把容器里面的类容填充到数组
- public String[] list() {
String []a = new String[notes.size()];
// for (int i = 0; i < a.length; i++) {
// a[i] = notes.get(i);
// }
notes.toArray(a);
return a;
}
2. Hash表
散列表
(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构,Key和value一一对应、成对存在。它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。
- 语法格式:
HashMap<Integer,String> coinnames = new HashMap<Integer,String>();
例一:map的基本方法
package com.lovo.testmap;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class TestMap {
public static void main(String[] args) {
Map<Integer, String> map = new HashMap<>();
//放入键值对
map.put(1, "aaa");
map.put(2, "bbb");
map.put(3, "ccc");
map.put(4, "ddd");
//键无序,并且不能重复
//map.put(4, "eee");
//值可以重复
//map.put(5, "ddd");
//map.put(6, "ddd");
//map.put(7, "ddd");
//通过键获取值
String value = map.get(5);
System.out.println(value);
//获取所有的键
Set<Integer> sets = map.keySet();
//直接循环键
for (Integer i : sets) {
System.out.println(i + " " + map.get(i));
}
//获取所有的值
Collection<String> cs = map.values();
for (String s : cs) {
System.out.println(s);
}
}
}
例二:Entry接口
package com.lovo.testmap;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class TestMap2 {
public static void main(String[] args) {
Map<String,Student> map = new HashMap<>();
Student s1 = new Student(1,"张三1",21);
Student s2 = new Student(2,"张三2",22);
Student s3 = new Student(3,"张三3",23);
Student s4 = new Student(4,"张三4",24);
map.put("zs1", s1);
map.put("zs2", s2);
map.put("zs3", s3);
map.put("zs4", s4);
// Set<String> ss = map.keySet();
//
// for (String s : ss) {
// System.out.println(s + " " + map.get(s));
// }
//Map中有一个Entry的内部接口,其实就是保存的键和值在一起的内容
//整个一起的内容放入到了Set集合中
Set<Map.Entry<String, Student>> entry = map.entrySet();
//使用迭代器循环Map
Iterator<Map.Entry<String,Student>> it = entry.iterator();
while(it.hasNext()) {
Map.Entry<String,Student> en = it.next();
System.out.println(en.getKey() + " " + en.getValue());
}
}
}
例三:值为集合的情况
package com.lovo.testmap;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
public class TestMap3 {
public static void main(String[] args) {
Student s1 = new Student(1,"张三1",21);
Student s2 = new Student(2,"张三2",22);
Student s3 = new Student(3,"张三3",23);
Student s4 = new Student(4,"张三4",24);
Student s5 = new Student(5,"张三5",25);
Student s6 = new Student(6,"张三6",26);
Student s7 = new Student(7,"张三7",27);
Student s8 = new Student(8,"张三8",28);
List<Student> list1 = new ArrayList<Student>();
list1.add(s1);list1.add(s2);
List<Student> list2 = new ArrayList<Student>();
list2.add(s3);list2.add(s4);list2.add(s5);
List<Student> list3 = new ArrayList<Student>();
list3.add(s6);list3.add(s7);list3.add(s8);
Map<String,List<Student>> map = new HashMap<>();
map.put("j178",list1);
map.put("j179",list2);
map.put("j180",list3);
//通过Iterator迭代这个map集合,把所有学生信息显示出来
Set<Map.Entry<String,List<Student>>> entry = map.entrySet();
Iterator<Map.Entry<String,List<Student>>> it = entry.iterator();
while(it.hasNext()) {
Entry<String,List<Student>> en = it.next();
System.out.println(en.getKey());
List<Student> list = en.getValue();
for (Student student : list) {
System.out.println(student);
}
}
}
}
3. Iterator(迭代器)
3.1什么情况使用迭代器
- 需要对集合遍历且遍历过程中需要修改集合内容时,就必须使用迭代器,而不能直接操作集合,否则会导致 ConcurrentModifiedException。
- 对无限的操作,如打印所有整数;
- Iterator 适合访问链式结构,因为迭代器是通过next()和Pre()来定位的.可以访问没有顺序的集合.
3.2特点
- 将遍历的逻辑(迭代器)和对每一个迭代对象(迭代器调用代码)分开,使得遍历可以被重用。
- 不包含任何有关它所遍历的序列的类型信息,能够将遍历序列的操作与序列底层的结构分离,统一了对容器的访问方式。
3.3基本操作
- 调用 it.next()会返回迭代器的下一个元素,并且更新迭代器的状态。
- 调用 it.hasNext() 用于检测集合中是否还有元素。
- 调用 it.remove() 将迭代器返回的元素删除。
3.4Iterator与ListIterator的区别
Iterator只能正向遍历集合,适用于获取移除元素。ListIerator继承自Iterator,专门针对List,可以从两个方向遍历List,同时支持元素的修改。