HashMap集合:
HashMap集合本身就基于哈希表,并且可以保证健的唯一性(Map集合针对的都是健有效);
HashMap集合的遍历:
如果集合对象存储的是一个实体类,例如:HashMap<Student,String>,那么这个类中必须重写hashCodehashCode()和equals()两个方法;
原因:哈希表依赖于hashCode()和equals()方法;
举例:
public class HashMapDemo {
public static void main(String[] args) {
//创建HashMap集合对象
HashMap<String, String> map = new HashMap<String,String>();
//添加元素
map.put("it001", "马云") ;
map.put("it003", "马化腾") ;
map.put("it004", "乔布斯") ;
map.put("it001", "裘伯君") ; //wps
map.put("it005", "比尔盖茨");
//遍历元素
//获取所有的键的集合
Set<String> set = map.keySet() ;
for(String key :set) {
String value = map.get(key) ;
System.out.println(key+"---"+value);
}
//如果有添加的元素中的健key相同,那么厚出现的值value会将先出现的值value替换掉
//所以这里会将马云替换成求伯君,但是它的健key不变
//并且输出的元素根据健key有序且唯一
}
}
LinkedHashMap集合:
LinkedHashMap<K,V>:是Map接口基于哈希表和链接列表实现的;
特性:
哈希表保证键的唯一性;
链接列表保证元素有序性(存储和取出一致);
LinkedHashMap集合的遍历:
举例:
public class LinkedHashMapDemo {
public static void main(String[] args) {
LinkedHashMap<String, String> map = new LinkedHashMap<String,String>() ;
//添加元素
map.put("it001", "hello");
map.put("it002", "mysql");
map.put("it003", "world");
map.put("it004", "javaweb");
map.put("it001", "javaee");
Set<String> set = map.keySet() ;
for(String key :set) {
String value = map.get(key) ;
System.out.println(key+"----"+value);
}
}
}
TreeMap集合:
TreeMap基于红黑树结构的Map接口的实现;
TreeMap集合的遍历:
举例:
public class TreeMapDemo {
public static void main(String[] args) {
//创建TreeMap集合对象
TreeMap<String, String> tm = new TreeMap<String,String>() ;
//存储元素
tm.put("hello", "哈喽") ;
tm.put("world", "世界") ;
tm.put("java", "爪哇") ;
tm.put("world", "世界2") ;
tm.put("java", "爪哇2") ;
//遍历
Set<String> set = tm.keySet() ;
for(String key :set) {
String value = tm.get(key) ;
System.out.println(key+"---"+value);
}
}
}
TreeMap存储自定义类型:
主要条件:并且按照年龄从小到大进行排序;
举例:
package org.westos.c;
import java.util.Comparator;
import java.util.Set;
import java.util.TreeMap;
//学生类
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;
}
}
public class TreeMapDemo2 {
public static void main(String[] args) {
//创建一个TreeMap集合,使用比较器排序的方式
//匿名内部类的方式:将年龄进行从小到大排序
TreeMap<Student, String> tm = new TreeMap<Student,String>(new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
//主要条件:年龄从小到大
int num =s1.getAge() -s2.getAge() ;
//年龄相同,不一定姓名一样
int num2 = num ==0 ? s1.getName().compareTo(s2.getName()): num ;
return num2 ;
}
} );
//创建学生对象
Student s1 = new Student("唐伯虎", 28) ;
Student s2 = new Student("杜甫", 35) ;
Student s3 = new Student("李白", 40) ;
Student s4 = new Student("李清照", 32) ;
Student s5 = new Student("唐伯虎", 28) ;
Student s6 = new Student("苏轼", 35) ;
//添加到集合中
tm.put(s1, "宋代") ;
tm.put(s2, "唐代") ;
tm.put(s3, "唐代") ;
tm.put(s4, "宋代") ;
tm.put(s5, "清代") ;
tm.put(s6, "清代") ;
//遍历
Set<Student> set = tm.keySet() ;
for(Student key :set) {
String value = tm.get(key) ;
System.out.println(key.getName()+"---"+key.getAge()+"---"+value);
}
}
}
练习:HashMap集合里面嵌套ArrayList集合;
package org.westos.d;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Set;
/**
* 需求:
假设HashMap集合的元素是ArrayList。有3个。
每一个ArrayList集合的值是字符串。
元素我已经完成,请遍历。
结果:
三国演义
吕布
周瑜
笑傲江湖
令狐冲
林平之
神雕侠侣
郭靖
杨过
*HashMap<String,ArrayList<String>>
*/
public class HashMapIncludeArrayListTest {
public static void main(String[] args) {
//创建一个大集合对象
HashMap<String, ArrayList<String>> hm = new HashMap<String,ArrayList<String>>() ;
//创建第一个子集合对象
ArrayList<String> array1 = new ArrayList<String>() ;
array1.add("吕布") ;
array1.add("周瑜") ;
//添加到集合中
hm.put("三国演义", array1) ;
//创建第二个子集合对象
ArrayList<String> array2 = new ArrayList<String>() ;
array2.add("令狐冲") ;
array2.add("林平之") ;
//添加到集合中
hm.put("笑傲江湖", array2) ;
//创建第二个子集合对象
ArrayList<String> array3 = new ArrayList<String>() ;
array3.add("郭靖") ;
array3.add("杨过") ;
//添加到集合中
hm.put("神雕侠侣", array3) ;
//遍历
Set<String> set = hm.keySet() ;
for(String key :set) {
System.out.println(key) ;
//通过key获取value
ArrayList<String> value = hm.get(key) ;
for(String s: value) {
System.out.println("\t"+s);
}
}
}
}
练习:HashMap集合嵌套HashMap集合;
package org.westos.d;
import java.util.HashMap;
import java.util.Set;
/**
*HashMap集合嵌套HashMap集合
*
* 西部开源
*
* jc(基础班)
* 高圆圆 27
* 张三 28
*
* jy(就业班)
* 赵又廷 29
* 李四 30
*
* HashMap<String,HashMap<String,Integer>>
*
*/
public class HashMapTest {
public static void main(String[] args) {
//创建一个大集合
HashMap<String,HashMap<String,Integer>> map =
new HashMap<String,HashMap<String,Integer>>();
//创建第一子HashMap集合,存储元素
HashMap<String, Integer> hm1 = new HashMap<String,Integer>() ;
hm1.put("高圆圆", 27) ;
hm1.put("张三", 28) ;
//将第一个子集合添加到大集合中
map.put("jc", hm1) ;
//创建第二个子HashMap集合,存储元素
HashMap<String, Integer> hm2 = new HashMap<String,Integer>() ;
hm2.put("赵又廷", 29) ;
hm2.put("李四",30) ;
//添加到大集合中
map.put("jy", hm2) ;
//遍历
Set<String> mapSet = map.keySet() ;
for(String mapSetKey :mapSet) {
System.out.println(mapSetKey);
//通过大集合的对象,通过键获取值(HashMap集合)
HashMap<String, Integer> mapSetKeyValue = map.get(mapSetKey) ;
//获取所有的键的集合
Set<String> mapSetKeyValueKey = mapSetKeyValue.keySet() ;
for(String mapSetKeyValueKeyKey :mapSetKeyValueKey) {
Integer mapSetKeyValueKeyKeyValue = mapSetKeyValue.get(mapSetKeyValueKeyKey) ;
System.out.println("\t"+mapSetKeyValueKeyKey+"---"+mapSetKeyValueKeyKeyValue);
}
}
}
}
面试题:
HashMap集合和Hashtable的区别?
共同点:都是map接口的实现类,都是基于哈希表的实现类;
HashMap集合线程不安全的类,不同步,执行效率高(允许键和值是null的);
Hashtable集合线程安全的类,同步,执行效率低(不允许有null键和null值) ;
练习:
package org.westos.d;
import java.util.HashMap;
import java.util.Scanner;
import java.util.Set;
/**
*需求:
* 字符串:比如: aaaaabbbbcccddddee ,最终控制台要出现的结果:a(5)b(4)c(3)d(3)e(2)
*
*思路:
* 1)改进:键盘录入一个字符串
* 2)创建一个HashMap集合key:Character,Value:Integer
* 3)将录入的字符串转换成字符数组
* 4)遍历可以获取每一个字符
*
* 5)将元素添加到对应的HashMap集合中
* 使用的put(key,value): 通过判断值是否null ,如果是null表示第一次存储
* 集合对象.put(ch,1) ;
* 否则,不是null
* Integer那个值++;
* 集合对象.put(ch,变量Integer值) ;
*
* 6)遍历HashMap集合即可
*
*/
public class Test {
public static void main(String[] args) {
//创建键盘录入对象
Scanner sc = new Scanner(System.in);
//接收数据
System.out.println("请输入一个字符串:");
String line = sc.nextLine() ;
//创建一个HashMap集合来存储对应的字符和值
HashMap<Character, Integer> hm = new HashMap<Character,Integer>() ;
//将字符串转换成字符数组
char[] chs = line.toCharArray() ;
//遍历字符数组,获取到每一个字符
for(char ch:chs) {
//获取到每一个字符
Integer i = hm.get(ch) ; //肯定要把值获取到
System.out.println(i);
//通过put方法添加元素,看这个值是否为null
if(i==null) {
//第一次存储
hm.put(ch, 1);
}else {
//不是null,存储了多次
i ++ ;
hm.put(ch, i) ;
}
}
//创建一个字符串缓冲区对象
StringBuilder sb = new StringBuilder() ;
//遍历HashMap集合
Set<Character> set = hm.keySet() ;
for(Character key :set) {
//获取值
Integer value = hm.get(key) ;
sb.append(key).append("(").append(value).append(")") ;
}
String str = sb.toString() ;
System.out.println("str:"+str);
}
}
Collections工具类:
Collection和Collections的区别:Collection:顶层次单列集合的根接口,它是一个集合,是一个接口;
Collections:是针对集合操作的工具类,有一些功能:随机置换,集合里面的二分查找,将集合的元素进行反转;
功能:
public static <T> int binarySearch(List<T> list, T key):集合的二分查找;
static T max(Collection coll):获取集合中的最大值;
public static void reverse(List<?> list):将集合中的元素顺序反转;
public static void shuffle(List<?> list):将集合中的元素打乱;
public static void sort(List<T> list):排序(分为自然排序,选择器排序);
举例:
public class CollectionsDemo {
public static void main(String[] args) {
//定义List集合
List<Integer> array = new ArrayList<Integer>() ;
//添加元素
array.add(55);
array.add(11);
array.add(10);
array.add(20);
array.add(25);
array.add(21);
array.add(29);
//输出当前array集合
System.out.println(array);
//public static void sort(List<T> list):排序(分为自然排序,选择器排序)
Collections.sort(array);
System.out.println(array);
//public static <T> int binarySearch(List<T> list, T key):集合的二分查找
int index = Collections.binarySearch(array,11); //针对集合元素有序
System.out.println("值11的下标为:"+index);
// static T max(Collection coll):获取集合中的最大值
System.out.println("max:"+Collections.max(array));
//public static void reverse(List<?> list):将集合中的元素顺序反转
Collections.reverse(array);
System.out.println(array);
//public static void shuffle(List<?> list):将集合中的元素打乱
Collections.shuffle(array) ;
System.out.println(array);
}
}
Collections工具类中sort方法两种形式的比较:
1> 自然排序:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
class Student implements Comparable<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;
}
//方法重写
@Override
public int compareTo(Student s) {
//主要条件
int num = s.getAge() -this.getAge() ;
int num2= num==0 ?this.getName().compareTo(s.getName()) :num ;
return num2 ;
}
}
public class CollectionsTest {
public static void main(String[] args) {
//自然排序
List<Student> list = new ArrayList<Student> (); //元素可以重复
//创建学生对象
Student s1 = new Student("高圆圆", 28);
Student s2 = new Student("唐嫣", 28);
Student s3 = new Student("刘诗诗", 28);
Student s4 = new Student("文章", 30);
Student s5 = new Student("马伊琍", 39);
Student s6 = new Student("高圆圆", 28);
//添加到集合中
list.add(s1) ;
list.add(s2) ;
list.add(s3) ;
list.add(s4) ;
list.add(s5) ;
list.add(s6) ;
for(Student s: list) {
System.out.println(s.getName()+"---"+s.getAge());
}
}
}
2>
选择器排序:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
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;
}
}
public class CollectionsTest {
public static void main(String[] args) {
List<Student> list = new ArrayList<Student> (); //元素可以重复
//创建学生对象
Student s1 = new Student("高圆圆", 28);
Student s2 = new Student("唐嫣", 28);
Student s3 = new Student("刘诗诗", 28);
Student s4 = new Student("文章", 30);
Student s5 = new Student("马伊琍", 39);
Student s6 = new Student("高圆圆", 28);
//添加到集合中
list.add(s1) ;
list.add(s2) ;
list.add(s3) ;
list.add(s4) ;
list.add(s5) ;
list.add(s6) ;
//直接可以使用Collections的sort功能进行条件排序
//比较器排序 (两种方式习惯使用比较器排序)
Collections.sort(list, new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
//主要条件
int num = s1.getAge()-s2.getAge() ;
int num2= num==0 ?s1.getName().compareTo(s2.getName()) :num ;
return num2 ;
}
});
for(Student s: list) {
System.out.println(s.getName()+"---"+s.getAge());
}
}
}
综合练习:模拟斗地主发牌洗牌;
package org.westos.f;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.TreeSet;
/**
* 模拟斗地主的洗牌和发牌,发到每一个手上的牌是保证有序的.. 思考: 1)创建牌盒
* 创建两个集合:HashMap<Integer,String>,ArrayList<Integer> 2)装牌 定义花色数组和点数数组
* 从0开始编号,将编号和编号对应的牌都存储到HashMap集合中,同时往ArrayList单独存储编号 3)洗牌 洗的是编号 4)发牌
* 发的也是编号,为了保证牌有序,集合由TreeSet集合接收 5)看牌 封装功能
*
*/
public class Porker2 {
public static void main(String[] args) {
// 1. 创建两个集合:HashMap<Integer,String>,ArrayList<Integer>
HashMap<Integer, String> hm = new HashMap<Integer, String>();
ArrayList<Integer> array = new ArrayList<Integer>();
// 2.装牌
// 2.1 定义花色数组和点数数组
String[] colors = { "♥", "♠", "♣", "♦" };
String[] numbers = { "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A", "2" };
// 从0开始编号,将编号和编号对应的牌都存储到HashMap集合中,同时往ArrayList单独存储编号
int index = 0;
// 拼接
for (String number : numbers) {
for (String color : colors) {
String poker = color.concat(number);
hm.put(index, poker);
array.add(index);
index++;
}
}
// 装小王和大王
hm.put(index, "小王");
array.add(index);
index++;
hm.put(index, "大王");
array.add(index);
// 不能++了,角标越界
// 洗牌
Collections.shuffle(array);
// System.out.println(array);
// 4)发牌
// 发的也是编号,为了保证牌有序,集合由TreeSet集合接收
TreeSet<Integer> player1 = new TreeSet<Integer>();
TreeSet<Integer> player2 = new TreeSet<Integer>();
TreeSet<Integer> player3 = new TreeSet<Integer>();
TreeSet<Integer> diPai = new TreeSet<Integer>();
//有规律的:遍历ArrayList集合 使用普通for循环,获取到集合的元素
//通过元素 % 人数 = 0 /1/2 /..
//这里的下标存的是打乱顺序以后的每个位置存的数字,这个数字表示打乱顺序之前的下标,每个下标对应一张牌
for (int x = 0; x < array.size(); x++) {
// 获取到每一个元素
if (x >= array.size() - 3) {
diPai.add(array.get(x));
} else if (x % 3 == 0) {
// 玩家1
player1.add(array.get(x));
} else if (x % 3 == 1) {
// 玩家2
player2.add(array.get(x));
} else if (x % 3 == 2) {
player3.add(array.get(x));
}
}
//5)看牌 封装功能
lookPoker("玩家1", player1, hm);
lookPoker("玩家2", player2, hm);
lookPoker("玩家3", player3, hm);
lookPoker("底牌", diPai, hm);
}
public static void lookPoker(String name,TreeSet<Integer> ts,
HashMap<Integer, String> hm) {
System.out.print(name+"的牌是:");
//遍历TreeSet集合获取到每一个编号
for(Integer key :ts) {
//获取到编号,通过编号找牌(在HashMap中找)
String value = hm.get(key) ;
System.out.print(value+" ");
}
System.out.println();
}
}