前言
提示:这里介绍的是Collections、Set、Map和集合的嵌套的基础知识点
提示:以下是本篇文章正文内容,下面案例可供参考
一、Collections类
1、概述:
java.util.Collections是集合工具类,用来对集合进行操作。
2、常用方法:
public static void shuffle(List<?> list) :打乱集合顺序。
public class Test1_shuffle {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(500);
list.add(200);
list.add(400);
list.add(100);
list.add(300);
System.out.println("打乱顺序之前的集合:"+list);
Collections.shuffle(list);
System.out.println("打乱顺序之后的集合:"+list);
}
}
public static <T> void sort(List<T> list):将集合中元素按照默认规则排序。
- 默认规则: 事先写好的规则
- 默认规则是在哪里指定的?
- 默认规则如何指定?
- 要求集合元素所属的类必须实现Comparable接口,重写compareTo方法,在compareTo方法中书写默认排序规则
public class Test2_sort默认规则排序 {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(500);
list.add(200);
list.add(400);
list.add(100);
list.add(300);
System.out.println("排序之前的集合:"+list);
Collections.sort(list);
System.out.println("排序之后的集合:"+list);
}
}
public class Student implements Comparable<Student>{
String name;
int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public int compareTo(Student o) {
return o.age - this.age;
}
}
public static void main(String[] args) {
List<Student> list = new ArrayList<>();
list.add(new Student("张三1",18));
list.add(new Student("张三2",38));
list.add(new Student("张三3",28));
list.add(new Student("张三4",48));
list.add(new Student("张三5",58));
System.out.println("排序之前的集合:"+list);
Collections.sort(list);
System.out.println("排序之后的集合:"+list);
}
}
public <T> void sort(List<T> list,Comparator<? super T> comp):将集合中元素按照指定规则排序
案例1:
public class Test4_sort指定规则排序 {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(500);
list.add(200);
list.add(400);
list.add(100);
list.add(300);
System.out.println("排序之前的集合:"+list);
Collections.sort(list, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1 - o2;
}
});
System.out.println("排序之后的集合:"+list);
Collections.sort(list, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
});
System.out.println("排序之后的集合:"+list);
}
}
public class Test5_sort指定规则排序 {
public static void main(String[] args) {
List<Student> list = new ArrayList<>();
list.add(new Student("张三1",18));
list.add(new Student("张三2",38));
list.add(new Student("张三3",28));
list.add(new Student("张三4",48));
list.add(new Student("张三5",58));
System.out.println("排序之前的集合:"+list);
Collections.sort(list, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o1.age - o2.age;
}
});
System.out.println("排序之后的集合:"+list);
Collections.sort(list, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o2.age - o1.age;
}
});
System.out.println("排序之后的集合:"+list);
}
}
3、可变参数
3.1、概述:
在JDK1.5之后,定义了可变参数,用来表示一个方法需要接受的多个同类型参数。
3.2、格式:
修饰符 返回值类型 方法名(数据类型... 变量名){
}
案例:
public class Test {
public static void main(String[] args) {
method1();
System.out.println("--------");
method1(10);
System.out.println("--------");
method1(10,20);
System.out.println("--------");
method1(10,20,30);
System.out.println("--------");
method1(10,20,30,40);
System.out.println("--------");
int[] arr = {10,20,30,40,50};
method1(arr);
}
public static void method1(int... nums){
for (int i = 0; i < nums.length; i++) {
System.out.println(nums[i]);
}
}
}
3.3、注意事项:
注意事项:
- 可变参数一定是定义在方法的形参位置
- 一个方法只能有一个可变参数
- 如果方法中有多个参数,可变参数要放到最后。
public class Test_注意事项 {
public static void main(String[] args) {
method2("itheima",10,20,30);
}
public static void method2(String str,int... nums){
}
}
3.4、应用场景
Collections工具类中的批量添加元素的静态方法: static <T> boolean addAll(Collection<T> c, T... elements) :往集合中添加一些元素。
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "2", "A", "K", "Q", "J", "10", "9", "8", "7", "6", "5", "4", "3");
System.out.println("list:" + list);
}
二、Set接口
1、 Set接口介绍
概述:
java.util.Set接口继承自Collection接口,是单列集合的一个重要分支。
特点:
元素没有索引,元素唯一(不重复)
注意事项:
- Set集合元素没有索引,只能使用迭代器或者增强for循环进行遍历元素
- Set集合没有特殊的方法,都是使用Collection的方法
- Set接口就是Set集合,但凡实现了Set接口的类也叫做Set集合
常用实现类:
- HashSet类: 元素没有索引,元素唯一,元素存取顺序不一致
- 存储结构采用的是哈希表结构,由哈希表保证元素唯一
- LinkedHashSet类:元素没有索引,元素唯一,元素存取顺序一致
- 存储结构采用的是哈希表+链表结构,由哈希表保证元素唯一,由链表保证元素存取顺序一致
- TreeSet类: 元素没有索引,元素唯一,可以对元素进行排序
- 存储结构采用的是红黑树结构,由红黑树保证元素唯一,由比较器来对元素进行排序
2、 HashSet集合
- 概述:
java.util.HashSet是Set接口的一个实现类, 底层的实现其实是一个java.util.HashMap支持
特点:
元素没有索引,元素唯一,元素存取顺序不一致
案例:
public class Test {
public static void main(String[] args) {
HashSet<String> set = new HashSet<>();
set.add("nba");
set.add("bac");
set.add("cba");
set.add("abc");
set.add("nba");
System.out.println("set:"+set);
}
}
HashSet集合存储数据的结构(哈希表)
在**JDK1.8**之前,哈希表底层采用数组+链表实现,即使用数组处理冲突,同一hash值的链表都存储在一个数组里。但是当位于一个桶中的元素较多,即hash值相等的元素较多时,通过key值依次查找的效率较低。而JDK1.8中,哈希表存储采用数组+链表+红黑树实现,当链表长度超过阈值(8)时,将链表转换为红黑树,这样大大减少了查找时间。
简单的来说,哈希表是由数组+链表+红黑树(JDK1.8增加了红黑树部分)实现的,如下图所示。 HashSet保证元素唯一原理:
保证元素唯一的原理: 依靠hashCode和equals方法 1.存储元素的时候,会调用该元素的hashCode方法计算该元素的哈希值 2.判断该哈希值对应的位置上是否有元素 3.如果该哈希值对应的位置上没有元素,就直接存储 4.如果该哈希值对应的位置上有元素,说明产生了哈希冲突 5.产生了哈希冲突就会调用该元素的equals方法与该哈希值对应的位置上的所有元素进行一一比较: 5.1 如果比较完之后,没有一个元素与该元素相等,就直接存储 5.2 如果比较完之后,有任意一个元素与该元素相等,就不存储
注意: 1.hashCode和equals方法属于Object类的 2.任意类的对象都拥有hashCode和equals方法 3.Object类中的hashCode方法是主要根据地址值计算哈希值 4.Object类中的equals方法是比较地址值
HashSet存储自定义类型元素
需求: 使用HashSet集合存储学生对象
结论: HashSet存储自定义类型元素,要求该元素所属的类要重写hashCode和equals方法
3、 LinkedHashSet
概述:
java.util.LinkedHashSet 是HashSet的一个子类,底层采用链表+哈希表
特点:
元素没有索引,元素唯一,元素存取顺序一致
存储结构采用的是哈希表+链表结构,由哈希表保证元素唯一,由链表保证元素存取顺序一致
如果集合中存储的是自定义类型的元素,那么就要求该元素所属的类要重写hashCode和
equals方法
案例:
public class Test {
public static void main(String[] args) {
LinkedHashSet<String> set = new LinkedHashSet<>();
set.add("nba");
set.add("cba");
set.add("bac");
set.add("abc");
set.add("nba");
System.out.println("set:" + set);
System.out.println("========");
LinkedHashSet<Student> set2 = new LinkedHashSet<>();
Student stu1 = new Student("张三",18);
Student stu2 = new Student("李四",28);
Student stu3 = new Student("王五",38);
Student stu4 = new Student("赵六",48);
Student stu5 = new Student("张三",18);
set2.add(stu1);
set2.add(stu2);
set2.add(stu3);
set2.add(stu4);
set2.add(stu5);
for (Student stu : set2) {
System.out.println(stu);
}
}
}
4、TreeSet集合
概述:
TreeSet集合是Set接口的一个实现类,底层依赖于TreeMap,是一种基于红黑树的实现
特点:
- 元素没有索引,元素唯一,可以对元素进行排序
- 存储结构采用的是红黑树结构,由红黑树保证元素唯一,由比较器来对元素进行排序
排序:
- 默认规则排序: `public TreeSet(); 创建TreeSet集合对象,该集合对象使用默认规则对元素进行排序`
- 默认规则是在元素所属的类中指定的
- **要求集合元素所属的类必须实现Comparable接口,重写compareTo方法,在compareTo方法中指定排序规则**
三、Map集合
1、Map概述
- 概述: java.util.Map双列集合的顶层接口,用来存储具备映射关系对象的集合接口定义
特点:
- Map<K,V>,K用来限制键的类型,V用来限制值的类型
- Map集合以键值对的形式来存储数据
- Map集合的键是唯一的,值可以重复,但键如果重复,值就会覆盖
- Map集合是根据键来找值
实现类:
实现类都有的特点: 键是唯一的,值可以重复,但键如果重复,值就会覆盖
HashMap: 键值对存取顺序不一致
底层哈希表结构,由哈希表保证键唯一
LinkedHashMap:键值对存取顺序一致
底层哈希表+链表结构,由哈希表保证键唯一,由链表保证存取顺序一致
TreeMap: 可以对键进行排序,从而实现键值对排序
底层红黑树结构,由红黑树保证键唯一,由比较器对象对元素进行排序
2、 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 boolean containsValue(Object value): 判断该集合中是否有此值public Set<K> keySet() : 获取Map集合中所有的键,存储到Set集合中。public Set<Map.Entry<K,V>> entrySet() : 获取到Map集合中所有的 键值对对象 的集合(Set集合)。
3、 Map的遍历
方式1:键找值方式
- 获取Map集合的所有键--->keySet()方法
- 循环遍历所有的键
- 根据键找值--->get(K k)方法
案例:
public class Test1_键找值的方式 {
public static void main(String[] args) {
Map<String, String> map = new HashMap<>();
map.put("黄晓明", "杨颖");
map.put("文章", "马伊琍");
map.put("谢霆锋", "王菲");
map.put("李亚鹏", "王菲");
Set<String> keys = map.keySet();
for (String key : keys) {
String value = map.get(key);
System.out.println("key:"+key+",value:"+value);
}
}
}
方式2:键值对对象方式
- 获取所有的键值对对象---->entrySet()方法
- 循环遍历所有的键值对对象
- 使用键值对对象获取键和值--->使用Entry接口的方法
- Entry<K,V>接口:
- Entry接口是Map接口的成员内部接口,使用的方式是Map.Entry<K,V>
- Entry表示键值对对象,也就是说Entry是用来封装键值对的
- Entry接口里面的常用方法:
- K getKey(); 获取键值对对象封装的键
- V getValue(); 获取键值对对象封装的值
- 案例:
public class Test2_键值对对象的方式 {
public static void main(String[] args) {
Map<String, String> map = new HashMap<>();
map.put("黄晓明", "杨颖");
map.put("文章", "马伊琍");
map.put("谢霆锋", "王菲");
map.put("李亚鹏", "王菲");
Set<Map.Entry<String, String>> set = map.entrySet();
for (Map.Entry<String, String> entry : set) {
String key = entry.getKey();
String value = entry.getValue();
System.out.println("key:"+key+",value:"+value);
}
}
}
4、 HashMap存储自定义类型
结论: 如果键是自定义类型的元素,要保证键唯一,那么该键所属的类需要重写hashCode和equals方法
5、LinkedHashMap
概述:
LinkedHashMap是HashMap子类,底层由链表和哈希表组合,由哈希表保证键唯一,由链表保证键值对存取顺序一致
- 结论: 如果键是自定义类型的元素,要保证键唯一,那么该键所属的类需要重写hashCode和equals方法
6、TreeMap集合
概述: TreeMap是Map实现类,底层由红黑树实现,可以对元素的键进行排序
构造方法:
public TreeMap();创建TreeMap集合对象,使用默认规则对键进行排序
public class Test1_默认规则排序 {
public static void main(String[] args) {
TreeMap<Integer, String> map = new TreeMap<>();
map.put(500, "深圳");
map.put(100, "北京");
map.put(400, "广州");
map.put(200, "上海");
map.put(300, "杭州");
Set<Integer> keys = map.keySet();
for (Integer key : keys) {
String value = map.get(key);
System.out.println(key + " = " + value);
}
}
}
public TreeMap(Comparator<? super K> comparator);创建TreeMap集合对象,使用指定规则对键进行排序
public class Test2_指定规则排序 {
public static void main(String[] args) {
TreeMap<Integer, String> map = new TreeMap<>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
});
map.put(500, "深圳");
map.put(100, "北京");
map.put(400, "广州");
map.put(200, "上海");
map.put(300, "杭州");
Set<Integer> keys = map.keySet();
for (Integer key : keys) {
String value = map.get(key);
System.out.println(key + " = " + value);
}
}
}
|