集合
集合流程图
集合的概述:
集合其实就是一个大小可变的容器,可以存储各种引用类型的数据,包括基本类型的包装类型.
集合和数组的区别:
- 数组大小是固定,只能存储相同数据类型的数据(基本类型和引用类型都可以)。
- 集合大小是可变的,可以存储各种引用类型的数据(基本类型不能存,要用,必须转化成对应的包装类)。
集合分类:
集合分为两大类:Collection(单列集合)和Map(双列集合)
Collection:
是单列集合类的根接口,用于存储一系列符合某种规则的元素,它有两个重要的子接口(List接口和Set接口)
List接口:
List接口的主要实现类有java.util.ArrayList和java.util.LinkedList,
Set接口:
Set接口的主要实现类有java.util.HashSet和java.util.LinkedHashSet,java.util.TreeSet。
单列集合方法归类:
Collection集合通用方法:
Collection是所有单列集合的父接口,
因此在Collection中定义了单列集合(List和Set)通用的一些方法,
这些方法可用于操作所有的单列集合。方法如下:
public boolean add(E e): 把给定的对象添加到当前集合中 。
public void clear() :清空集合中所有的元素。
public boolean remove(E e): 把给定的对象在当前集合中删除。
public boolean contains(Object obj): 判断当前集合中是否包含给定的对象。
public boolean isEmpty(): 判断当前集合是否为空。
public int size(): 返回集合中元素的个数。
public Object[] toArray(): 把集合中的元素,存储到数组中
ArrayList常用方法
public boolean remove(Object o) 删除指定的元素,返回删除是否成功
public E remove(int index) 删除指定索引处的元素,返回被删除的元素
public E set(int index, E element) 修改指定索引处的元素,返回被修改的元素
public E get(int index) 返回指定索引处的元素
public int size() 返回集合中的元素的个数
LinkedList常用方法
- public void addFirst(E e)`:将指定元素插入此列表的开头。
- `public void addLast(E e)`:将指定元素添加到此列表的结尾。
- `public E getFirst()`:返回此列表的第一个元素。
- `public E getLast()`:返回此列表的最后一个元素。
- `public E removeFirst()`:移除并返回此列表的第一个元素。
- `public E removeLast()`:移除并返回此列表的最后一个元素。
- `public E pop()`:从此列表所表示的堆栈处弹出一个元素。
- `public void push(E e)`:将元素推入此列表所表示的堆栈。
注意:
1.Set集合并没有特有的功能,所以它三个子类集合HashSet集合, LinkedHashSet集合,TreeSet集合都是使用Collection父接口中的方法
2.Set集合元素无索引,所以遍历方式只能是:迭代器,增强for循环
List接口:
也称List集合,但凡是实现了List接口的类都叫做List集 合
特点:元素有索引,元素存取有序,元素可重复
实现类:
ArrayList集合:有索引,元素存取有序,元素可重复(数据存储结构为数组结构)
LinkedList集合:无索引,排列有序,可重复(数据存储结构为链式结构)
Set接口:
也称Set集合,但凡是实现了Set接口的类都叫做Set集合
特点:元素无索引,元素存取无序,元素不可重复(唯一)
实现类:
HashSet集合:元素无索引,元素存取无序,元素不可重复(唯一)
LinkedHashSet集合:元素无索引,元素存取有序(数据存储结构为链式结构),元素不可重复(唯一)
TreeSet集合:元素无索引,元素存取无序,元素不可重复(唯一),但元素可排序
拥有public TreeSet(): 根据其元素的自然排序进行排序 public TreeSet(Comparator<E> comparator): 根据指定的比较器进行排序
)
HashSet保证元素唯一原理
HashSet集合保证元素唯一的原理:底层是哈希表结构,哈希表保证元素唯一依赖于hashCode()和equals方法();
1.当HashSet集合存储元素的时候,就会调用该元素的hashCode()方法计算哈希值
2.判断该哈希值位置上,是否有相同哈希值的元素
3.如果该哈希值位置上没有相同哈希值的元素,那么就直接存储
4.如果该哈希值位置上有相同哈希值的元素,那么就产生了哈希冲突
5.如果产生了哈希冲突,就得调用该元素的equals()方法与该哈希值位置上的所有元素进行一一比较:
如果该哈希值位置上有任意一个元素与该元素相等,那么就不存储
如果该哈希值位置上所有元素与该元素都不相等,那么就直接存储
补充:
Object类: hashCode()和equals()方法;
hashCode():Object类中的hashCode()方法是根据地址值计算哈希值
Map集合
Map集合的概述:
Map<K,V>接口概述:也称Map集合,是所有双列集合的顶层父接口,K用来限制键的类型,V用来限制值的类型
Map集合的特点:
1.Map集合存储元素是以键值对的形式存储,也就是说每一个键值对都有键和值
2.通过键取值
3.Map集合中的键不能重复,如果键重复了,那么值就会覆盖
4.Map集合中的值是可以重复
Map集合的实现类:
HashMap类:无索引,键唯一,键值对存取无序, 由哈希表保证键唯一
LinkedHashMap类:无索引,键唯一,键值对存取有序,由哈希表保证键唯一,由链表保证键值对存取有序
TreeMap类:无索引,键唯一,可以对键值对进行排序, 由哈希表保证键唯一
Map的常用方法:
- public V put(K key, V value)`: 把指定的键与指定的值添加到Map集合中。
- `public V remove(Object key)`: 把指定的键 所对应的键值对元素 在Map集合中删除,返回被删除元素的值。
- `public V get(Object key)` 根据指定的键,在Map集合中获取对应的值。
- `public boolean containsKey(Object key)`:判断该集合中是否有此键
- `public Set<K> keySet()`: 获取Map集合中所有的键,存储到Set集合中。
- `public Collection<V> values()` 获取Map集合中所有的值,存储到Collection集合中
- `public Set<Map.Entry<K,V>> entrySet()`: 获取到Map集合中所有的键值对对象的集合(Set集合)。
Map的遍历
方式1:键找值方式
通过元素中的键,获取键所对应的值
分析步骤:
1. 获取Map中所有的键,由于键是唯一的,所以返回一个Set集合存储所有的键。方法提示:`keyset()`
2. 遍历键的Set集合,得到每一个键。
3. 根据键,获取键所对应的值。方法提示:`get(K key)`
方式2:键值对方式
步骤
根据键值对对象的方式
1.获取集合中所有键值对对象,以Set集合形式返回。 Set<Map.Entry<K,V>> entrySet()
2.遍历所有键值对对象的集合,得到每一个键值对(Entry)对象。
3.在循环中,可以使用键值对对对象获取键和值 getKey()和getValue()
Entry<K,V>接口:简称Entry项,表示键值对对象,用来封装Map集合中的键值对
Entry<K,V>接口:是Map接口中的内部接口,在外部使用的时候是这样表示: Map.Entry<K,V>
Map集合中提供了一个方法来获取所有键值对对象:
public Set<Map.Entry<K,V>> entrySet()
集合的嵌套
- List嵌套List
public class Test1 {
public static void main(String[] args) {
/*
集合的嵌套:
- List嵌套List
- List嵌套Map
- Map嵌套Map
结论:任何集合内部都可以存储其它任何集合
*/
// List嵌套List
// 创建一个List集合,限制元素类型为String
List<String> list1 = new ArrayList<>();
// 往集合中添加元素
list1.add("王宝强");
list1.add("贾乃亮");
list1.add("陈羽凡");
// 创建一个List集合,限制元素类型为String
List<String> list2 = new ArrayList<>();
// 往集合中添加元素
list2.add("马蓉");
list2.add("李小璐");
list2.add("白百何");
// 创建一个List集合,限制元素类型为List集合 (List集合中的元素是List集合)
List<List<String>> list = new ArrayList<>();
list.add(list1);
list.add(list2);
// 遍历
for (List<String> e : list) {
for (String name : e) {
System.out.println(name);
}
System.out.println("=============");
}
System.out.println(list);
}
}
- List嵌套Map
-public class Test2 {
public static void main(String[] args) {
/*
List嵌套Map:
*/
// 创建Map集合对象
Map<String,String> map1 = new HashMap<>();
map1.put("it001","迪丽热巴");
map1.put("it002","古力娜扎");
// 创建Map集合对象
Map<String,String> map2 = new HashMap<>();
map2.put("heima001","蔡徐坤");
map2.put("heima002","李易峰");
// 创建List集合,用来存储以上2个map集合
List<Map<String,String>> list = new ArrayList<>();
list.add(map1);
list.add(map2);
System.out.println(list.size()); // 2
for (Map<String, String> map : list) {
// 遍历获取出来的map集合对象
Set<String> keys = map.keySet();// 获取map集合所有的键
// 根据键找值
for (String key : keys) {
System.out.println(key + ","+ map.get(key));
}
}
}
}
- Map嵌套Map
public class Test3 {
public static void main(String[] args) {
/*
Map嵌套Map:
*/
// 创建Map集合对象
Map<String,String> map1 = new HashMap<>();
map1.put("it001","迪丽热巴");
map1.put("it002","古力娜扎");
// 创建Map集合对象
Map<String,String> map2 = new HashMap<>();
map2.put("heima001","蔡徐坤");
map2.put("heima002","李易峰");
// 创建Map集合,把以上2个Map集合作为值存储到这个map集合中
Map<String, Map<String, String>> map = new HashMap<>();
map.put("传智博客",map1);
map.put("黑马程序员",map2);
System.out.println(map.size());// 2
// 获取map集合中的所有键
Set<String> keys = map.keySet();
// 遍历所有的键
for (String key : keys) {
// 根据键找值
Map<String, String> value = map.get(key);
// 遍历value这个Map集合
Set<String> keySet = value.keySet();
for (String k : keySet) {
String v = value.get(k);
System.out.println(k+","+v);
}
}
}
}
集合的应用场景:
1.如果存取单个单个元素存,存取元素可重复,选List集合(且查询元素多,选List的子集合ArrayList集合)
2.如果存取单个单个元素存,存取元素可重复,选List集合(且查询元素少,增删多,选List的子集合LinkedList集合)
3.如果存取单个单个元素存,存取元素唯一,选Set集合,有序排列,选LinkedHashSet或TreeSet集合。
4.如果存取单个单个元素存,存取元素唯一,选Set集合,无序排列,选HashSet集合。
5.如果以键值对存入,选Map集合,元素存取无序,选HashMap.
6.如果以键值对存入,选Map集合,元素存取有序,选LinkedHashMap或TreeMap集合.
Collections类
java.utils.Collections``是集合工具类,用来对集合进行操作.
常用方法
- `public static void shuffle(List<?> list) `:打乱集合顺序。
- `public static <T> void sort(List<T> list)`:将集合中元素按照默认规则排序。
- `public static <T> void sort(List<T> list,Comparator<? super T> com )`:将集合中元素按照指定规则排序。
代码演示:
/**
* public static void shuffle(List<?> list):打乱集合中元素的顺序。
*/
private static void method01() {
// 创建一个List集合对象,限制集合中元素类型为Integer
List<Integer> list = new ArrayList<>();
// 往集合中添加一些元素
list.add(300);
list.add(100);
list.add(200);
list.add(500);
list.add(400);
System.out.println("打乱顺序之前:"+list);// 打乱顺序之前:[300, 100, 200, 500, 400]
// 随机打乱集合中元素的顺序:public static void shuffle(List<?> list)
Collections.shuffle(list);
System.out.println("打乱顺序之后:"+list);
}
/**
* public static <T> void sort(List<T> list):将集合中元素按照默认规则排序。
* 集合中的元素为系统类的对象
*/
private static void method02() {
// 创建一个List集合对象,限制集合中元素类型为Integer
List<Integer> list = new ArrayList<>();
// 往集合中添加一些元素
list.add(300);
list.add(100);
list.add(200);
list.add(500);
list.add(400);
System.out.println("排序之前的集合:"+list);// 打乱顺序之前:[300, 100, 200, 500, 400]
// 将集合中元素按照默认规则排序: public static <T> void sort(List<T> list)
Collections.sort(list);
System.out.println("排序之后的集合:"+list);// 排序之后的集合:[100, 200, 300, 400, 500]
}
Comparator比较器
public static void main(String[] args) {
/*
Collections常用功能:
- public static void shuffle(List<?> list):打乱集合中元素的顺序。
- public static <T> void sort(List<T> list):将集合中元素按照默认规则排序。
默认规则: 事先写好的规则
对集合中的元素按照默认规则排序,要求该集合元素所属的类实现Comparable接口,重写compareTo()方法
然后在compareTo()方法中指定排序的默认规则
- public static <T> void sort(List<T> list,Comparator<? super T> ):将集合中元素按照指定规则排序。
指定规则: 自己定义的规则
参数Comparator<T>接口:也称比较器接口,用来指定排序的规则
*/
// 创建一个List集合对象,限制集合中元素类型为Integer
List<Integer> list = new ArrayList<>();
// 往集合中添加一些元素
list.add(300);
list.add(100);
list.add(200);
list.add(500);
list.add(400);
System.out.println("排序之前的集合:"+list);// 打乱顺序之前:[300, 100, 200, 500, 400]
// 300 100 200 500 400
// 300
// 对list集合指定规则排序: 降序
Collections.sort(list, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
// 指定排序规则
// 前减后:升序
// 后减前:降序
// 前:第一个参数 o1
// 后:第二个参数 o2
return o2 - o1;
}
});
System.out.println("排序之后的集合:"+list);// 排序之后的集合:[500, 400, 300, 200, 100]
// 对list集合指定规则排序: 升序
Collections.sort(list, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
// 指定排序规则
// 前减后:升序
// 后减前:降序
// 前:第一个参数 o1
// 后:第二个参数 o2
return o1 - o2;
}
});
System.out.println("排序之后的集合:"+list);// 排序之后的集合:[100, 200, 300, 400, 500]
}
可变参数
定义一个方法需要接受多个参数,并且多个参数类型一致
格式:
修饰符 返回值类型 方法名(参数类型... 形参名){ }
代码演示:
public class Demo {
public static void main(String[] args) {
// 可变参数的语法
/*int[] arr = {10, 20, 30, 40, 50, 60};
// 调用method1方法
method1(10, 20, 30, 40, 50);
// 调用method2方法
method2(arr);
method2(10, 20, 30, 40, 50, 60);
//
method3(arr);
method3(10, 20, 30, 40, 50, 60);
method4(10,"jack","rose");*/
}
public static void method4(int num,String... str){
}
// 定义一个方法,可以接收5个int类型的参数
public static void method3(int[] arr) {
for (int i : arr) {
System.out.println(i);
}
System.out.println(arr[0]);
}
// 定义一个方法,可以接收5个int类型的参数
public static void method2(int... num) {
for (int i : num) {
System.out.println(i);
}
System.out.println(num[0]);
}
// 定义一个方法,可以接收5个int类型的参数
public static void method1(int num1, int num2, int num3, int num4, int num5) {
}
}
注意事项:
1.一个方法只能有一个可变参数
2.如果方法中有多个参数,可变参数要放到最后。
应用场景: Collections
在Collections中也提供了添加一些元素方法:
public static <T> boolean addAll(Collection<T> c, T... elements)
:往集合中添加一些元素。
代码演示:
public class CollectionsDemo {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<Integer>();
//原来写法
//list.add(12);
//list.add(14);
//list.add(15);
//list.add(1000);
//采用工具类 完成 往集合中添加元素
Collections.addAll(list, 5, 222, 1,2);
System.out.println(list);
}