------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------
集合类目录:
一、Set接口
1、Set接口概述
2、Set集合的特点
3、Set_存储自定义对象
4、LinkedHashSet类
5、TreeSet类
6、TreeSet类存储自定义对象
7、TreeSet类_比较器排序
8、TreeSet类_排序说明
9、Set小结
10、产生10个1到20之间的随机数要求随机数不能重复(练习)
11、按总分排序(练习)
二、Map接口
1、Map集合
2、Map集合_的基本功能
3、Map集合_的获取功能
4、键是String值是Student的案例
5、键是Student值是String的案例
6、LinkedHashMap的概述和使用
7、TreeMap_键是String值是String的案例
8、TreeMap_键是Student值是String的案例
9、统计字符出现的次数
10、HashMap集合嵌套HashMap集合的案例
11、HashMap集合嵌套ArrayList集合的案例
12、ArrayList集合嵌套HashMap集合的案例
13、HashMap和Hashtable的区别
三、Collections工具类
1、Collections工具类的使用
2、ArrayList存储自定义对象并排序案例
3、模拟斗地主洗牌和发牌
4、模拟斗地主洗牌和发牌_对牌进行排序
总结集合类知识详解:
一、Set接口
1、Set接口概述
* Collection(接口)
* |--List(接口):1.有序的;2.可以存储重复值
* |--ArrayList(类):
* |--Vector(类):
* |--LinkedList(类):
* |--Set(接口):1.无序的;2.不能存储重复值
* |--HashSet(类):哈希表;
* |--LinkeHashSet(类):
* |--TreeSet(类):
public class Demo {
public static void main(String[] args) {
Set<String> strSet = new HashSet<>();
strSet.add("aaa");
strSet.add("bbb");
strSet.add("ccc");
strSet.add("ddd");
//存储重复值
strSet.add("ccc");//不存
strSet.add("ddd");//不存
strSet.add("eee");
//1.toArray();
//2.Iterator();
Iterator<String> it = strSet.iterator();
while(it.hasNext()){
System.out.println(it.next());//取出时的顺序,跟存入时的顺序不同;
}
}
}

2、Set集合的特点
* Collection(接口)
* |--List(接口):1.有序的;2.可以存储重复元素
* |--ArrayList:数组实现;线程不完全的,效率高;
* |--Vector:数组实现;线程安全的,效率低;
* |--LinkedList:链表实现;线程不安全的,效率高;
* 数组:查询快;增、删慢;
* 链表:查询慢;增、删快;
* |--Set(接口):1.无序的;2.不能存储重复值;
* |--HashSet(类):哈希表结构;综合了数组和链表的优点了。查询快;增、删快;
* 重复性验证:第一步:哈希值;
* 第二步:equals():
* HashSet如何保证元素唯一性,底层数据结构是哈希表(元素是链表的数组),哈希表依赖于哈希值存储
* 添加功能底层依赖两个方法:,int hashCode(),boolean equals(Object obj)

public class Demo {
public static void main(String[] args) {
Set<String> strSet = new HashSet<>();
strSet.add("aaa");
strSet.add("bbb");
strSet.add("ccc");
strSet.add("ddd");
strSet.add("ccc");
strSet.add("ddd");
strSet.add("eee");
for(String s : strSet){
System.out.println(s);
}
}
}

3、Set_存储自定义对象
* 使用HashSet存储自定义对象
* 1.需要判断出两个对象中的属性值是否完全一样,需要重写hashCode()和equals();
* 2.怎么重写?
* 鼠标-->右键-->source-->Generate hashCode() and equals()
class Student {
String name;
int age;
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
@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;
}
}
public class Demo {
public static void main(String[] args) {
Set<Student> stuSet = new HashSet<>();
stuSet.add(new Student("张三",20));
stuSet.add(new Student("李四",22));
stuSet.add(new Student("王五",24));
stuSet.add(new Student("王五",24));
for(Student stu : stuSet){
System.out.println(stu.name + "---" + stu.age);
}
}
}

4、LinkedHashSet类
* Collection
* |--List:
* |--Set:
* |--HashSet:哈希表结构:
* |--LinkedHashSet:链表和哈希表结构:
* 1.有序的;(由链表保证顺序)
* 2.不存储重复值;(由哈希表保证唯一):hashCode-->equals()
public class Demo {
public static void main(String[] args) {
LinkedHashSet<String> set = new LinkedHashSet<>();
set.add("aaa");
set.add("bbb");
set.add("ccc");
set.add("ddd");
set.add("ddd");
for(String s : set){
System.out.println(s);
}
}
}

5、TreeSet类
* Collection:
* |--List:
* |--Set:
* |--HashSet:哈希表;
* |--LinkedHashSet:链表和哈希表;
* |--TreeSet:树结构:
* 特点:对元素进行排序;
* 排序的方式:
* 一:自然排序;
* 二:比较器排序;
* 用TreeSet存储Integer类型数据讲解排序和唯一。
* 20,18,23,22,17,24,19,18,24
public class Demo {
public static void main(String[] args) {
TreeSet<Integer> tree1 = new TreeSet<>();
tree1.add(20);
tree1.add(18);
tree1.add(23);
tree1.add(22);
tree1.add(17);
tree1.add(24);
tree1.add(19);
tree1.add(18);
tree1.add(24);
for(Integer i : tree1){
System.out.println(i);
}
TreeSet<String> tree2 = new TreeSet<>();
tree2.add("aaa");
tree2.add("ccc");
tree2.add("eee");
tree2.add("bbb");
tree2.add("ddd");
for(String s : tree2){
System.out.println(s);
}
System.out.println("------------------------");
TreeSet<String> tree3 = new TreeSet<>();
tree3.add("张三");//z
tree3.add("李四");//l
tree3.add("赵四");//z
tree3.add("王五");//w
tree3.add("周六");//z
tree3.add("阿炳");//a
for(String s : tree3){
System.out.println(s);
}
}
}

6、TreeSet类存储自定义对象
* 如果TreeSet中存储的是自定义类型,那么使用Tree,就得排序,要排序就得比较:
* 比较的方式:
* 1.自然排序:Comparable(接口)--》compareTo()方法
* 2.比较器排序:
* 1.自定义类无需实现任何接口;
* 2.自定义比较器对象,实现Comparator接口,并重写compare()方法;(一般使用匿名内部类的方式实现)
* 3.当实例化一个TreeSet时,将此比较器对象传入构造方法;
public class Student implements Comparable{
String name;
int age;
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
@Override
public int compareTo(Object o) {
//按学员的年龄排序
Student stu = (Student)o;
//1,先按年龄排
int n1 = this.age - stu.age;
//2.如果年龄相同,按姓名排
int n2 = (n1 == 0 ? this.name.compareTo(stu.name) : n1);
return n2;
}
}
public class Demo {
public static void main(String[] args) {
TreeSet<Student> set = new TreeSet<>();
set.add(new Student("张三",20));
set.add(new Student("李四",19));
set.add(new Student("王五",21));
set.add(new Student("周六",17));
set.add(new Student("赵七",28));
set.add(new Student("刘备",28));
set.add(new Student("李四",20));
set.add(new Student("赵七",28));//重复的元素;
for(Student stu : set){
System.out.println(stu.name + "--" + stu.age);
}
/*TreeSet<String> strSet = new TreeSet<>();
strSet.add("aaa");
String s;*/
//TreeMap m;
}
}

7、TreeSet类_比较器排序
public class Student{
String name;
int age;
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
}
public class Demo {
public static void main(String[] args) {
TreeSet<Student> set = new TreeSet<>(new Comparator<Student>(){
@Override
public int compare(Student o1, Student o2) {
//1.先比较年龄
int n1 = o1.age - o2.age;
//2.再判断姓名
int n2 = (n1 == 0 ? o1.name.compareTo(o2.name) : n1);
return n2;
}
});
set.add(new Student("张三",20));
set.add(new Student("李四",19));
set.add(new Student("赵七",28));
set.add(new Student("赵七",28));//重复的元素;
for(Student stu : set){
System.out.println(stu.name + "--" + stu.age);
}
}
}

8、TreeSet类_排序说明
interface Comparator{//IA9、Set小结
int compare();
}
interface Comparable{
int compareTo();
}
class TreeSet{//我
private TreeMap m;
public TreeSet(){
m = new TreeMap();
}
public TreeSet(Comparator a){
m = new TreeMap(a);
}
public void add(Comparable obj){
m.put(obj);
}
}
class TreeMap{//班长
private Comparator a;//比较器
public TreeMap(){
}
public TreeMap(Comparator a){
this.a = a;
}
public void put(Comparable obj){
if(this.a != null){//有比较器
//按比较器比较
this.a.compare(obj,内部已经存储的对象);
}else{ //没有比较器,按自然排序
obj.compareTo("//内部的已经存储的对象进行比较");
}
}
}
public class Demo {
public static void main(String[] args) {
TreeSet set = new TreeSet();//没有比较器-->使用自然排序
TreeSet set = new TreeSet(new Comparator(){
});//传递一个比较器-->比较器排序;
}
}
* Collection:
* |--List:1.有序的;2.存储重复值;
* |--Set:1.无序的;2.不能存储重复值:
* |--HashSet:
* 1.哈希表存储;
* 2.验证唯一性:
* 1).hashCode();
* 2).equals();
* |--TreeSet:
* 1.树结构存储;验证唯一性:如果"比较器"的"比较的方法"返回0,则认为是相同对象;
* 2.树结构的特点:对元素进行排序:
* 1).自然排序:
* 1.存储的对象,必须实现:Comparable接口
* 2.重写compareTo()方法;
* 2).比较器排序:
* 1.存储的对象无需实现任何接口;
* 2.需要自定义一个比较器,实现:Comparator接口,重写compare()方法;
* 3.构造TreeSet时,为其传递一个"比较器对象"
* 说明:第2,3步,我们一般使用"匿名内部类"实现;
* |--LinkedHashSet:有序的集合
* 1.链表、哈希表实现;
* 2.链表:保证元素有序;
* 哈希表:保证元素的唯一性;
10、产生10个1到20之间的随机数要求随机数不能重复(练习)
* 产生10个1-20之间的随机数要求随机数不能重复
* 1.利用HashSet不存储重复元素的特性;
* 2.定义一个无限循环;
* 3.每次循环生成一个随机数;
* 4.将这个随机数直接存储到集合中;
* 5.如果集合的长度达到10,就结束循环;
public class Demo {
public static void main(String[] args) {
//1.定义一个集合
TreeSet<Integer> set = new TreeSet<>();
//2.随机数的类
Random rdm = new Random();
//3.无限循环
while(set.size() < 10){
int num = rdm.nextInt(20) + 1;
set.add(num);
}
//打印
for(Integer num : set){
System.out.println(num);
}
}
}

11、按总分排序(练习)
import java.util.Comparator;
import java.util.Scanner;
import java.util.TreeSet;
class Student {
private String name;
private int chineseScore;
private int mathScore;
private int englishScore;
public Student(String name, int chineseScore, int mathScore,
int englishScore) {
super();
this.name = name;
this.chineseScore = chineseScore;
this.mathScore = mathScore;
this.englishScore = englishScore;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getChineseScore() {
return chineseScore;
}
public void setChineseScore(int chineseScore) {
this.chineseScore = chineseScore;
}
public int getMathScore() {
return mathScore;
}
public void setMathScore(int mathScore) {
this.mathScore = mathScore;
}
public int getEnglishScore() {
return englishScore;
}
public void setEnglishScore(int englishScore) {
this.englishScore = englishScore;
}
//获取总分的方法
public int getSum(){
return this.chineseScore + this.mathScore + this.englishScore;
}
}
public class Demo {
public static void main(String[] args) {
TreeSet<Student> stuSet = new TreeSet<>(new Comparator<Student>(){
@Override
public int compare(Student o1, Student o2) {
//1.按总分升序排序
int n1 = o1.getSum() - o2.getSum();
//2.如果总分相同,判断按语文排序
int n2 = (n1 == 0 ? o1.getChineseScore() - o2.getChineseScore() : n1);
//3.如果语文相同,比较数学
int n3 = (n2 == 0 ? o1.getMathScore() - o2.getMathScore() : n2);
//4.如果数学相同,比较姓名
int n4 = (n3 == 0 ? o1.getName().compareTo(o2.getName()) : n3);
return n4;
}});
Scanner sc = new Scanner(System.in);
System.out.println("请输入学员的数量:");
int count = sc.nextInt();
for(int i = 1 ; i <= count ; i++){
System.out.println("请输入第:" + i + " 名学员的信息:");
System.out.println("姓名:");
String name = sc.next();
System.out.println("语文成绩:");
int cScore = sc.nextInt();
System.out.println("数学成绩:");
int mScore = sc.nextInt();
System.out.println("英语成绩:");
int eScore = sc.nextInt();
Student stu = new Student(name,cScore,mScore,eScore);
stuSet.add(stu);
}
System.out.println("排序后的结果");
System.out.println("\t姓名\t语文\t数学\t英语\t\t总分");
for(Student stu : stuSet){
System.out.println("\t" + stu.getName() +
"\t" + stu.getChineseScore() +
"\t" + stu.getMathScore() +
"\t" + stu.getEnglishScore() +
<span style="white-space:pre"></span>"\t\t" + stu.getSum());
}
}
}

二、Map接口
1、Map集合
* Collection(接口):单列集合
* |--List(接口):
* |--Set(接口):
* Map(接口):双列集合:键、值对存储
* |--HashMap:
* |--LinkedHashMap:
* |--TreeMap:
public class Demo {
public static void main(String[] args) {
Map<String,String> map = new HashMap<>();
map.put("it001", "刘德华");
map.put("it002", "张学友");
map.put("it003", "章子怡");
map.put("it004", "汪峰");
System.out.println(map);
}
}
2、Map集合_的基本功能
* Map集合的基本功能:
* 1.put(K key ,V value):添加元素;
* 2.clear():清空集合
* 3.remove(Object key):移除键key
* 4.containsKey(Object key):判断键key在集合中是否存在;
* 5.boolean containsValue(Object value):判断值value,在集合中是否存在;
* 6.isEmpty():判断集合是否为空;
* 注意:关于put()方法的返回值:
* 1.如果put()进去一个未曾添加的一个新键值对,那么返回null;
* 2.如果put()进去一个已经存在的键,那么用"新值"替换"原值";
public class Demo {
public static void main(String[] args) {
Map<String,String> map = new HashMap<>();
System.out.println(map.put("it001", "刘德华"));
System.out.println(map.put("it002", "张学友"));
System.out.println(map.put("it003", "章子怡"));
System.out.println(map.put("it004", "撒贝宁"));
System.out.println(map.put("it004", "汪峰"));
//清空集合
//map.clear();
//移除it004
//System.out.println("移除it005结果:" + map.remove("it005"));
//System.out.println("移除it004结果:" + map.remove("it004"));
//判断键it004是否存在
System.out.println("判断键it004是否存在:" + map.containsKey("it004"));
System.out.println("判断键it005是否存在:" + map.containsKey("it005"));
System.out.println("判断章子怡是否存在:" + map.containsValue("章子怡"));
System.out.println("判断汪峰是否存在:" + map.containsValue("汪峰"));
System.out.println("集合是否为空: " + map.isEmpty());
System.out.println(map);
}
}

3、Map集合_的获取功能
* Map集合的获取功能测试
* V get(Object key):用一个key查找对应的值;
* Set<K> keySet():返回所有键的Set集合;
* Collection<V> values():获取所有value的集合;
* Set<Map.Entry<K,V>> entrySet():获取所有"键值对对象";
* Map的遍历方式只有两种:
* 1.keySet:先获取所有键的集合,然后遍历键的集合,根据每个键去获取值;
* 2.entrySet:获取所有的"键值对对象"的集合,然后遍历;
public class Demo {
public static void main(String[] args) {
Map<String,String> map = new HashMap<>();
map.put("it001", "刘德华");
map.put("it002", "张学友");
map.put("it003", "章子怡");
map.put("it004", "撒贝宁");
System.out.println("获取it004对应的值:" + map.get("it004"));
//遍历Map集合的一种方式:
Set<String> keys = map.keySet();
for(String key : keys){
System.out.println(key + "----" + map.get(key));
}
System.out.println("------------Map.Entry遍历--------------");
//遍历Map集合的第二种方式:
Set<Map.Entry<String,String>> entrySet = map.entrySet();
for(Map.Entry<String,String> en : entrySet){
System.out.println(en.getKey() + "---" + en.getValue());
}
}
}

4、键是String值是Student的案例
* 存储一个班学员的信息:
* 学员编号 学员信息
* it001 new Student("刘亦菲",18);
* it002 new Student("杨颖",17);
* it003 new Student("高圆圆",19);
class Student {
private String name;
private int age;
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;
}
}
public class Demo {
public static void main(String[] args) {
Map<String,Student> map = new HashMap<>();
map.put("it001", new Student("刘亦菲",18));
map.put("it002", new Student("杨颖",17));
map.put("it003", new Student("高圆圆",19));
//遍历
Set<String> ks = map.keySet();
for(String k : ks){
Student stu = map.get(k);
System.out.println(k + "---" + stu.getName() + "," + stu.getAge());
}
}
}

5、键是Student值是String的案例
* 键是Student值是String的案例
* 注意:当我们自定义类做"键"时,如果需要判断出重复的键,需要重写:hashCode()和equals()方法;
* new Student("刘亦菲",18) "it001"
* new Student("杨颖",17) "it002"
* new Student("高圆圆",19) "it003"
public class Student {
private String name;
private int age;
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;
}
@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;
}
}
public class Demo {
public static void main(String[] args) {
Map<Student,String> map = new HashMap<>();
map.put(new Student("刘亦菲",18), "it001");
map.put(new Student("杨颖",17), "it002");
map.put(new Student("高圆圆",19), "it003");
map.put(new Student("高圆圆",19), "it003");
Set<Student> ks = map.keySet();
for(Student stu : ks){
System.out.println("键:" + stu.getName() + "," + stu.getAge() + "---值:" + map.get(stu));
}
}
}

6、LinkedHashMap的概述和使用
* LinkedHashMap的概述和使用
* 内部使用哈希表和链表
* Map的数据结构都是引用在"键"上;
* 1.有序的双列集合
public class Demo {
public static void main(String[] args) {
LinkedHashMap<String,String> map = new LinkedHashMap<>();
map.put("it001", "刘德华");
map.put("it002","张学友");
map.put("it003", "黎明");
map.put("it004", "郭富城");
//遍历
//1.keySet():
//2.entrySet():
Set<String> keySet = map.keySet();
for(String key : keySet){
System.out.println(key + "--" + map.get(key));
}
}
}

7、TreeMap_键是String值是String的案例
* TreeMap需要对"键"进行排序,排序的方式:
* 1.自然排序:
* 1).作为"键"的对象,一定要实现:Comparable接口
* 2).重写compreTo()方法;
* 2.比较器排序:
* 1).自定义比较器对象,要实现:Comparator接口;
* 2).重写compare()方法;
* 3).在实例化TreeMap时,将自定义的比较器对象传入TreeMap的构造方法;
public class Demo {
public static void main(String[] args) {
TreeMap<String,String> map = new TreeMap<>();
map.put("it002", "张学友");
map.put("it004", "章子怡");
map.put("it001", "撒贝宁");
map.put("it003", "刘德华");
//使用entrySet()遍历
Set<Map.Entry<String,String>> enSet = map.entrySet();
for(Map.Entry<String, String> en : enSet){
System.out.println(en.getKey() + "---" + en.getValue());
}
}
}

8、TreeMap_键是Student值是String的案例
class Student {
String name;
int age;
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
}
public class Demo {
public static void main(String[] args) {
TreeMap<Student,String> map =new TreeMap<>(new Comparator<Student>(){
@Override
public int compare(Student o1, Student o2) {
//1.先按年龄排
int n1 = o1.age - o2.age;
//2.如果年龄相同,按姓名排
int n2 = (n1 == 0 ? o1.name.compareTo(o2.name) : n1);
return n2;
}
});
map.put(new Student("张三",20), "it001");
map.put(new Student("李四",18), "it003");
map.put(new Student("王五",22), "it002");
map.put(new Student("周六",17), "it004");
Set<Student> keySet = map.keySet();
for(Student stu : keySet){
System.out.println(stu.name + "," + stu.age + "---" + map.get(stu));
}
}
}

9、统计字符出现的次数
* "aababcabcdabcde",
* 获取字符串中每一个字母出现的次数要求结果:a(5)b(4)c(3)d(2)e(1)
* 1.字母 + 出现的次数:可以使用双列集合:Map
* 2.因为字母不重复,所以使用字母做键;
* 3.因为需要字母排序,所以使用:TreeMap
public class Demo {
public static void main(String[] args) {
TreeMap<Character,Integer> map = new TreeMap<>();
String str = "aababcafebcdabcefdefg";
for(int i = 0;i < str.length() ; i++){
char c = str.charAt(i);
//先用c 做键,到集合中查找相应的值
Integer value = map.get(c);
//取出的value有两种情况:1.null 2.值
if(value == null){
map.put(c, 1);
}else{
map.put(c, ++value);
}
}
StringBuffer buf = new StringBuffer();
Set<Character> keySet = map.keySet();
for(Character c : keySet){
buf.append(c).append("(").append(map.get(c)).append(")");
}
System.out.println(buf);
}
}

10、HashMap集合嵌套HashMap集合的案例
* 我们要存储两个班的信息:
*
* -----------HashMap--------------
* "20150822"
* ----HashMap----
* "it001","张学友"
* "it002","刘德华"
* "it003","郭峰"
*
* 20150830
* ----HashMap----
* "it001","章子怡"
* "it002","刘亦菲"
* "it003","杨颖"
public class Demo {
public static void main(String[] args) {
HashMap<String,String> map1 = new HashMap<>();
map1.put("it001", "张学友");
map1.put("it002", "刘德华");
map1.put("it003", "郭峰");
HashMap<String,String> map2 = new HashMap<>();
map2.put("it001", "章子怡");
map2.put("it002", "刘亦菲");
map2.put("it003", "杨颖");
HashMap<String,HashMap<String,String>> map = new HashMap<>();
map.put("20150822", map1);
map.put("20150830", map2);
//遍历
Set<String> keySet = map.keySet();
for(String key : keySet){
System.out.println(key);
HashMap<String,String> valueMap = map.get(key);
Set<String> keys = valueMap.keySet();
for(String k : keys){
System.out.println("\t" + k + "," + valueMap.get(k));
}
}
}
}

11、HashMap集合嵌套ArrayList集合的案例
* 案例:记录两个班的学员信息:
*
* ---------HashMap--------------
* 20150822
* ---ArrayList---
* "刘德华"
* "张学友"
* "郭富城"
*
* 20150830
* ---ArrayList---
* "章子怡"
* "刘亦菲"
* "杨颖"
public class Demo {
public static void main(String[] args) {
//1.第一个班的集合
ArrayList<String> class1List = new ArrayList<>();
class1List.add("刘德华");
class1List.add("张学友");
class1List.add("郭富城");
//2.第二个班的集合
ArrayList<String> class2List = new ArrayList<>();
class2List.add("章子怡");
class2List.add("刘亦菲");
class2List.add("杨颖");
//3.记录两个班的集合
HashMap<String,ArrayList<String>> map = new HashMap<>();
map.put("20150822", class1List);
map.put("20150830", class2List);
//遍历
Set<String> keySet = map.keySet();
for(String key : keySet){
System.out.println(key);
ArrayList<String> valueList = map.get(key);
for(String v : valueList){
System.out.println("\t" + v);
}
}
}
}

12、ArrayList集合嵌套HashMap集合的案例
* 记录两个班的信息,不记录班号:
* =======ArrayList=========
* -----HashMap--------
* "it001","刘德华"
* "it002","张学友"
* "it003","郭富城"
* -----HashMap--------
* "it001","章子怡"
* "it002","刘亦菲"
* "it003","杨颖"
public class Demo {
public static void main(String[] args) {
HashMap<String,String> map1 = new HashMap<>();
map1.put("it001", "刘德华");
map1.put("it002", "张学友");
map1.put("it003", "郭富城");
HashMap<String,String> map2 = new HashMap<>();
map2.put("it001", "章子怡");
map2.put("it002", "刘亦菲");
map2.put("it003", "杨颖");
ArrayList<HashMap<String,String>> list = new ArrayList<>();
list.add(map1);
list.add(map2);
for(HashMap<String,String> map : list){
Set<String> keySet = map.keySet();
for(String key : keySet){
System.out.println(key + "," + map.get(key));
}
}
}
}

13、HashMap和Hashtable的区别
* 1.Hashtable:
* 1).从1.0版本开始:
* 2).不能使用null做键或值;
* 3).线程安全的(同步的),效率低
* 2.HashMap:
* 1).从1.2版本开始:
* 2).允许使用null键和null值;
* 3).线程不安全的(非同步的),效率高;
public class Demo {
public static void main(String[] args) {
Hashtable<String,String> table = new Hashtable<>();
//table.put(null, "张三");//运行时异常:空指针
//table.put("it001", null);//运行时异常:空指针
table.put("it001", "张三");//OK的
HashMap<String,String> map = new HashMap<>();
map.put(null, "张三");
map.put("it002", null);
map.put(null, null);
map.put("it003" , null);
Set<String> keySet = map.keySet();
for(String key : keySet){
System.out.println(key + "--" + map.get(key));
}
}
}

三、Collections工具类
1、Collections工具类的使用
* java.util.Collections(工具类):对集合操作的工具类;
* public static <T> void sort(List<T> list):根据元素的自然顺序 对指定列表按升序进行排序。-->compareTo()
* public static <T> int binarySearch(List<?> list,T key):在集合list中查找key:要先排序;
* public static <T> T max(Collection<?> coll):获取集合中的最大元素;
* public static void reverse(List<?> list):反转集合内的所有元素;
* public static void shuffle(List<?> list):打乱集合中所有元素的顺序;
public class Demo {
public static void main(String[] args) {
List<String> arrayList = new ArrayList<>();
arrayList.add("ccc");
arrayList.add("bbb");
arrayList.add("aaa");
arrayList.add("ddd");
System.out.println(arrayList);
//排序
Collections.sort(arrayList);
System.out.println(arrayList);
//查找元素"ddd"
System.out.println("查找元素ddd: " + Collections.binarySearch(arrayList, "ddd"));
System.out.println("集合中的最大元素:" + Collections.max(arrayList));
Collections.reverse(arrayList);
System.out.println("反转集合内的元素:" + arrayList);
Collections.shuffle(arrayList);
System.out.println("打乱集合内的元素的顺序:" + arrayList);
}
}

2、ArrayList存储自定义对象并排序案例
public class Student implements Comparable{
String name;
int age;
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
@Override
public int compareTo(Object o) {
Student stu = (Student)o;
int n1 = stu.age - this.age;
int n2 = (n1 == 0 ? this.name.compareTo(stu.name) : n1);
return n2;
}
}
public class Demo {
public static void main(String[] args) {
ArrayList<Student> stuList = new ArrayList<>();
stuList.add(new Student("刘德华",20));
stuList.add(new Student("张学友",22));
stuList.add(new Student("章子怡",18));
stuList.add(new Student("杨颖",16));
Collections.sort(stuList);
for(Student stu : stuList){
System.out.println(stu.name + "--" + stu.age);
}
}
}

3、模拟斗地主洗牌和发牌
* 模拟斗地主洗牌和发牌:
* 1.封装一副牌:
* 2.洗牌:
* 3.发牌:
* 4.看牌:
public class Demo {
public static void main(String[] args) {
//1.封装一副牌
String[] color ={"♥","♠","♦","♣"};
String[] number = {"2","3","4","5","6","7","8","9","10","J","Q","K","A"};
String[] pokerArray = new String[54];
int index = 0;
for(String c : color){
for(String n : number){
pokerArray[index++] = c + n;
}
}
//小王
pokerArray[index++] = "小王";
//大王
pokerArray[index] = "大王";
//System.out.println(Arrays.toString(pokerArray));
//2.洗牌
//将数组转换为集合
List<String> pokerList = Arrays.asList(pokerArray);
Collections.shuffle(pokerList);
//System.out.println("洗完牌后:" + pokerList);
//3.发牌
ArrayList<String> user1List = new ArrayList<>();
ArrayList<String> user2List = new ArrayList<>();
ArrayList<String> user3List = new ArrayList<>();
ArrayList<String> dipaiList = new ArrayList<>();
//遍历集合,发牌
for(int i = 0;i < pokerList.size() ; i++){
if(i >= pokerList.size() - 3){
dipaiList.add(pokerList.get(i));
}else{
if(i % 3 == 0){
user1List.add(pokerList.get(i));
}else if (i % 3 == 1){
user2List.add(pokerList.get(i));
}else if( i % 3 == 2){
user3List.add(pokerList.get(i));
}
}
}
System.out.println("奥巴马:" + user1List);
System.out.println("普京:" + user2List);
System.out.println("朴槿惠:" + user3List);
System.out.println("底牌:" + dipaiList);
}
}

4、模拟斗地主洗牌和发牌_对牌进行排序
public class Demo {
public static void main(String[] args) {
//1.封装一副牌
String[] color ={"♥","♠","♦","♣"};
String[] number = {"3","4","5","6","7","8","9","10","J","Q","K","A","2"};
HashMap<Integer,String> pokerMap = new HashMap<>();//牌面和编号的映射关系
ArrayList<Integer> pokerIndex = new ArrayList<>();
int index = 1;
for(String n : number){
for(String c : color){
pokerMap.put(index, c + n);
pokerIndex.add(index);
index++;
}
}
pokerMap.put(index, "小王");
pokerIndex.add(index);
index++;
pokerMap.put(index, "大王");
pokerIndex.add(index);
//洗牌:洗的编号
Collections.shuffle(pokerIndex);
//发牌:发编号
TreeSet<Integer> user1Set = new TreeSet<>();
TreeSet<Integer> user2Set = new TreeSet<>();
TreeSet<Integer> user3Set = new TreeSet<>();
TreeSet<Integer> dipaiSet = new TreeSet<>();
for(int i = 0 ;i < pokerIndex.size() ; i++){
if(i >= pokerIndex.size() - 3){
dipaiSet.add(pokerIndex.get(i));
}else{
if(i % 3 == 0){
user1Set.add(pokerIndex.get(i));
}else if(i % 3 == 1){
user2Set.add(pokerIndex.get(i));
}else if(i % 3 == 2){
user3Set.add(pokerIndex.get(i));
}
}
}
//看牌
System.out.print("奥巴马:【");
for(Integer n : user1Set){
System.out.print(pokerMap.get(n) + ", ");
}
System.out.println("】");
System.out.println();
System.out.print("拉登:【");
for(Integer n : user2Set){
System.out.print(pokerMap.get(n) + ", ");
}
System.out.println("】");
System.out.println();
System.out.print("普京:【");
for(Integer n : user3Set){
System.out.print(pokerMap.get(n) + ", ");
}
System.out.println("】");
System.out.println();
System.out.print("底牌:【");
for(Integer n : dipaiSet){
System.out.print(pokerMap.get(n) + ", ");
}
System.out.println("】");
System.out.println();
}
}

总结:
Collection(接口):单列
|--List(接口):1.有序的;2.可以存储重复值;
|--ArrayList(类):数组实现;不同步的,效率高;
|--Vector(类):数组实现;同步的,效率低;
|--LinkedList(类):链表实现;不同步的,效率高;
|--Set(接口):1.无序的;2.不能存储重复值;(全是不同步的)
|--HashSet(类):哈希表实现;验证重复:hashCode()和equals()
|--LinkedHashSet(类):链表,哈希表实现;链表:有序;哈希表:唯一
|--TreeSet(类):树结构;唯一性验证:比较的方法compareTo()或者compare()方法如果返回0,就不存;
对元素排序的:
1.自然排序:
1).存储的对象必须实现Comparable接口
2).重写compareTo()方法;
2.比较器排序:
1).自定义比较器,实现Comparator接口
2).重写compare()方法;
3).实例化TreeSet对象时,传递自定义比较器的对象;(一般我们使用匿名内部类的方式)
Map(接口):双列集合
|--HashMap(类):"键"使用的"哈希表"结构;
|--LinkedHashMap(类):"键"使用的"链表、哈希表"结构;
|--TreeMap(类):"键"使用的"树"结构;
|--Hashtable(类):哈希表。同步的,效率低;
数据结构:
栈:后进先出;
队列:先进先出;
数组:查询快;增、删慢;
链表:查询慢;增、删快;
哈希表:综合了数组和链表的优点,查询、增、删都快。效率取决于"哈希算法";
树:对元素排序。
我们该怎样选择集合呢?
1.单列or双列:
1):单列:Collection:-->有序or无序
1)有序:List:-->是否经常增、删?
1).是:LinkedList:
2).否:ArrayList_or_Vector:是否多线程访问:
1)是:Vector
2)否:ArrayList
2)无序:Set:-->是否要排序?
1).是:TreeSet
2).否:HashSet
LinkedHashSet和 ArrayList:建议使用ArrayList
2):双列:Map:-->是否排序?
1).是:TreeMap
2).否:HashMap
遍历集合的方式:
Collection:
1).toArray():
2).iterator():
3).增强for():(最常用)
|--List:
4).get():
5).ListIterator():
|--Set:
(无)
Map:
1).keySet:
2).entrySet: