package cn.temptation; import java.util.HashMap;
import java.util.Map; public class Sample01 {
public static void main(String[] args) {
/*
* Collection接口及其子接口、实现类 等 称为 单列集合
* Map接口及其子接口、实现类等 称为 双列集合
*
* 接口 Map<K,V>:映射,将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。
*
* Map(映射)由两部分组成:键(Key)和值(Value)
*
* 特点:
* 1、一个映射不能包含重复的键
* 2、每个键最多只能映射到一个值
* 3、映射中的键值对是无序的
*
* 理解Map(映射):
* 联想地图,能唯一确定地点使用的是坐标,地图上没有两个相同的坐标
* 但是地图上可以有相同的地名,比如不同省份下的区县可能名字相同,但是它们的坐标是不同的
* 地图上的坐标就是键,地名就是值
*
* Map<K,V>接口的常用成员方法:
* 1、添加功能
* V put(K key, V value) :将指定的值与此映射中的指定键关联(可选操作)。
* 返回:以前与 key 关联的值,如果没有针对 key 的映射关系,则返回 null。(如果该实现支持 null 值,则返回 null 也可能表示此映射以前将 null 与 key 关联)。
*
* 2、删除功能
* void clear() :从此映射中移除所有映射关系(可选操作)。
* V remove(Object key) :如果存在一个键的映射关系,则将其从此映射中移除(可选操作)。
*
* 3、判断功能
* boolean containsKey(Object key) :如果此映射包含指定键的映射关系,则返回 true。
* boolean containsValue(Object value) :如果此映射将一个或多个键映射到指定值,则返回 true。
*
* boolean isEmpty() :如果此映射未包含键-值映射关系,则返回 true。
*
* 4、长度功能
* int size() :返回此映射中的键-值映射关系数。
*
*/
Map<String, String> map = new HashMap<>(); System.out.println("map:" + map); // map:{} // 1、添加功能
// 如果把Map的键值对理解为夫妻的话,那么其put方法可以认为是返回伴侣的前任
// System.out.println("map`s put:" + map.put("高祖", "杨开慧")); // map`s put:null
// System.out.println("map`s put:" + map.put("高祖", "贺子珍")); // map`s put:杨开慧
// System.out.println("map`s put:" + map.put("高祖", "*")); // map`s put:贺子珍 map.put("秦皇", "嬴政");
map.put("汉武", "刘彻");
map.put("唐宗", "李世民");
map.put("宋祖", "赵匡胤");
map.put("一代天骄", "成吉思汗");
// 键值对映射关系中,键相同的,通过put添加后显示的是最后的那个键值对或者说是最新的那个键值对
map.put("一代天骄", "蒋中正"); System.out.println("map:" + map); // map:{汉武=刘彻, 宋祖=赵匡胤, 一代天骄=蒋中正, 唐宗=李世民, 秦皇=嬴政} System.out.println("----------------------------------------------------"); // 2、删除功能
// map.clear();
// System.out.println("map:" + map); // map:{} map.remove("唐宗");
System.out.println("map:" + map); // map:{汉武=刘彻, 宋祖=赵匡胤, 一代天骄=蒋中正, 秦皇=嬴政} System.out.println("map`s remove:" + map.remove("宋祖")); // map`s remove:赵匡胤
System.out.println("map:" + map); // map:{汉武=刘彻, 一代天骄=蒋中正, 秦皇=嬴政} System.out.println("map`s remove:" + map.remove("西楚霸王")); // map`s remove:null System.out.println("----------------------------------------------------"); // 3、判断功能
System.out.println("map`s containsKey:" + map.containsKey("秦皇")); // map`s containsKey:true
System.out.println("map`s containsKey:" + map.containsKey("西楚霸王")); // map`s containsKey:false System.out.println("map`s containsValue:" + map.containsValue("刘彻")); // map`s containsValue:true
System.out.println("map`s containsValue:" + map.containsValue("刘秀")); // map`s containsValue:false map.clear();
System.out.println("map`s isEmpty:" + map.isEmpty()); // map`s isEmpty:true // 4、长度功能
System.out.println("map`s size:" + map.size()); // map`s size:0
}
}
package cn.temptation; import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set; public class Sample02 {
public static void main(String[] args) {
/*
* Map<K, V>接口的常用成员方法:
* 1、获取功能
* V get(Object key) :返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null。
* Set<K> keySet() :返回此映射中包含的键的 Set 视图。
* Collection<V> values() :返回此映射中包含的值的 Collection 视图。
*/
Map<String, String> map = new HashMap<>(); map.put("休斯敦", "火箭");
map.put("金州", "勇士");
map.put("洛杉矶", "湖人"); System.out.println(map.get("休斯敦")); // 火箭
System.out.println(map.get("金州")); // 勇士
System.out.println(map.get("洛杉矶")); // 湖人 System.out.println("-------------------------------"); // key不能重复
// 键值对映射关系中,键相同的,通过put添加后显示的是最后的那个键值对或者说是最新的那个键值对
map.put("西雅图", "超音速");
map.put("西雅图", "不眠夜"); Set<String> set = map.keySet(); for (String item : set) {
System.out.println(item);
} System.out.println("-------------------------------"); // value可以重复
map.put("夏洛特", "黄蜂");
map.put("新奥尔良", "黄蜂"); Collection<String> collection = map.values(); for (String item : collection) {
System.out.println(item);
} // 注意:取出的值的顺序 和 放入映射的顺序是不一致的,但是取出的值的顺序 和 取出的键的顺序一致
}
}
package cn.temptation; import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set; public class Sample03 {
public static void main(String[] args) {
/*
* Map<K, V>接口的常用成员方法:
* Set<Map.Entry<K,V>> entrySet() :返回此映射中包含的映射关系的 Set 视图。
*
* 接口 Map.Entry<K,V>:映射项(键-值对)。
*
* Map.Entry<K,V>接口的常用成员方法:
* 1、K getKey() :返回与此项对应的键。
* 2、V getValue() :返回与此项对应的值。
*/
Map<String, String> map = new HashMap<>(); map.put("德玛西亚之力", "盖伦");
map.put("德邦总管", "赵信");
map.put("无极剑圣", "易大师"); // 遍历Map // 方法1、通过Map接口的keySet方法、get方法
Set<String> keySet = map.keySet();
for (String key : keySet) {
String value = map.get(key);
System.out.println("key:" + key + " <-----> " + "value:" + value);
} System.out.println("-------------------------------------"); // 方法2、通过Map接口的entrySet方法、Entry接口的getKey方法、getValue方法(常用写法)
Set<Entry<String,String>> set = map.entrySet();
for (Entry<String, String> entry : set) {
String key = entry.getKey();
String value = entry.getValue();
System.out.println("key:" + key + " <-----> " + "value:" + value);
}
}
}
package cn.temptation; import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry; public class Sample04 {
public static void main(String[] args) {
/*
* 类 HashMap<K,V>:基于哈希表的 Map 接口的实现。此实现提供所有可选的映射操作,并允许使用 null 值和 null 键。
*/
Map<String, String> map = new HashMap<>(); map.put("中国", "北京");
map.put("美国", "华盛顿");
map.put(null, null); // 遍历
for (Entry<String, String> entry : map.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
System.out.println("key:" + key + " <-----> " + "value:" + value);
}
}
}
package cn.temptation; import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry; public class Sample05 {
public static void main(String[] args) {
// 需求:在map中存储学生信息(姓名和年龄)及学号,并进行遍历(以学号为key,以学生信息为value)
Map<String, Student> map = new HashMap<>(); // Map中key这个字符串类型设为学号,通过学号确定唯一性,学生信息作为值
map.put("9526", new Student("张三", 20));
map.put("9527", new Student("李四", 18));
map.put("9528", new Student("王五", 22));
// 因为key相同,所以覆盖了前面添加进去的Student对象
map.put("9526", new Student("赵六", 16)); System.out.println("map:" + map); // 遍历映射
for (Entry<String, Student> entry : map.entrySet()) {
String id = entry.getKey();
Student temp = entry.getValue();
System.out.println("学号为:" + id + "," + temp.toString());
}
}
}
package cn.temptation; import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry; public class Sample06 {
// 成员变量
private static Map<Student, String> map = new HashMap<>(); public static void main(String[] args) {
// 需求:在map中存储学生信息(姓名和年龄)及学号,并进行遍历(以学生信息为key,以学号为value)
// 问题1:如果我们知道这两个学生对象其实指的是同一个人,该如何处理?
// 答:这样学号就不是判断学生的唯一性的标准,而是学生信息是判定学生唯一的依据 // 问题2:添加学生信息不同的对象,但是学号相同,也加入到map对象中,想避免学号的重复,该如何处理?
// 答:考虑制作自动学号的生成方法,并且制作学生信息判断去重的方法 // 因为map中的数据不同的成员方法都要使用,所以考虑提取出去作为成员变量
// Map<Student, String> map = new HashMap<>(); // Map中key这个字符串类型设为学号,通过学号确定唯一性,学生信息作为值
// map.put(new Student("张三", 20), "9526");
// map.put(new Student("李四", 18), "9527");
// map.put(new Student("王五", 22), "9528");
// map.put(new Student("张三", 20), "9520"); // 重写Studengt对象的hashCode方法和equals后,就不会出现两个张三 20岁的学生对象了
// map.put(new Student("赵六", 16), "9527"); Student student1 = new Student("张三", 20);
if (checkStudent(student1)) {
map.put(student1, getCurrentID());
} Student student2 = new Student("李四", 18);
if (checkStudent(student2)) {
map.put(student2, getCurrentID());
} Student student3 = new Student("王五", 2);
if (checkStudent(student3)) {
map.put(student3, getCurrentID());
} Student student4 = new Student("赵六", 16);
if (checkStudent(student4)) {
map.put(student4, getCurrentID());
} Student student5 = new Student("张三", 20);
if (checkStudent(student5)) {
map.put(student5, getCurrentID());
} System.out.println("map:" + map); // 遍历映射
for (Entry<Student, String> entry : map.entrySet()) {
Student temp = entry.getKey();
String id = entry.getValue();
System.out.println("学号为:" + id + "," + temp.toString());
}
} // 获取当前可以使用的学号
public static String getCurrentID() {
String result = "1"; if (map.size() > 0) { // 获取所有的学号,存入Collection对象
Collection<String> collection = map.values(); int max = 0; for (String item : collection) {
if (Integer.parseInt(item) > max) {
max = Integer.parseInt(item);
}
} result = max + 1 + "";
} return result;
} // 判断学生信息是否有重复
public static boolean checkStudent(Student student) {
boolean flag = true; // 获取所有的学生信息,存入Set对象
Set<Student> keySet = map.keySet(); for (Student item : keySet) {
if (item.equals(student)) {
flag = false;
break;
}
} return flag;
}
}
package cn.temptation; // 学生类
public class Student {
// 成员变量
private String name;
private int age; // 构造函数
public Student() {
super();
} public Student(String name, int age) {
super();
this.name = name;
this.age = age;
} // 成员方法
public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} // 为了唯一判断对象,重写hashCode方法和equals方法
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
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 (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
} @Override
public String toString() {
return "学生 [姓名为:" + name + ", 年龄为:" + age + "]";
}
}
package cn.temptation; import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry; public class Sample07 {
public static void main(String[] args) {
/*
* 类 LinkedHashMap<K,V>:Map 接口的哈希表和链接列表实现,具有可预知的迭代顺序。
*
* 特点:
* 1、由HashMap保证唯一性
* 2、由链表保证有序性
*/
Map<String, String> map = new LinkedHashMap<>(); map.put("无冕之王", "荷兰");
map.put("桑巴军团", "巴西");
map.put("亚洲三流", "中国"); for (Entry<String, String> entry : map.entrySet()) {
System.out.println("美称:" + entry.getKey() + " <-----> 国家名称:" + entry.getValue());
}
}
}
package cn.temptation; import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap; public class Sample08 {
public static void main(String[] args) {
/*
* 类 TreeMap<K,V>:
* 基于红黑树(Red-Black tree)的 NavigableMap 实现。
* 该映射根据其键的自然顺序进行排序,或者根据创建映射时提供的 Comparator 进行排序,具体取决于使用的构造方法。
*
* 用法:类比TreeSet
*/
Map<String, String> map = new TreeMap<>(); map.put("Q", "嬴政");
map.put("H", "刘彻");
map.put("T", "李世民");
map.put("S", "赵匡胤"); for (Entry<String, String> entry : map.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
System.out.println(key + " <-----> " + value);
} System.out.println("------------------------------"); Set<String> keySet = map.keySet();
System.out.println("keyset:" + keySet); for (String key : keySet) {
String value = map.get(key);
System.out.println(key + " <-----> " + value);
}
}
}
package cn.temptation; import java.util.Comparator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap; public class Sample09 {
public static void main(String[] args) {
// 需求:使用TreeMap存储学生信息,姓名和年龄相同的学生只能存储一个,排序规则:先按年龄排序,年龄相同按姓名自然排序 // 思路:姓名和年龄相同的学生只能存储一个,也就是把学生信息作为键;和TreeSet一样,自定义排序规则:通过实现Comparable接口 或 Comparator接口 Map<Student, String> map = new TreeMap<>(new Comparator<Student>() {
@Override
public int compare(Student student1, Student student2) {
// 先比较年龄
int resultAge = student1.getAge() - student2.getAge(); // 年龄相同比较姓名
int result = (resultAge == 0) ? student1.getName().compareTo(student2.getName()) : resultAge; return result;
}
}); map.put(new Student("张三", 20), "9526");
map.put(new Student("李四", 18), "9527");
map.put(new Student("王五", 20), "9528");
map.put(new Student("张三", 20), "9529"); for (Entry<Student, String> entry : map.entrySet()) {
Student temp = entry.getKey();
String id = entry.getValue();
System.out.println("学号为:" + id + "," + temp.toString());
}
}
}
package cn.temptation; import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry; public class Sample10 {
public static void main(String[] args) {
// 需求:选择合适的容器结构,存储并显示数据
// 类别:篮球明星前三名:乔丹、邓肯、科比
// 类别:足球明星前五名:梅西、C罗、卡卡、伊布、哈维 // 思路:容器中可以再放入容器 // 写法1、使用数组存储(注意:不同数组的索引同步)
// 声明类别数组
String[] arrCategory = { "篮球", "足球" };
// 声明球星数组
String[][] arrStar = { { "乔丹", "邓肯", "科比" }, { "梅西", "C罗", "卡卡", "伊布", "哈维" } }; // 遍历数组
for (int i = 0; i < arrCategory.length; i++) {
StringBuffer sb = new StringBuffer();
sb.append("类别:").append(arrCategory[i]).append("中前").append(arrStar[i].length).append("名:"); for (int j = 0; j < arrStar[i].length; j++) {
sb.append(arrStar[i][j]).append("、");
} System.out.println(sb.substring(0, sb.length() - 1));
} System.out.println("--------------------------------------------------------"); // 写法2、使用集合存储(整体使用Map映射,key存为类别,value存为存放了多个球星名字的ArrayList)
Map<String, ArrayList<String>> map = new LinkedHashMap<>(); ArrayList<String> basketBallList = new ArrayList<>();
basketBallList.add("乔丹");
basketBallList.add("邓肯");
basketBallList.add("科比"); map.put("篮球", basketBallList); ArrayList<String> soccerList = new ArrayList<>();
soccerList.add("梅西");
soccerList.add("C罗");
soccerList.add("卡卡");
soccerList.add("伊布");
soccerList.add("哈维"); map.put("足球", soccerList); for (Entry<String, ArrayList<String>> entry : map.entrySet()) {
StringBuffer sb = new StringBuffer(); String category = entry.getKey();
ArrayList<String> list = entry.getValue(); sb.append("类别:").append(category).append("中前").append(list.size()).append("名:"); for (String item : list) {
sb.append(item).append("、");
} System.out.println(sb.substring(0, sb.length() - 1));
}
}
}
package cn.temptation; import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry; public class Sample11 {
public static void main(String[] args) {
// 需求:
// 存储并显示2016年NBA东西部决赛
// 东部:克利夫兰<----->骑士、明尼苏达<----->森林狼
// 西部:休斯敦<----->火箭、金州<----->勇士
// 存储并显示2015年NBA东西部决赛
// 东部:克利夫兰<----->骑士、亚特兰大<----->老鹰
// 西部:洛杉矶<----->湖人、金州<----->勇士 // 思路:复杂问题分解为若干个简单问题 Map<String, String> map1 = new LinkedHashMap<>();
map1.put("克利夫兰", "骑士");
map1.put("明尼苏达", "森林狼"); Map<String, String> map2 = new LinkedHashMap<>();
map2.put("休斯敦", "火箭");
map2.put("金州", "勇士"); Map<String, Map<String, String>> mapArea2016 = new LinkedHashMap<>();
mapArea2016.put("东部", map1);
mapArea2016.put("西部", map2); // 把2016年的数据封装在对象中
Record record2016 = new Record();
record2016.setYear(2016);
record2016.setMapArea(mapArea2016); Map<String, String> map3 = new LinkedHashMap<>();
map3.put("克利夫兰", "骑士");
map3.put("亚特兰大", "老鹰"); Map<String, String> map4 = new LinkedHashMap<>();
map4.put("洛杉矶", "湖人");
map4.put("金州", "勇士"); Map<String, Map<String, String>> mapArea2015 = new LinkedHashMap<>();
mapArea2015.put("东部", map3);
mapArea2015.put("西部", map4); // 把2015年的数据封装在对象中
Record record2015 = new Record();
record2015.setYear(2015);
record2015.setMapArea(mapArea2015); // 创建存储数据记录的集合
Collection<Record> collectionNBA = new ArrayList<>();
collectionNBA.add(record2016);
collectionNBA.add(record2015); StringBuffer sb = new StringBuffer(); // 遍历
for (Record record : collectionNBA) {
sb.append(record.getYear()).append("年NBA东西部决赛:").append("\r\n"); for (Entry<String, Map<String, String>> entryArea : record.getMapArea().entrySet()) {
sb.append(entryArea.getKey()).append(":"); Map<String, String> mapCity = entryArea.getValue(); StringBuffer sbTemp = new StringBuffer(); for (Entry<String, String> entry : mapCity.entrySet()) {
sbTemp.append(entry.getKey()).append("<------>").append(entry.getValue()).append(",");
} sb.append(sbTemp.substring(0, sbTemp.length() - 1));
sb.append("\r\n");
} sb.append("\r\n");
} System.out.println(sb);
}
}
package cn.temptation; import java.util.LinkedHashMap;
import java.util.Map; /**
* 数据记录类
*/
public class Record {
// 成员变量
// 数据记录年份
private int year;
// 数据记录内容
private Map<String, Map<String, String>> mapArea = new LinkedHashMap<>(); // 构造函数
public Record() {
super();
} public Record(int year, Map<String, Map<String, String>> mapArea) {
super();
this.year = year;
this.mapArea = mapArea;
} // 成员方法
public int getYear() {
return year;
} public void setYear(int year) {
this.year = year;
} public Map<String, Map<String, String>> getMapArea() {
return mapArea;
} public void setMapArea(Map<String, Map<String, String>> mapArea) {
this.mapArea = mapArea;
} @Override
public String toString() {
return "数据 [年份为:" + year + ", 内容为:" + mapArea + "]";
}
}
package cn.temptation; import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry; public class Sample12 {
public static void main(String[] args) {
// 需求:使用集合相关知识统计"javaisgoodisbetterisbestisamazing"中各个字符出现的次数
// 显示:字符j:1次、字符a:4次、... // 思路:
// 1、既然统计的是字符出现的次数,所以把字符串转换为字符数组
// 2、创建一个map集合用来存储字符及其出现次数的关系映射,设置key为字符,value为出现次数
// 3、遍历字符数组,将得到的字符(key)传递map映射的get方法找到对应出现的次数(value)
// A:如果返回值为null,说明map映射中没有该字符及其出现次数的映射关系,那么map中存储下来这个映射关系
// B:如果返回值不为null,说明map映射中存在该字符及其出现次数的映射关系,那么将value值+1,再存储下来 String str = "javaisgoodisbetterisbestisamazing";
char[] arr = str.toCharArray();
Map<Character, Integer> map = new LinkedHashMap<>(); // 遍历字符数组
for (char item : arr) {
// 根据各个字符传入map集合中查找
Integer count = map.get(item); if (count == null) {
// 如果返回值为null,说明map映射中没有该字符及其出现次数的映射关系,那么map中存储下来这个映射关系
map.put(item, 1);
} else {
// 如果返回值不为null,说明map映射中存在该字符及其出现次数的映射关系,那么将value值+1,再存储下来
count++;
// 注意:具有相同key的键值对,最新的键值对会覆盖之前的键值对
map.put(item, count);
}
} // 遍历map集合
for (Entry<Character, Integer> entry : map.entrySet()) {
Character key = entry.getKey();
Integer value = entry.getValue();
System.out.println("字符" + key + ":" + value + "次");
}
}
}
package cn.temptation; import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List; public class Sample13 {
public static void main(String[] args) {
/*
* 类 Collections:
* 此类完全由在 collection 上进行操作或返回 collection 的静态方法组成。
* 它包含在 collection 上操作的多态算法,即“包装器”,包装器返回由指定 collection 支持的新 collection,以及少数其他内容。
*
* Collections类的常用成员方法:
* 1、static <T extends Comparable<? super T>> void sort(List<T> list) :根据元素的自然顺序 对指定列表按升序进行排序。
*
* 2、static <T> int binarySearch(List<? extends Comparable<? super T>> list, T key) :使用二分搜索法搜索指定列表,以获得指定对象。
* 返回:如果搜索键包含在列表中,则返回搜索键的索引;否则返回 (-(插入点) - 1)。
* 插入点 被定义为将键插入列表的那一点:即第一个大于此键的元素索引;如果列表中的所有元素都小于指定的键,则为 list.size()。
* 注意,这保证了当且仅当此键被找到时,返回的值将 >= 0。
*
* 3、static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll) :根据元素的自然顺序,返回给定 collection 的最大元素。
*
* 4、static void reverse(List<?> list) :反转指定列表中元素的顺序。
*
* 5、static void shuffle(List<?> list) :使用默认随机源对指定列表进行置换。
*
*/ Collection<Integer> collection = new ArrayList<>(); collection.add(2);
collection.add(3);
collection.add(5);
collection.add(4);
collection.add(1); System.out.println("初始集合:" + collection); // 初始集合:[2, 3, 5, 4, 1] Collections.sort((List<Integer>)collection);
System.out.println("使用排序:" + collection); // 使用排序:[1, 2, 3, 4, 5] System.out.println("二分查找:" + Collections.binarySearch((List<Integer>)collection, 2)); //
System.out.println("二分查找:" + Collections.binarySearch((List<Integer>)collection, 0)); // -1
System.out.println("二分查找:" + Collections.binarySearch((List<Integer>)collection, 5)); // System.out.println("最大值:" + Collections.max(collection)); // Collections.reverse((List<Integer>)collection);
System.out.println("使用反转:" + collection); // 使用反转:[5, 4, 3, 2, 1] Collections.shuffle((List<Integer>)collection);
System.out.println("随机置换:" + collection);
}
}
package cn.temptation; import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List; public class Sample14 {
public static void main(String[] args) {
/*
* Collections类的常用成员方法:
* 1、static <T> void sort(List<T> list, Comparator<? super T> c) :根据指定比较器产生的顺序对指定列表进行排序。
*/
Collection<Student> collection = new ArrayList<>(); collection.add(new Student("张三", 20));
collection.add(new Student("李四", 18));
collection.add(new Student("王五", 22));
collection.add(new Student("张飞", 20)); // 语法错误:The method sort(List<T>) in the type Collections is not applicable for the arguments (List<Student>)
// Collections.sort((List<Student>)collection); Collections.sort((List<Student>)collection, new Comparator<Student>() {
@Override
public int compare(Student student1, Student student2) {
// 先比较年龄
int resultAge = student1.getAge() - student2.getAge(); // 年龄相同再比较姓名
int result = (resultAge == 0) ? student1.getName().compareTo(student2.getName()) : resultAge; return result;
}
}); // 遍历
for (Student item : collection) {
System.out.println(item);
}
}
}
package cn.temptation; import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List; public class Sample15 {
public static void main(String[] args) {
// 需求:使用所学集合知识,模拟一副牌(54张)的洗牌、发牌(按照规则制作即可,规则选用一副牌斗地主)和看牌(无序)
// 牌:A、2、3、4、5、6、7、8、9、10、J、Q、K、BlackJoker、RedJoker
// 花色:♥ ◆ ♠ ♣ // 思路:
// 1、创建出一副牌54张(4种花色每种13张,还有大王小王)
// 2、把牌放入一个容器中
// 3、洗牌(考虑使用集合工具类Collections的shuffle方法)
// 4、发牌
// 5、看牌 // 1、创建出一副牌54张(4种花色每种13张,还有大王小王)
// 创建花色集合
Collection<String> colors = new ArrayList<>();
colors.add("♥");
colors.add("◆");
colors.add("♠");
colors.add("♣"); // 创建数字集合
Collection<String> numbers = new ArrayList<>();
numbers.add("A");
for (int i = 2; i <= 10; i++) {
numbers.add(String.valueOf(i));
}
numbers.add("J");
numbers.add("Q");
numbers.add("K"); // 2、把牌放入一个容器中
Collection<String> poker = new ArrayList<>(); for (String color : colors) {
for (String number : numbers) {
poker.add(color.concat(number));
}
} poker.add("BlackJoker");
poker.add("RedJoker"); // System.out.println("一副牌:" + poker); // 3、洗牌(考虑使用集合工具类Collections的shuffle方法)
Collections.shuffle((List<String>)poker); // System.out.println("洗一副牌:" + poker); // 4、发牌
// 声明剩余底牌数量
int remain = 3;
// 声明三个玩家对象和一个底牌对象
Collection<String> player1 = new ArrayList<>();
Collection<String> player2 = new ArrayList<>();
Collection<String> player3 = new ArrayList<>();
Collection<String> last = new ArrayList<>(); for (int i = 0; i < poker.size(); i++) {
if (i >= poker.size() - remain) { // 留下底牌
last.add(((List<String>)poker).get(i));
} else if (i % 3 == 0) { // 给第一个玩家发牌
player1.add(((List<String>)poker).get(i));
} else if (i % 3 == 1) { // 给第二个玩家发牌
player2.add(((List<String>)poker).get(i));
} else if (i % 3 == 2) { // 给第三个玩家发牌
player3.add(((List<String>)poker).get(i));
}
} // 5、看牌
lookPoker("玩家1", player1);
lookPoker("玩家2", player2);
lookPoker("玩家3", player3);
lookPoker("底牌", last);
} /**
* 看牌方法
* @param name 玩家名
* @param collection 手牌集合
*/
public static void lookPoker(String name, Collection<String> collection) {
System.out.println(name + "的手牌是:");
for (String item : collection) {
System.out.print(item + " ");
}
// 换行
System.out.println();
}
}
package cn.temptation; import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet; public class Sample16 {
public static void main(String[] args) {
// 需求:使用所学集合知识,模拟一副牌(54张)的洗牌、发牌(按照规则制作即可,规则选用一副牌斗地主)和看牌(有序)
// 牌:A、2、3、4、5、6、7、8、9、10、J、Q、K、BlackJoker、RedJoker
// 花色:♥ ◆ ♠ ♣
// 顺序规则:牌的规则:3 < 4 < 5 < ... < 10 < J < Q < K < A < 2 < BlackJoker < RedJoker
// 花色的规则(牌相同时)♥ ♠ ♣ ◆ // 思路1:
// 在发牌时,通过比较器的使用,直接按规则排列玩家手中牌和底牌 // 1、创建出一副牌54张(4种花色每种13张,还有大王小王)
// 创建花色集合
Collection<String> colors = new ArrayList<>();
colors.add("♥");
colors.add("◆");
colors.add("♠");
colors.add("♣"); // 创建数字集合
Collection<String> numbers = new ArrayList<>();
numbers.add("A");
for (int i = 2; i <= 10; i++) {
numbers.add(String.valueOf(i));
}
numbers.add("J");
numbers.add("Q");
numbers.add("K"); // 2、把牌放入一个容器中
Collection<Card> poker = new ArrayList<>(); for (String color : colors) {
for (String number : numbers) {
Card temp = new Card();
temp.setColor(color);
temp.setNumber(number); poker.add(temp);
}
} poker.add(new Card("", "BlackJoker"));
poker.add(new Card("", "RedJoker")); // System.out.println("一副牌:" + poker); // 3、洗牌(考虑使用集合工具类Collections的shuffle方法)
Collections.shuffle((List<Card>)poker); // System.out.println("洗一副牌:" + poker); // 4、发牌
// 声明剩余底牌数量
int remain = 3; // 声明三个玩家对象和一个底牌对象
Comparator<Card> comparator = new CardComparator(); Set<Card> player1 = new TreeSet<>(comparator);
Set<Card> player2 = new TreeSet<>(comparator);
Set<Card> player3 = new TreeSet<>(comparator);
Set<Card> last = new TreeSet<>(comparator); for (int i = 0; i < poker.size(); i++) {
if (i >= poker.size() - remain) { // 留下底牌
last.add(((List<Card>)poker).get(i));
} else if (i % 3 == 0) { // 给第一个玩家发牌
player1.add(((List<Card>)poker).get(i));
} else if (i % 3 == 1) { // 给第二个玩家发牌
player2.add(((List<Card>)poker).get(i));
} else if (i % 3 == 2) { // 给第三个玩家发牌
player3.add(((List<Card>)poker).get(i));
}
} // 5、看牌
lookPoker("玩家1", player1);
lookPoker("玩家2", player2);
lookPoker("玩家3", player3);
lookPoker("底牌", last);
} /**
* 看牌方法
* @param name 玩家名
* @param collection 手牌集合
*/
public static void lookPoker(String name, Set<Card> collection) {
System.out.println(name + "的手牌是:");
for (Card item : collection) {
System.out.print(item + " ");
}
// 换行
System.out.println();
}
}
package cn.temptation; /**
* 牌类
*/
public class Card {
// 成员变量
// 花色
private String color;
// 数字
private String number; // 构造函数
public Card() {
super();
} public Card(String color, String number) {
super();
this.color = color;
this.number = number;
} // 成员方法
public String getColor() {
return color;
} public void setColor(String color) {
this.color = color;
} public String getNumber() {
return number;
} public void setNumber(String number) {
this.number = number;
} @Override
public String toString() {
return color + number;
}
}
package cn.temptation; import java.util.Comparator; /**
* 牌的比较器
*/
public class CardComparator implements Comparator<Card> {
@Override
public int compare(Card card1, Card card2) {
// 首先比较数字
int resultNumber = numberChange(card1.getNumber()) - numberChange(card2.getNumber()); // 数字相同时,比较花色
int result = (resultNumber == 0) ? colorChange(card1.getColor()) - colorChange(card2.getColor()) : resultNumber; return result;
} /**
* 手牌数字转换方法
* @param number 手牌数字
* @return 对应数字
*/
public static int numberChange(String number) {
int result = 0; switch (number) {
case "J":
result = 11;
break;
case "Q":
result = 12;
break;
case "K":
result = 13;
break;
case "A":
result = 14;
break;
case "2":
result = 15;
break;
case "BlackJoker":
result = 16;
break;
case "RedJoker":
result = 17;
break;
default:
result = Integer.parseInt(number);
break;
} return result;
} /**
* 手牌花色转换方法
* @param color 手牌花色
* @return 对应数字
*/
public static int colorChange(String color) {
int result = 0; switch (color) {
case "♥":
result = 1;
break;
case "♠":
result = 2;
break;
case "♣":
result = 3;
break;
case "◆":
result = 4;
break;
default:
break;
} return result;
}
}
package cn.temptation; import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet; public class Sample17 {
public static void main(String[] args) {
// 需求:使用所学集合知识,模拟一副牌(54张)的洗牌、发牌(按照规则制作即可,规则选用一副牌斗地主)和看牌(有序)
// 牌:A、2、3、4、5、6、7、8、9、10、J、Q、K、BlackJoker、RedJoker
// 花色:♥ ◆ ♠ ♣
// 顺序规则:牌的规则:3 < 4 < 5 < ... < 10 < J < Q < K < A < 2 < BlackJoker < RedJoker
// 花色的规则(牌相同时)♥ ♠ ♣ ◆ // 思路2:
// 在发牌阶段进行排序比较麻烦,可以考虑在创建牌的时候,就把顺序订好,54张牌按照大小和花色有一个数字排序(索引)
// 后续操作时,洗牌洗的就是这个数字顺序,看牌时每个人的手牌和底牌都按数字顺序排列就好 // 1、创建出一副牌54张(4种花色每种13张,还有大王小王),花色顺序和数字顺序都定好
// 2、牌不但有纸面内容(花色和数字),还有其索引,所以考虑使用Map存储
// 3、洗牌(考虑使用集合工具类Collections的shuffle方法)
// 4、发牌(发的也是牌的索引)
// 5、看牌 // 1、创建出一副牌54张(4种花色每种13张,还有大王小王),花色顺序和数字顺序都定好
// 创建花色集合
Collection<String> colors = new ArrayList<>();
colors.add("♥");
colors.add("♠");
colors.add("♣");
colors.add("◆"); // 创建数字集合
Collection<String> numbers = new ArrayList<>();
for (int i = 3; i <= 10; i++) {
numbers.add(String.valueOf(i));
}
numbers.add("J");
numbers.add("Q");
numbers.add("K");
numbers.add("A");
numbers.add("2"); // 2、牌不但有纸面内容(花色和数字),还有其索引,所以考虑使用Map存储
// 创建存放牌的容器
Map<Integer, String> poker = new HashMap<>();
// 创建存放牌的索引的容器(伴随着把牌放入Map对象中,索引放入Collection对象中)
Collection<Integer> collection = new ArrayList<>();
// 声明牌的索引变量
int index = 0; // 注意:放牌进入map中顺序,先数字再花色
for (String number : numbers) {
for (String color : colors) {
// 把牌放入Map对象中
poker.put(index, color.concat(number));
// 把牌的索引放入Collection对象中
collection.add(index);
// 创建一张牌,索引自增
index++;
}
} // 创建小王
poker.put(index, "BlackJoker");
collection.add(index);
index++; // 创建大王
poker.put(index, "RedJoker");
collection.add(index);
index++; // 遍历map
// for (Entry<Integer, String> entry : poker.entrySet()) {
// System.out.println(entry.getKey() + "<----->" + entry.getValue());
// } // 3、洗牌(考虑使用集合工具类Collections的shuffle方法,洗的是牌的索引集合)
Collections.shuffle((List<Integer>)collection); // System.out.println("洗一副牌:" + collection); // 4、发牌(发的是牌的索引)
// 声明剩余底牌数量
int remain = 3; Set<Integer> player1 = new TreeSet<>();
Set<Integer> player2 = new TreeSet<>();
Set<Integer> player3 = new TreeSet<>();
Set<Integer> last = new TreeSet<>(); for (int i = 0; i < poker.size(); i++) {
if (i >= poker.size() - remain) { // 留下底牌
last.add(((List<Integer>)collection).get(i));
} else if (i % 3 == 0) { // 给第一个玩家发牌
player1.add(((List<Integer>)collection).get(i));
} else if (i % 3 == 1) { // 给第二个玩家发牌
player2.add(((List<Integer>)collection).get(i));
} else if (i % 3 == 2) { // 给第三个玩家发牌
player3.add(((List<Integer>)collection).get(i));
}
} // 5、看牌(根据键值对中的键去map中找值)
lookPoker("玩家1", player1, poker);
lookPoker("玩家2", player2, poker);
lookPoker("玩家3", player3, poker);
lookPoker("底牌", last, poker);
} /**
* 看牌方法
* @param name 玩家名
* @param collection 手牌集合
*/
public static void lookPoker(String name, Set<Integer> collection, Map<Integer, String> map) {
System.out.println(name + "的手牌是:"); for (Integer item : collection) {
System.out.print(map.get(item) + " ");
} // 换行
System.out.println();
}
}
package cn.temptation; public class Sample18 {
public static void main(String[] args) {
/*
* 集合总结:
* Collection接口(单列集合):
* 1、List接口(有序、可重复):
* A、ArrayList:底层实现是数组,查找快速、增删比较慢
* B、Vector:向量类,ArrayList是其升级版,底层实现是数组,查找快速、增删比较慢,遍历向量对象可以使用枚举器(Enumeration)
* C、LinkedList:底层实现是链表,查找比较慢、增删快速
*
* 2、Set接口(无序、唯一):
* A、HashSet:底层实现是哈希表、依赖于hashCode()和equals()
* B、LinkedHashSet:底层实现是哈希表和链表组成,由哈希表保证元素唯一、由链表保证元素有序
* C、TreeSet:支持自然排序和自定义规则排序(实现Comparable接口 或 Comparator接口)
*
* Map接口(双列集合):
* A、HashMap:底层实现是哈希表、依赖于hashCode()和equals()
* B、LinkedHashMap:底层实现是哈希表和链表组成,由哈希表保证元素唯一、由链表保证元素有序
* C、TreeMap:支持自然排序和自定义规则排序(实现Comparable接口 或 Comparator接口)
*
*
* 是否需要键值对:
* 是:选择Map,键是否需要排序
* 是:选择TreeMap
* 否:选择HashMap
* 否:选择Collection,元素是否需要唯一
* 是:选择Set,元素是否需要排序
* 是:TreeSet
* 否:HashSet
* 否:选择List,需要查找快速还是需要增删快速
* 查找快速:ArrayList
* 增删快速:LinkedList
*
* 遍历元素:
* 1、一般for循环
* 2、迭代器(Iterator)或枚举器(Enumeration)
* 3、增强型for循环
*
*/
}
}