一、Collections工具类
一、解释
java.utils.Collections
是集合工具类,用来对集合进行操作。注意和Collection集合区分。集合和类的区分。
类是数据类型,集合是保存数据的,数据有数据类型。
二、常用方法
1.打乱集合顺序
//public static void shuffle(List<?> list) :打乱集合顺序。
// 创建List集合,限制集合中元素的类型为Integer类型
List<Integer> list = new ArrayList<>();
// 往集合中添加元素
//这边自动装箱,int变成integer
list.add(300);
list.add(100);
list.add(200);
list.add(500);
list.add(400);
System.out.println("打乱顺序之前的集合:"+list);// [300, 100, 200, 500, 400]
// 打乱顺序
Collections.shuffle(list); // 随机打乱顺序
System.out.println("打乱顺序之后的集合:"+list);// [500, 300, 100, 200, 400]
2.按照默认规则排序
默认规则是从小到大,是升序。这是事先写好的规则,需要排序的集合元素所属的类需要实现重写Comparable接口,重写compareTo方法,在compareTo方法指定排序。
//public static <T> void sort(List<T> list)`:将集合中元素按照默认规则排序。
// 创建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]
// 将集合中元素按照默认规则排序
Collections.sort(list);
System.out.println("排序之后的集合:"+list); // [100, 200, 300, 400, 500]
模拟重写compareTo方法
public class Student implements Comparable<Student>{
int age;
public Student(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"age=" + age +
'}';
}
//重写conpareTo方法
@Override
public int compareTo(Student o) {
// 指定排序规则
// 前减后 升序
// 后减前 降序
// 前:this 后: 参数o
//按什么排序,就以什么计算
//这里是年龄来计算
return this.age - o.age;// 升序
}
}
// 创建List集合,限制集合中元素的类型为Student类型
List<Student> list1 = new ArrayList<>();
// 往集合中添加元素
Student stu1 = new Student(19);
Student stu2 = new Student(18);
Student stu3 = new Student(20);
Student stu4 = new Student(17);
list1.add(stu1);
list1.add(stu2);
list1.add(stu3);
list1.add(stu4);
System.out.println("排序之前的集合:"+list1);
// 将集合中元素按照默认规则排序
Collections.sort(list1);
System.out.println("排序之后的集合:"+list1);
3.按指定规则排序
这样可以在使用的时候再确定按什么排序。上面的排序写在类中就写死了。
//public static <T> void sort(List<T> list,Comparator<? super T> ):将集合中元素按照指定规则排序。
//Comparator是一个接口,不能创建对象,所以用匿名内部类来实现比较的方法
//参数是接口或类时,就可以想到匿名内部类,尤其是接口不能创建对象,只能用匿名内部类
// 创建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]
// 将集合中元素按照指定规则排序---->降序
//new Comparator<Integer>(){}是匿名内部类
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]
// 将集合中元素按照指定规则排序---->升序
Collections.sort(list, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1 - o2;
}
});
System.out.println("排序之后的集合:" + list);// [100, 200, 300, 400, 500]
System.out.println("=======================================");
// 创建List集合,限制集合中元素的类型为Student类型
List<Student> list1 = new ArrayList<>();
// 往集合中添加元素
Student stu1 = new Student(19);
Student stu2 = new Student(18);
Student stu3 = new Student(20);
Student stu4 = new Student(17);
list1.add(stu1);
list1.add(stu2);
list1.add(stu3);
list1.add(stu4);
System.out.println("排序之前的集合:" + list1);
// 将集合中元素按照指定规则排序-->按照年龄降序排序
Collections.sort(list1, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
// 指定排序规则
// 前减后 升序
// 后减前 降序
// 前: 第一个参数o1 后:第二个参数o2
return o2.age - o1.age;
}
});
System.out.println("排序之后的集合:" + list1);//是降序
// 将集合中元素按照指定规则排序-->按照年龄升序排序
Collections.sort(list1, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
// 指定排序规则
// 前减后 升序
// 后减前 降序
// 前: 第一个参数o1 后:第二个参数o2
return o1.age - o2.age;
}
});
System.out.println("排序之后的集合:" + list1);//是升序
}
}
4.批量添加元素
//public static <T> boolean addAll(Collection<T> c, T... elements) `:往集合中添加一些元素。
// 创建ArrayList集合,限制集合元素的类型为String类型
ArrayList<String> list = new ArrayList<>();
// 往list集合中添加批量元素
Collections.addAll(list,"2","A","K","Q","J","10","9","8","7","6","5","4","3");
System.out.println(list)
二、可变参数
一、解释
在JDK1.5之后,如果我们定义一个方法需要接受多个参数,并且多个参数类型一致,我们可以对其简化
二、写法
//修饰符 返回值类型 方法名(参数类型... 形参名){ }
// 定义一个方法,可以接收5个int类型的数
public static void method1(int num1,int num2,int num3,int num4,int num5){// 接收5个具体的数
}
// 定义一个方法,可以接收5个int类型的数
public static void method2(int[] arr){// 接收数组
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
// 定义一个方法,可以接收5个int类型的数
public static void method3(int... nums){
// 使用:把nums可变参数当成数组使用
for (int i = 0; i < nums.length; i++) {
System.out.println(nums[i]);
}
}
method3(10,20,30,40,50);
int[] arr = {10,20,30,40,50};
method3(arr);
//两种格式都能使用。进来后都会变成数组。
三、注意事项
- 1.一个方法只能有一个可变参数
- 2.如果方法中有多个参数,可变参数要放到最后。
三、set接口
一、解释
Set接口:也称Set集合,但凡是实现了Set接口的类都叫做Set集合
特点: 元素无索引,元素不可重复(唯一)
- HashSet集合: 实现类–元素存取无序
- LinkedHashSet集合:实现类–元素存取有序
- TreeSet集合:实现类–> 对元素进行排序
- 注意:
1.Set集合没有特殊的方法,都是使用Collection接口的方法
2.Set集合没有索引,所以遍历元素的方式就只有: 增强for循环,或者迭代器
每个接口都可以有不同的实现类,来实现不同 的功能,创建不同的对象.
二、HashSet集合
一、解释
java.util.HashSet
是Set
接口的一个实现类,它所存储的元素是不可重复的,并且元素都是无序的(即存取顺序不能保证不一致)。
public class Test {
public static void main(String[] args) {
/*
HashSet集合: 元素存取无序,元素不可重复,元素无索引
*/
// 创建HashSet集合对象,限制集合元素的类型为String
HashSet<String> set = new HashSet<>();
// 往集合中添加元素
set.add("nba");
set.add("cba");
set.add("bac");
set.add("abc");
set.add("nba");
System.out.println(set);// [cba, abc, bac, nba],顺序和存储的顺序不一致
}
}
二、HashSet集合存储数据和保持数据唯一性原理
- HashSet集合存储数据的结构—哈希表结构
哈希表结构:
jdk8以前: 数组+链表
jdk8以后: 数组+链表+红黑树
链表元素个数没有超过8: 数组+链表
链表元素个数超过8: 数组+链表+红黑树 - HashSet集合保证元素唯一的原理–依赖Object类的两个方法,hashCode()和equals()方法
1.当存储元素的时候,就会调用该元素的hashCode()方法计算该元素的哈希值,哈希值模16,得到一个余数,得到的结果是1到15,在比较对应位置上有没有元素,没有就存进去,这就导致存和取的顺序不一样了。
2.判断该哈希值对应的位置上,是否有元素:
3.如果该哈希值对应的位置上,没有元素,就直接存储
4.如果该哈希值对应的位置上,有元素,说明产生了哈希冲突
5.产生了哈希冲突,就得调用该元素的equals方法,与该位置上的所有元素进行一一比较:
如果比较的时候,有任意一个元素与该元素相同,那么就不存储
如果比较完了,没有一个元素与该元素相同,那么就直接存储,要是这个链表的元素到了8个,就会变成红黑树。 - 补充:
Object类: hashCode()和equals()方法;
hashCode():Object类中的hashCode()方法是根据地址值计算哈希值
equals方法():Object类中的equals()方法是比较地址值
三、hashset存储自定义类型
重写hashcode方法和equals方法,建立自己的比较方式,才能保证HashSet集合中的对象唯一.,不然的话,对象属性值相同的值还是会存进去,开发中我们认为对象属性相同就是同一个对象。不管它的地址值
public class Person{
/**
* 姓名
*/
public String name;
/**
* 年龄
*/
public int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return age == person.age &&
Objects.equals(name, person.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
public class Demo {
public static void main(String[] args) {
// 创建多个Person对象
Person p1 = new Person("张三", 18);
Person p2 = new Person("李四", 38);
Person p3 = new Person("王五", 28);
Person p4 = new Person("张三", 18);
// 创建HashSet集合对象,限制集合中元素的类型为Person
HashSet<Person> set = new HashSet<>();
// 往集合中添加Person对象
set.add(p1);
set.add(p2);
set.add(p3);
set.add(p4);
// 遍历打印集合中的元素
for (Person p : set) {
System.out.println(p);
}
System.out.println(p1.hashCode());
System.out.println(p2.hashCode());
System.out.println(p3.hashCode());
System.out.println(p4.hashCode());
}
}
三、linkedHashSet集合
一、解释
HashSet保证元素唯一,可是元素存放进去是没有顺序的,要保证有序,可以使用LinkedHashSet,在HashSet下面有一个子类java.util.LinkedHashSet
,它是链表和哈希表组合的一个数据存储结构,由哈希表保证元素唯一,由链表保证元素存取有序
// 创建LinkedHashSet集合,限制集合中元素的类型为Integer类型
LinkedHashSet<Integer> set = new LinkedHashSet<>();// 存取有序
//HashSet<Integer> set = new HashSet<>();// 存取无序
// 往集合中存储数据
set.add(300);
set.add(100);
set.add(200);
set.add(500);
set.add(400);
set.add(400);
System.out.println(set);// [300, 100, 200, 500,400]
四、TreeSet集合
一、解释
TreeSet集合是Set接口的一个实现类,底层依赖于TreeMap,是一种基于红黑树的实现,其特点为:
- 元素唯一
- 元素没有索引
- 使用元素的自然顺序对元素进行排序,或者根据创建 TreeSet 时提供的
Comparator
比较器
进行排序,具体取决于使用的构造方法
public class Test {
public static void main(String[] args) {
/*
TreeSet集合: 元素无索引,元素唯一,对元素进行排序
通过构造方法实现排序:
public TreeSet():根据其元素的自然排序进行排序
默认规则排序:集合元素所属的类需要实现Comparable接口,重写compareTo方法,在compareTo方法中指定默认排序规则
public TreeSet(Comparator<E> comparator): 根据指定的比较器进行排序
指定规则排序: 通过传入Comparator接口的实现类对象,在实现类对象中重写compare方法,在compare方法中指定排序规则
*/
// 按照默认规则排序---->默认升序
// 创建TreeSet集合,限制集合中元素的类型为Integer类型
TreeSet<Integer> set = new TreeSet<>();
// 往集合中存储数据
set.add(300);
set.add(100);
set.add(200);
set.add(500);
set.add(400);
set.add(400);
System.out.println(set);// [100, 200, 300, 400, 500]
System.out.println("===========================================");
// 按照指定规则排序---->降序
// 创建TreeSet集合,限制集合中元素的类型为Integer类型
TreeSet<Integer> set1 = new TreeSet<>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
/*
指定排序规则:
前减后 升序
后减前 降序
前:第一个参数 后:第二个参数
*/
return o2 - o1;
}
});
// 往集合中存储数据
set1.add(300);
set1.add(100);
set1.add(200);
set1.add(500);
set1.add(400);
set1.add(400);
System.out.println(set1);// [500, 400, 300, 200, 100]
System.out.println("===========================================");
// 按照指定规则排序---->升序
// 创建TreeSet集合,限制集合中元素的类型为Integer类型
TreeSet<Integer> set2 = new TreeSet<>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
/*
指定排序规则:
前减后 升序
后减前 降序
前:第一个参数 后:第二个参数
*/
return o1 - o2;
}
});
// 往集合中存储数据
set2.add(300);
set2.add(100);
set2.add(200);
set2.add(500);
set2.add(400);
set2.add(400);
System.out.println(set2);// [100, 200, 300, 400, 500]
}
}
四、Map集合
一、解释
Map集合是双列集合的顶层,它里面的方法所有双列集合都能使用,collection是单列集合,存储元素是单个单个存储的,双列集合是一对一对存储的。Collection是单列集合,相当于js数组,双列相当于js里的对象。有键名和键值对。
二、Map集合特点
Map<K,V>集合的特点: K用来限制键的类型,V用来限制值的类型
1.Map集合存储元素是以键值对的形式存储,每一个键值对都有键和值
2.Map集合的键是唯一,值可以重复,如果键重复了,那么值就会被覆盖
3.根据键取值,HashSet<E>:存储数据采用的是哈希表结构,保证元素唯一,重写元素所属的类hashCode和eauals方法。
三、Map集合子类
-
HashMap<K,V>:存储数据采用的哈希表结构,元素的存取顺序不能保证一致。
由于要保证键的唯一、不重复,需要重写键的hashCode()方法、equals()方法。-
LinkedHashMap<K,V>:HashMap下有个子类LinkedHashMap,存储数据采用的哈希表结构+链表结构。
通过链表结构可以保证键值对的存取顺序一致;
通过哈希表结构可以保证的键的唯一、不重复,需要重写键的hashCode()方法、equals()方法。 -
TreeMap<K,V>:TreeMap集合和Map相比没有特有的功能,底层的数据结构是红黑树;
可以对元素的键进行排序,排序方式有两种:自然排序和比较器排序
-
四、Map集合的常用方法
1.把指定的键与指定的值添加到Map集合中
这个方法也可以做修改方法,因为重复的键,后面的会覆盖前面的
//public V put(K key, V value): 把指定的键与指定的值添加到Map集合中。
// 创建Map集合,限制键的类型为String,值的类型为String
//接口不能创建对象,所以用hashMap这个实现类来创建对象
Map<String, String> map = new HashMap<>();
// 往map集合中添加键值对
map.put("黄晓明", "杨颖");
map.put("文章", "马伊琍");
map.put("谢霆锋", "王菲");
System.out.println(map);// {文章=马伊琍, 谢霆锋=王菲, 黄晓明=杨颖}
// Map集合键唯一,如果键重复了,值会覆盖
String v1 = map.put("文章", "姚笛");
System.out.println("v1:"+v1);// 马伊琍
System.out.println(map);// {文章=姚笛, 谢霆锋=王菲, 黄晓明=杨颖}
// Map集合值可以重复
String v2 = map.put("李亚鹏", "王菲");
System.out.println("v2:"+v2);// null
System.out.println(map);// {文章=姚笛, 谢霆锋=王菲, 李亚鹏=王菲, 黄晓明=杨颖}
//使用put方法时,若指定的键(key)在集合中没有,则没有这个键对应的值,返回null,并把指定的键值添加到集合中;
//若指定的键(key)在集合中存在,则返回值为集合中键对应的值(该值为替换前的值),并把指定键所对应的值,替换成指定的新值
2.把指定的键 所对应的键值对元素 在Map集合中删除,返回被删除元素的值。
//public V remove(Object key): 把指定的键 所对应的键值对元素 在Map集合中删除,返回被删除元素的值。
// 删除文章这个键对应的键值对
String v3 = map.remove("文章");
System.out.println("被删除键值对的值:"+v3);// 姚笛
System.out.println(map);// {谢霆锋=王菲, 李亚鹏=王菲, 黄晓明=杨颖}
3.根据指定的键,在Map集合中获取对应的值
// 获取黄晓明这个键对应的值
String value = map.get("黄晓明");
System.out.println("value:"+value);// 杨颖
4.判断该集合中是否有此键或此值
containsKey和containsValue
//public boolean containsKey(Object key):判断该集合中是否有此键
// 判断是否包含指定的键
System.out.println(map.containsKey("黄晓明"));// true
System.out.println(map.containsKey("文章"));// false
// 判断是否包含指定的值
System.out.println(map.containsValue("杨颖"));// true
System.out.println(map.containsValue("马伊琍"));// false
5.获取Map集合中所有的键,存储到Set集合中。
//public Set<K> keySet(): 获取Map集合中所有的键,存储到Set集合中。
// 获取所有的键
Set<String> keys = map.keySet();
System.out.println("keys:"+keys);// [谢霆锋, 李亚鹏, 黄晓明]
6.获取Map集合中所有的值,存储到Collection集合中。
//public Collection<V> values(): 获取Map集合中所有的值,存储到Collection集合中。
// 获取所有的值
Collection<String> values = map.values();
System.out.println("values:"+values);// [王菲, 王菲, 杨颖]
7.获取到Map集合中所有的键值对对象的集合(Set集合)。
//public Set<Map.Entry<K,V>> entrySet(): 获取到Map集合中所有的键值对对象的集合(Set集合)。
//Entry是Map的内部类,表示set里是Entry类型的对象
//Map.Entry<K,V>:表示键值对对象---把键值对包装成一个对象,该对象的类型就是Entry类型
// 获取Map集合中所有键值对对象
Set<Map.Entry<String, String>> set = map.entrySet();
System.out.println(set);// [谢霆锋=王菲, 李亚鹏=王菲, 黄晓明=杨颖]
五、Map集合的遍历
1.根据键找值
- 获取Map中所有的键,由于键是唯一的,所以返回一个Set集合存储所有的键。方法提示:
keyset()
- 遍历键的Set集合,得到每一个键。
- 根据键,获取键所对应的值。方法提示:
get(K key)
public class Demo {
public static void main(String[] args) {
// 创建Map集合对象,限制键的类型为String,值的类型为String
Map<String, String> map = new HashMap<>();
// 往map集合中添加键值对
map.put("黄晓明", "杨颖");
map.put("文章", "马伊琍");
map.put("谢霆锋", "王菲");
// 遍历map集合
// 获取集合中所有的键 Set<K> keySet()方法
Set<String> keys = map.keySet();
// 遍历所有的键的集合
for (String key : keys) {
// 在循环中,根据键找值 V get(K key)方法
String value = map.get(key);
System.out.println("键:"+key+",值:"+value);
}
}
}
2.键值对方式
Entry<K,V>接口:简称Entry项,表示键值对对象,用来封装Map集合中的键值对
Entry<K,V>接口:是Map接口中的内部接口,在外部使用的时候是这样表示: Map.Entry<K,V>
Map集合中提供了一个方法来获取所有键值对对象:
public Set<Map.Entry<K,V>> entrySet()
根据键值对对对象获取键和值:
- public K getKey():获取Entry对象中的键。
- public V getValue():获取Entry对象中的值。
Map遍历方式二:根据键值对对象的方式
1.获取集合中所有键值对对象,以Set集合形式返回。 Set<Map.Entry<K,V>> entrySet()
2.遍历所有键值对对象的集合,得到每一个键值对(Entry)对象。
3.在循环中,可以使用键值对对对象获取键和值 getKey()和getValue()
public class Demo {
public static void main(String[] args) {
// 创建Map集合对象,限制键的类型为String,值的类型为String
Map<String, String> map = new HashMap<>();
// 往map集合中添加键值对
map.put("黄晓明", "杨颖");
map.put("文章", "马伊琍");
map.put("谢霆锋", "王菲");
// 获取集合中所有键值对对象 Set<Map.Entry<K,V>> entrySet()
Set<Map.Entry<String, String>> entrySet = map.entrySet();
// 遍历所有键值对对象的集合
for (Map.Entry<String, String> entry : entrySet) {
// 在循环中,可以使用键值对对对象获取键和值 getKey()和getValue()
String key = entry.getKey();
String value = entry.getValue();
System.out.println("键:"+key+",值:"+value);
}
}
}
六、HashMap存储自定义类型
public class Student {
/**
* 姓名
*/
public String name;
/**
* 年龄
*/
public int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age &&
Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
public class Demo {
public static void main(String[] args) {
// 创建Map集合,指定键的类型为Student,值的类型为String
HashMap<Student,String> map = new HashMap<>();
// 创建多个学生对象
Student stu1 = new Student("张三", 18);
Student stu2 = new Student("李四", 38);
Student stu3 = new Student("王五", 28);
Student stu4 = new Student("张三", 18);
// 把学生对象作为键,家庭地址作为值,存储到map集合中
map.put(stu1,"北京");
map.put(stu2,"上海");
map.put(stu3,"深圳");
map.put(stu4,"广州");
// 打印map集合
System.out.println(map);
System.out.println(map.size());// 3
}
}
- 当给HashMap中存放自定义对象时,如果自定义对象作为key存在,这时要保证对象唯一,必须复写对象的hashCode和equals方法(如果忘记,请回顾HashSet存放自定义对象)。
- 如果要保证map中存放的key和取出的顺序一致,可以使用
java.util.LinkedHashMap
集合来存放。
7.LinkedHashMap集合
HashMap保证成对元素唯一,并且查询速度很快,可是成对元素存放进去是没有顺序的,那么我们要保证有序,就要使用LinkedHashMap集合
- 通过链表结构可以保证元素的存取顺序一致;
- 通过哈希表结构可以保证的键的唯一、不重复,需要重写键的hashCode()方法、equals()方法。
public class Test {
public static void main(String[] args) {
/*
LinkedHashMap: 元素存取有序,键唯一,值可重复
- 通过链表结构可以保证元素的存取顺序一致;
- 通过哈希表结构可以保证的键的唯一、不重复,需要重写键的hashCode()方法、equals()方法。
*/
// 创建LinkedHashMap集合,限制键的类型为Integer,值的类型为String
LinkedHashMap<Integer, String> map = new LinkedHashMap<>();
// 往map集合中添加键值对
map.put(300, "深圳");
map.put(100, "北京");
map.put(200, "广州");
map.put(500, "上海");
map.put(400, "武汉");
map.put(400, "深圳");
System.out.println(map);
}
}
8.TreeMap集合
TreeMap集合和Map相比没有特有的功能,底层的数据结构是红黑树;可以对元素的键进行排序,排序方式有两种:自然排序和比较器排序;到时使用的是哪种排序,取决于我们在创建对象的时候所使用的构造方法;
构造方法
public TreeMap() 使用自然排序
public TreeMap(Comparator<? super K> comparator) 通过比较器指定规则排序
public class Test {
public static void main(String[] args) {
/*
TreeMap集合: 键唯一,值可以重复,如果键重复了,值就覆盖,可以根据键对键值对进行排序
public TreeMap() 根据键按照默认规则进行排序
public TreeMap(Comparator<? super K> comparator) 通过比较器指定规则排序
*/
// 按照键的默认规则排序: ---->升序
// 创建TreeMap集合,限制键的类型为Integer,值的类型为String
TreeMap<Integer, String> map = new TreeMap<>();
// 往map集合中添加键值对
map.put(300, "深圳");
map.put(100, "北京");
map.put(200, "广州");
map.put(500, "上海");
map.put(400, "武汉");
map.put(400, "深圳");
System.out.println(map);
System.out.println("+=================================");
// 按照指定规则排序: ---->降序
// 创建TreeMap集合,限制键的类型为Integer,值的类型为String
TreeMap<Integer, String> map1 = new TreeMap<>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
/*
前减后: 升序
后减前: 降序
前:第一个参数 后:第二个参数
*/
return o2 - o1;
}
});
// 往map集合中添加键值对
map1.put(300, "深圳");
map1.put(100, "北京");
map1.put(200, "广州");
map1.put(500, "上海");
map1.put(400, "武汉");
map1.put(400, "深圳");
System.out.println(map1);
}
}
五、Map集合例子
public class Test {
public static void main(String[] args) {
/*
Map集合练习:输入一个字符串,统计该字符串中每个字符出现次数。
*/
// 0.输入一个字符串
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个字符串:");
String s = sc.nextLine();
// 1.创建Map集合,键的类型为Character,值的类型为Integer
HashMap<Character, Integer> map = new HashMap<>();
// 2.循环遍历字符串
for (int i = 0; i < s.length(); i++) {
// 3.在循环中获取遍历出来的字符
char c = s.charAt(i);
// 4.判断集合中是否存在该字符的键
if (map.containsKey(c)) {
// 6.如果集合中已存在该字符的键,那么就取出该字符键对应的值,然后自增1,作为新的值,重新存储到Map集合中
Integer value = map.get(c);
value++;
map.put(c, value);
} else {
// 5.如果集合中不存在该字符的键,那么就该字符作为键,值为1,存储到Map集合中
map.put(c, 1);
}
}
// 7.循环结束,打印map集合
System.out.println(map);
}
}
六、集合嵌套
一、解释
任何集合内部都可以存储其它任何集合
二、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);
}
}
}
}