1、双列集合
1.1、双列集合的特点:
①、双列集合一次需要存入一对数据,分别为键和值
②、键不能重复,但是值可以重复
③、键和值是一一对应的,没一个键只能找到一个值
④、键 + 值 称为键值对(键值对对象),又称Entry对象。
2、Map接口
2.1、Map集合中常见的方法
对于put方法,如果再次添加相同键值的数据时,会覆盖之前的数据,并且返回被覆盖的数据,如下所示:
import java.util.HashMap;
import java.util.Map;
public class Test {
public static void main(String[] args) {
Map<Integer,String> m = new HashMap<>();
m.put(12,"酋长");
String result = m.put(12,"你好");
System.out.println(m);
System.out.println(result);
}
}
输出结果:
{12=你好} 酋长
3、Map的遍历方式
①、键找值
②、键值对
③、Lambda表达式
3.1、方式一
3.1.1、将所有的键值放在一个单列集合中
3.1.2、遍历单列集合依次获得每一个键,然后通过键获得value
public static void test02() {
Map<Integer, String> m = new HashMap<>();
m.put(1, "张三");
m.put(2, "李四");
m.put(3, "王五");
//获取键值
final Set<Integer> integers = m.keySet();
//遍历键值对
for (Integer integer : integers) {
//通过键值或得相应的value值
System.out.println(integer + " = " + m.get(integer));
}
}
3.2、方式二
3.2.1、通过一个方法获取所有的键值对,返回一个Set集合(将Entry对象放入Set里面,Entry里面又是一个泛型)(idea可以直接Ctrl + Alt + v自动生成左边)
3.2.2、通过遍历Set集合,再调用获取键值对的方法对Map集合进行遍历。
public static void test03() {
Map<Integer, String> m = new HashMap<>();
m.put(1, "张三");
m.put(2, "李四");
m.put(3, "王五");
//获取所有的键值对
final Set<Map.Entry<Integer, String>> entries = m.entrySet();
//遍历上面的Set集合,然后通过调用方法获取key和value
for (Map.Entry<Integer, String> entry : entries) {
final Integer key = entry.getKey();
final String value = entry.getValue();
System.out.println(key + " = " + value);
}
}
3.3、方式三
public static void test04() {
Map<Integer, String> m = new HashMap<>();
m.put(1, "张三");
m.put(2, "李四");
m.put(3, "王五");
m.forEach(new BiConsumer<Integer, String>() {
@Override
public void accept(Integer key, String value) {
System.out.println(key + " = " + value);
}
});
System.out.println("----------------------");
//写成Lambda表达式形式
m.forEach((Integer key, String value) -> {
System.out.println(key + " = " + value);
});
System.out.println("----------------------");
//继续简化Lambda表达式的写法
m.forEach((key, value) -> System.out.println(key + " = " + value));
}
4、HashMap
4.1、特点:特点都是由键决定的,无序、不重复、无索引。
4.2、需求:创建一个HashMap集合,键是学生对象(Student),值是籍贯,存储三个键值对对象,并遍历,要求:同姓名,同年龄的是同一个学生。
//定义学生类,一定要重写hashCode和equals方法
import java.util.Objects;
public class Student {
private String name;
private int 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 Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
/**
* 获取
* @return name
*/
public String getName() {
return name;
}
/**
* 设置
* @param name
*/
public void setName(String name) {
this.name = name;
}
/**
* 获取
* @return age
*/
public int getAge() {
return age;
}
/**
* 设置
* @param age
*/
public void setAge(int age) {
this.age = age;
}
public String toString() {
return "Student{name = " + name + ", age = " + age + "}";
}
}
//测试类
import java.util.HashMap;
public class Test {
public static void main(String[] args) {
test01();
}
public static void test01(){
Student stu1 = new Student("张三",14);
Student stu2 = new Student("王五",18);
Student stu3 = new Student("王二",21);
Student stu4 = new Student("张三",14);
HashMap<Student,String> map = new HashMap<>();
map.put(stu1,"四川叙永");
map.put(stu2,"四川叙永");
map.put(stu3,"四川叙永");
String result = map.put(stu4,"四川古蔺"); //会进行覆盖
map.forEach((key,value) -> System.out.println(key.toString() + " = " + value));
System.out.println(result);
}
}
输出结果:
Student{name = 王五, age = 18} = 四川叙永 Student{name = 张三, age = 14} = 四川古蔺 Student{name = 王二, age = 21} = 四川叙永 四川叙永
5、LinkedHashMap
由键决定:有序、不重复、无索引,底层原理依然是哈希表,只是每个键值对元素又额外的多了一个双向链表来记录存储时的顺序。
6、TreeMap
6.1、TreeMap和TreeSet底层原理一样,都是红黑树结构。
6.2、由键值对决定的:不重复、无索引、可排序(对键值进行排序)
题目1:现在我们有一个需求,键用整数id表示,值用字符串表示商品的名称,现在按照ID的升序排列(默认就是升序排列),按照ID的降序排列,代码如下所示:
import java.util.Comparator;
import java.util.TreeMap;
public class Test {
public static void main(String[] args) {
//在创建对象的时候就设置排序规则
TreeMap<Integer,String> tm = new TreeMap<>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return -Integer.compare(o1,o2);
}
});
//赋值
tm.put(12,"可乐");
tm.put(8,"农夫山泉");
tm.put(4,"冰红茶");
tm.put(15,"烧仙草");
tm.forEach((key,value) -> System.out.println(key + " = " + value));
}
}
输出结果:
15 = 烧仙草 12 = 可乐 8 = 农夫山泉 4 = 冰红茶
题目2:
提示:计数器思想,但是这里的计数器使用的是一个集合。解决办法如下所示:
import java.util.TreeMap;
public class Test {
public static void main(String[] args) {
String str = "aababcabcdabcde";
//创建集合对象 键表示字符,value值为字母出现的次数
TreeMap<Character,Integer> tm = new TreeMap<>();
//遍历字符串获得每一个字符
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if(tm.containsKey(c)){
int amount = tm.get(c); //获取value值
amount++; //自加1
tm.put(c,amount); //重新添加
}else { //没有就直接添加
tm.put(c,1);
}
}
//遍历集合
tm.forEach((key,value) -> System.out.print(key + "(" + value + ")"));
}
}
7、Collections(一个操作集合的工具类)
7.1、Collections的常见方法如下所示:
批量添加元素只能给单列集合添加!!
8、综合练习
8.1、班级里有N个学生,实现随机点名器
public class Test {
public static void main(String[] args) {
test01();
}
public static void test01() {
//创建集合
ArrayList<String> list = new ArrayList<>();
//添加信息
Collections.addAll(list, "张三", "李四", "王五", "赵六", "麻子");
//获取随机索引
Random r = new Random();
int index = r.nextInt(list.size());
System.out.println(list.get(index));
}
}
8.2、班级里有N个学生,要求70%的概率抽到男生,30%概率抽到女生。
提示:可以在一个集合中放入111111000,其中1表示男生,0表示女,那么打乱这个集合从中抽取,如果抽到的是1就是男生,0就是女生。
public static void test02() {
//创建集合对象
ArrayList<Integer> list = new ArrayList<>();
Collections.addAll(list, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0);
//打乱里面的数据
Collections.shuffle(list);
//获取里面的第一个元素就可以获得含概率的数字
System.out.println(list.get(0));
//通过数字判断是在男生的集合中抽取还是在女生的集合中抽取,判断好了之后再通过随机数在男女生的集合中进行抽取
}
8.3、
如下所示:
import java.util.*;
public class Test {
public static void main(String[] args) {
HashMap<String, ArrayList<String>> location = new HashMap<>();
ArrayList<String> city1 = new ArrayList<>();
Collections.addAll(city1, "南京市", "扬州市", "苏州市", "无锡市", "常州市");
ArrayList<String> city2 = new ArrayList<>();
Collections.addAll(city2, "武汉市", "孝感市", "十堰市", "宜昌市", "鄂州市");
ArrayList<String> city3 = new ArrayList<>();
Collections.addAll(city3, "石家庄市", "唐山市", "邢台市", "保定市", "张家口市");
//将市添加到Map集合里面
location.put("江苏省", city1);
location.put("湖北省", city2);
location.put("河北省", city3);
//遍历
final Set<Map.Entry<String, ArrayList<String>>> entries = location.entrySet();
for (Map.Entry<String, ArrayList<String>> entry : entries) {
final String key = entry.getKey();
final ArrayList<String> value = entry.getValue();
StringJoiner sj = new StringJoiner(",", "", "");
for (String s : value) {
sj.add(s);
}
System.out.println(key + " = " + sj);
}
System.out.println("-------------------------------");
location.forEach((key,value) -> {
StringJoiner sj = new StringJoiner(",", "", "");
for (String s : value) {
sj.add(s);
}
System.out.println(key + " = " + sj);
});
}
}
标签:String,框架,value,put,key,集合,new,public
From: https://blog.51cto.com/u_15433911/7106628