集合只能存放对象。比如你存一个 int 型数据 1放入集合中,其实它是自动转换成 Integer 类后存入的,Java中每一种基本类型都有对应的引用类型。
集合存放的是多个对象的引用,对象本身还是放在堆内存中。
集合可以存放不同类型,不限数量的数据类型。
1、集合框架简介:
Java 集合框架主要包括两种类型的容器,一种是集合(Collection),存储一个元素集合,另一种是图(Map),存储“键对象/值对象”映射
Collection 接口又有2 种子类型,List、Set,再下面是一些抽象类,最后是具体实现类,常用的有 ArrayList、LinkedList、HashSet、LinkedHashSet、HashMap、LinkedHashMap 等等
Map(映射)接口是不同于Collection 接口的另一个重要接口,Map 不是集合,但是它完全整合在集合中
Map(映射)接口的实现类中,最常用的是HashMap、TreeMap
2、Collection接口
collection主要方法:
boolean add(Object o)添加对象到集合
boolean remove(Object o)删除指定的对象
int size()返回当前集合中元素的数量
boolean contains(Object o)查找集合中是否有指定的对象
boolean isEmpty()判断集合是否为空
Iterator iterator()返回一个迭代器
boolean containsAll(Collection c)查找集合中是否有集合c中的元素
boolean addAll(Collection c)将集合c中所有的元素添加给该集合
void clear()删除集合中所有元素
void removeAll(Collection c)从集合中删除c集合中也有的元素
void retainAll(Collection c)从集合中删除集合c中不包含的元素
Collection接口的子接口的集合遍历方式:
//迭代器遍历集合
List<Student> list = new ArrayList<Student>();
Iterator<Student> it = list.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
//foreach遍历集合
Set<Student> st = new TreeSet<Student>();
for (Student student : st) {
System.out.println(student);
}
//for循环遍历集合
for(int i = 0 ;i<list.size();i++) {
int j= (Integer) list.get(i);
System.out.println(j);
}
3、List接口
List中的元素是有顺序的
List通常允许重复元素
List的实现类通常支持null元素
可以通过索引访问List集合中的元素
常用方法:
(1)、添加
void add(int Index , E element):在list的指定位置插入元素
void addAll(int index , Collection<? Extends E> e):将指定collection中的所有元素插入到列表中的指定位置
(2)、删除
E remove(int Index):删除指定位置的元素,并返回该元素;
(3)、修改
E set(int index , E element):替换指定位置的元素,并返回被替换的元素
(4)、获取
Int indexOf(Object o):返回指定元素第一次出现的索引,如果该list中不含则返回-1;
E get(int Index):返回指定位置的元素;
ArrayList:
ArrayList基于数组实现,是一个动态的数组队列。但是它和Java中的数组又不一样,它的容量可以自动增长
由于数据是存入数组中的,所以它的特点也和数组一样,查询很快,但是中间部分的插入和删除很慢
LinkedList:
LinkedList基于链表实现,在List中间进行插入和删除的代价较低,提供了优化的顺序访问。LinkedList在随机访问方面相对比较慢,但是它的特性集较ArrayList更大
使用场景:
ArrayList是由数组实现的,方便查找,返回数组下标对应的值即可,适用于多查找的场景
LinkedList由链表实现,插入和删除方便,适用于多次数据替换的场景
4、Set接口
Set类型容器不能包含重复元素,当加入一个元素到容器中时,需要比较元素的内容是否重复,所以加入Set类型对象容器的对象必须重写equals()方法
元素可能有顺序,可能没有顺序
不能基于索引访问Set中的元素
HashSet
HashSet类是基于哈希算法的Set接口实现的,主要有一下几个特点:
HashSet中元素没有顺序
不允许出现重复元素,重复指的是用hashCode()、equals()比较返回true
允许包含null元素
如果需要重写equals方法,那么必须重写hashCode方法
TreeSet
TreeSet集合中的元素有顺序,使用元素的自然顺序对元素进行排序
TreeSet中不允许使用null元素
当TreeSet中的元素类型为自定义类型时,必须重写compareTo方法
public class Student implements Comparable<Student>{
String name;
int age,id;
public Student (String name,int age,int id) {
this.name = name;
this.age = age;
this.id = id;
}
public String toString () {
return "name:"+name+"age:"+age+"id:"+id;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
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 (age != other.age)
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;
}
@Override
public int compareTo(Student s) {
if(this.id>s.id)
return 1;
else if(this.id==s.id)
return 0;
else
return -1;
}
}
public class Test03 {
public static void main(String[] args) {
Student s1 = new Student ("zhang1",18,16101);
Student s2 = new Student ("zhang2",28,16102);
Student s3 = new Student ("zhang3",38,16103);
Set<Student> st = new TreeSet<Student>();
st.add(s2);st.add(s3);st.add(s1);
for (Student student : st) {
System.out.println(student);
}
}
}
运行:
name:zhang1age:18id:16101
name:zhang2age:28id:16102
name:zhang3age:38id:16103
5、Map(key,value)
key不能重复,value可以重复
Map中常见方法:
1、添加:
put(K key, V value) 可以相同的key值,但是添加的value值会覆盖前面的,返回值是前一个,如果没有就返回null
putAll(Map<? extends K,? extends V> m) 从指定映射中将所有映射关系复制到此映射中(可选操作)。
2、删除
remove() 删除关联对象,指定key对象
clear() 清空集合对象
3、获取
get(key) 可以用于判断键是否存在的情况。当指定的键不存在的时候,返回的是null。
size() 返回int类型的集合长度
4、判断
boolean isEmpty() 长度为0返回true否则false
boolean containsKey(Object key) 判断集合中是否包含指定的key
boolean containsValue(Object value) 判断集合中是否包含指定的value
Map中所有的key放一起,就组成了一个Set集合,所以Key没有顺序,并不能重复
Map中的keySet()方法,用于返回Map中所有Key组成的Set对象
把所有的value放一起,就组成了一个可以重复,没有次序的Collection集合
Map中的Value()方法,用于返回Map中所有Value组成的Collection对象
HashMap与TreeMap的区别:
HashMap:基于哈希表实现。使用HashMap要求添加的键类明确定义了hashCode()和equals()(可以重写hashCode()和equals())
HashMap :适用于在Map中插入、删除和定位元素。Treemap:适用于按自然顺序或自定义顺序遍历键(key)。
HashMap通常比TreeMap快一点(树和哈希表的数据结构使然),建议多使用HashMap,在需要排序的Map时候才用TreeMap。
HashMap的结果是没有排序的,TreeMap实现SortMap接口,能够把它保存的记录根据键排序,默认是按键值的升序排序,也可以指定排序的比较器,当用Iterator遍历TreeMap时,得到的记录是排过序的
HashMap里面存入的键值对在取出的时候是随机的,它根据键的HashCode值存储数据,根据键可以直接获取它的值,具有很快的访问速度。在Map中插入、删除和定位元素,HashMap是最好的选择。TreeMap取出来的是排序后的键值对。但如果要按自然顺序或自定义顺序遍历键,那么TreeMap会更好。
遍历Map的方式:
1、将map 集合中所有的键取出存入set集合。
Set<K> keySet() 返回所有的key对象的Set集合,再通过get方法获取键对应的值。
2、 values() ,获取所有的值.
Collection<V> values()不能获取到key对象
3、 Map.Entry对象
Set<Map.Entry<k,v>> entrySet() 将map 集合中的键值映射关系打包成一个对象。
Map.Entry对象通过Map.Entry 对象的getKey,getValue获取其键和值。
第一种方式:使用keySet
将Map转成Set集合(keySet()),通过Set的迭代器取出Set集合中的每一个元素(Iterator)就是Map集合中的所有的键,再通过get方法获取键对应的值。
public class Demo1 {
public static void main(String[] args) {
Map<Integer, String> map = new HashMap<Integer, String>();
map.put(1, "aaaa");
map.put(2, "bbbb");
map.put(3, "cccc");
System.out.println(map);
// 获取方法:
// 第一种方式: 使用keySet
// 需要分别获取key和value,没有面向对象的思想
// Set<K> keySet() 返回所有的key对象的Set集合
Set<Integer> ks = map.keySet();
Iterator<Integer> it = ks.iterator();
while (it.hasNext()) {
Integer key = it.next();
String value = map.get(key);
System.out.println("key=" + key + " value=" + value);
}
}
}
第二种方式: 通过values()获取所有值,不能获取到key对象
public static void main(String[] args) {
Map<Integer, String> map = new HashMap<Integer, String>();
map.put(1, "aaaa");
map.put(2, "bbbb");
map.put(3, "cccc");
System.out.println(map);
// 通过values 获取所有值,不能获取到key对象
// Collection<V> values()
Collection<String> vs = map.values();
Iterator<String> it = vs.iterator();
while (it.hasNext()) {
String value = it.next();
System.out.println(" value=" + value);
}
}
第三种方式: Map.Entry
public static interface Map.Entry<K,V> 通过Map中的entrySet()方法获取存放Map.Entry<K,V>对象的Set集合。
Set<Map.Entry<K,V>> entrySet() 面向对象的思想将map集合中的键和值映射关系打包为一个对象,就是Map.Entry,将该对象存入Set集合,Map.Entry是一个对象,那么该对象具备的getKey,getValue获得键和值。
public static void main(String[] args) {
Map<Integer, String> map = new HashMap<Integer, String>();
map.put(1, "aaaa");
map.put(2, "bbbb");
map.put(3, "cccc");
System.out.println(map);
// Set<Map.Entry<K,V>> entrySet()
// 返回的Map.Entry对象的Set集合 Map.Entry包含了key和value对象
Set<Map.Entry<Integer, String>> es = map.entrySet();
Iterator<Map.Entry<Integer, String>> it = es.iterator();
while (it.hasNext()) {
// 返回的是封装了key和value对象的Map.Entry对象
Map.Entry<Integer, String> en = it.next();
// 获取Map.Entry对象中封装的key和value对象
Integer key = en.getKey();
String value = en.getValue();
System.out.println("key=" + key + " value=" + value);
}
}