大数据Java基础DAY21——集合完结(Map接口,HashMap,Linked Hash Map,TreeMap,Collections类)
Posted 16年义务教育
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了大数据Java基础DAY21——集合完结(Map接口,HashMap,Linked Hash Map,TreeMap,Collections类)相关的知识,希望对你有一定的参考价值。
目录
Map接口和Collection接口的不同 ( Collection接口 )
Map接口
Map接口概述
a.将键映射到值的对象
b.一个映射不能包含重复的键
c.每个键最多只能映射到一个值
Map接口和Collection接口的不同 ( Collection接口 )
a.Map是双列的,Collection是单列的
b.Map的键唯一,Collection的子体系Set是唯一的
c.Map集合的数据结构值针对键有效,跟值无关 Collection集合的数据结构是针对元素有效
Map接口成员方法
添加功能
V put(K key,V value) 将指定的值与该映射中的指定键相关联
import java.util.HashMap;
import java.util.Map;
public class MapTest1
public static void main(String[] args)
//Map是一个接口,不能实例化,借助子类HashMap来实例化
Map<String, String> map = new HashMap<>();
//V put(K key,V value) 将指定的值与该映射中的指定键相关联
map.put("充电器","手机");
map.put("电脑","鼠标");
System.out.println(map.put("电脑","键盘")); //如果插入的键一样,值会被覆盖,返回的是被覆盖的值
System.out.println(map);
删除功能
V remove(Object key) 如果存在(从可选操作),从该Map中删除一个键的映射
map.remove("电脑");
void clear() 从该Map中删除所有的映射(可选操纵)
map.clear();
判断功能
boolean containsKey(Object key) 如果此映射包含指定键的映射,则返回true
//boolean containsKey(Object key) 如果此映射包含指定键的映射,则返回true
System.out.println(map);
System.out.println(map.containsKey("充电器"));
boolean containsValue(Object value) 如果此Map将一个或多个键映射到指定的值,则返回true。
map.containsValue("手机")
boolean isEmpty() 如果此Map不包含键值映射,则返回true
map.isEmpty();//判断是否有键值对,有返回true,无false
获取功能
V get(Object key) 返回指定键所映射的值,或null如果此映射包含该键的映射
System.out.println(map.get("充电器"));
Set<K> keySet() 返回此Map中包含的键的Set试图
Set<String> set=map.keySet();
//遍历
for (String s:set)
System.out.println(s);
Collection<V> values() 返回此Map中包含的值的Collection视图
//Collection<V> values() 返回此Map中包含的值的Collection视图
Collection<String> value =map.values();
for (String s :value)
System.out.println(s);
Set<Map.Entry<K,V>> entrySet() 获取Map中所有的元素,元素的类组成是由一个键和一个值组成
//Set<Map.Entry<K,V>> entrySet() 获取Map中所有的元素,元素的类组成是由一个键和一个值组成
Set<Map.Entry<String, String>> entries = map.entrySet();
for (Map.Entry<String, String> s :entries)
System.out.println(s);
长度功能
int size() 返回此Map中键值映射的数量
int size = map.size();
System.out.println(size); //结果为2,取决于里面有多少个键值对
Map集合遍历
方式1:根据键找值
获取所有键的集合
遍历键的集合,获取到每一个键
根据键找值
例:
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class MapTest2
public static void main(String[] args)
//创建集合对象
Map<Integer, String> map = new HashMap<>();
//向集合添加元素
map.put(11,"qew");
map.put(23,"qew");
map.put(33,"sfs");
map.put(22,"asf");
//遍历
Set<Integer> set = map.keySet(); //获取到每一个键
for (Integer s:set)
String s1 = map.get(s); //获取到每一个键对应的值
System.out.println(s+":"+s1);
方式2:根据键值对对象找键和值
获取所有键值对对象的集合
遍历键值对对象的集合,获取到每一个键值对对象
根据键值对对象找键和值
//创建集合对象
Map<Integer, String> map = new HashMap<>();
//向集合添加元素
map.put(4,"rte");
map.put(23,"d234");
map.put(5,"e121");
map.put(75,"qee");
map.put(22,"fa");
//遍历
Set<Map.Entry<Integer, String>> entries = map.entrySet(); //获取到键值对集合
for (Map.Entry<Integer, String> s:entries)
Integer key = s.getKey(); //获取到键值对对应的键
String value = s.getValue(); //获取到键值对对应的值
System.out.println(key+":"+value);
HashMap类
HashMap类概述
键是哈希表结构,可以保证键的唯一性
HashMap案例
HashMap<String,String>
HashMap<Integer,String>
上面两个跟Map集合中的案例一样,重点说下面的
HashMap<String,Student>
首先封装一个学生类
public class Student
private String name;
private int age;
public Student()
public Student(String name, int age)
this.name = name;
this.age = age;
public String getName()
return name;
public int getAge()
return age;
public void setName(String name)
this.name = name;
public void setAge(int age)
this.age = age;
@Override
public String toString()
return "Student" +
"name='" + name + '\\'' +
", age=" + age +
'';
在创建集合添加学生对象测试
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class HashMapTest1
public static void main(String[] args)
//创建集合对象
HashMap<String, Student> hashMap = new HashMap<>();
//创建学生对象
Student s1 =new Student("student1",23);
Student s2 =new Student("student2",14);
Student s3 =new Student("student3",17);
Student s4 =new Student("student4",25);
Student s5 =new Student("student5",23);
//向集合添加元素
hashMap.put("sas",s1);
hashMap.put("qwe",s2);
hashMap.put("fsa",s3);
hashMap.put("ddd",s4);
hashMap.put("qca",s5);
//遍历
Set<Map.Entry<String, Student>> entries = hashMap.entrySet();
for (Map.Entry<String, Student> s:entries)
String key = s.getKey();
Student value = s.getValue(); //也可以调用student中的get方法把名字,年龄获取出来遍历
System.out.println(key+":"+value);
HashMap<Student,String>
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class HashMapTest2
public static void main(String[] args)
//创建集合对象
HashMap<Student, String> hashMap = new HashMap<>();
//创建学生对象
Student s1=new Student("qa",23);
Student s2=new Student("ea",25);
Student s3=new Student("fa",22);
Student s4=new Student("da",15);
Student s5=new Student("qa",23);
//向集合添加元素
hashMap.put(s1,"111");
hashMap.put(s2,"222");
hashMap.put(s3,"333");
hashMap.put(s4,"444");
hashMap.put(s5,"555");
//遍历
Set<Map.Entry<Student, String>> entries = hashMap.entrySet();
for (Map.Entry<Student, String> s:entries)
Student key = s.getKey();
String value = s.getValue();
System.out.println(key+":"+value);
从输出结果能发现,key有重复的对象,这违背了map中键是唯一的定义,原因是添加元素的put方法的源码涉及到hashCode()方法和equals()方法来判断元素是否重复(在Hash Set类中说过,Set接口 ),而我们创建做为key的自定义Student类中没有重写hashCode()方法和equals()方法,所以只能调用Object类中的equals方法来比较地址值,每一个学生对象都是new出来的,地址值固然不一样。
解决方法:在Student类中重写hashCode()方法和equals()方法
@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);
这样key就不会重复了
LinkedHashMap类
LinkedHashMap类概述
a.继承自HashMap类,实现了Map接口
b.Map 接口的哈希表和链接列表实现,具有可预知的迭代顺序。
哈希表保证元素的唯一,保证key是唯一
链表保证有序 (存储和取出的顺序一致)
例:
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
public class LinkedHashMapTest1
public static void main(String[] args)
//创建集合对象
LinkedHashMap<String, String> map = new LinkedHashMap<>();
//向集合添加元素
map.put("s1","qqw");
map.put("s2","q232");
map.put("s3","q211");
map.put("s4","d23");
map.put("s1","dsa");
//遍历
Set<Map.Entry<String, String>> entries = map.entrySet();
for (Map.Entry<String, String> s:entries)
String key = s.getKey();
String value = s.getValue();
System.out.println(key+":"+value);
从结果可以看出重复的key的值被覆盖了,并且输出的顺序就是存放的顺序
TreeMap类
TreeMap类概述
键是红黑树结构,可以保证键的排序和唯一性
TreeMap案例
HashMap<String,String>
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
public class TreeMapTest1
public static void main(String[] args)
//创建集合对象
TreeMap<String, String> map = new TreeMap<>();
//向集合添加元素
map.put("HashSet","Set接口");
map.put("TreeSet","Set接口");
map.put("LinkedHashSet","Set接口");
map.put("HashMap","Map接口");
map.put("HashMap","Map接口");
//遍历
Set<Map.Entry<String, String>> entries = map.entrySet();
for (Map.Entry<String, String> s:entries)
String key = s.getKey();
String value = s.getValue();
System.out.println(key+":"+value);
可以看出结果去重了,而且按key中的首字母排序,因为无参构造走的是自然排序,String类实现了Comparable接口,重写了ComparaTo方法( TreeSet类中有说过),String中ComparaTo方法比较ASCII码值,所以按首字母排序。
HashMap<Student,String>
方法一:
首先封装一个学生类2,跟学生类1一样的(不加hashCode方法和equals方法)
再创建集合
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
public class TreeMapTest2
public static void main(String[] args)
//创建集合对象
TreeMap<Student2, String> map = new TreeMap<>();
//创建学生对象
Student2 s1 =new Student2("student1",23);
Student2 s2 =new Student2("student2",22);
Student2 s3 =new Student2("student3",23);
Student2 s4 =new Student2("student1",23);
Student2 s5 =new Student2("student4",20);
//向集合添加元素
map.put(s1,"q111");
map.put(s2,"w111");
map.put(s3,"e111");
map.put(s4,"q111");
map.put(s5,"t111");
//遍历
Set<Map.Entry<Student2, String>> entries = map.entrySet();
for (Map.Entry<Student2, String> s:entries)
Student2 key = s.getKey();
String value = s.getValue();
System.out.println(key+":"+value);
然后到这一步你会报错,因为这里走的还是无参构造,自然排序,所创建的Stuent2类没有实现Comparable接口,而自然排序这个接口中有一个向下转型,所以会类型转换异常报错(具体跟TreeSet类中一 样 Set接口 )
解决方法:创建的Student2类需实现Comparable接口,并重写接口的ComparaTo方法,在其中自定义排序方法
public class Student2 implements Comparable<Student2>
private String name;
private int age;
public Student2()
public Student2(String name, int age)
this.name = name;
this.age = age;
public String getName()
return name;
public int getAge()
return age;
public void setName(String name)
this.name = name;
public void setAge(int age)
this.age = age;
@Override
public String toString()
return "Student" +
"name='" + name + '\\'' +
", age=" + age +
'';
@Override
public int compareTo(Student2 o)
//比较年龄是否一样
int i1=o.age-this.age;
//年龄一样,姓名不一定一样
int i2= i1==0 ? o.name.compareTo(this.name):i1;
return i2;
可以看出结果去重且按自定义方法排序(按年龄)
方法二:
当然,如果你不想改动学生类,那就走有参构造方法,也就是比较器排序
此时学生类是最初的封装状态,不需要修改,只需要在创建对象时修改就可以了,这里采用匿名内部类的方式,直接在创建对象时实现Comparato接口。
//创建集合对象
TreeMap<Student2, String> map = new TreeMap<>(new Comparator<Student2>() //匿名内部类
@Override
public int compare(Student2 o1, Student2 o2)
//比较年龄是否一样
int i1 = o1.getAge() - o2.getAge();
//年龄一样,姓名不一定一样
int i2 = i1 == 0 ? o1.getName().compareTo(o2.getName()) : i1;
return i2;
);
Map集合练习案例
例1:"aababcabcdabcde",获取字符串中每一个字母出现的次数要求结果:a(5)b(4)c(3)d(2)e(1)
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
public class MapTest4
public static void main(String[] args)
//创建字符串对象
String s="aababcabcdabcde";
//创建集合对象
TreeMap<Character, Integer> map = new TreeMap<>();
char[] chars = s.toCharArray(); //转成字符数组
//遍历字符数组
for (Character c : chars)
Integer integer = map.get(c); //用每一个字符当作键去找值
if (integer == null) //如果输出值为null,表示集合中没有这个键,添加这个键并赋值1;
map.put(c, 1);
else //如果输出不为null,表示集合中有这个键,赋值返回的值value+1,返回覆盖到集合中
integer++;
map.put(c, integer);
//遍历集合
Set<Map.Entry<Character, Integer>> entries = map.entrySet();
for (Map.Entry<Character, Integer> e:entries)
Character key = e.getKey();
Integer value = e.getValue();
System.out.print(key+"("+value+")");
例2:ArrayList集合嵌套HashMap集合
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class MapTest5
public static void main(String[] args)
//创建ArrayList集合对象
ArrayList<HashMap<String, String>> list = new ArrayList<>();
//创建2个HashMap集合,并添加元素
HashMap<String, String> map1 = new HashMap<>();
map1.put("user1","qwq");
map1.put("user2","q33q");
HashMap<String, String> map2 = new HashMap<>();
map2.put("user3","q3we");
map2.put("user4","aa");
//把HashMap集合添加进入ArrayList集合
list.add(map1);
list.add(map2);
//遍历ArrayList集合
for (HashMap<String, String> s:list)
//遍历HashMap集合
Set<Map.Entry<String, String>> entries = s.entrySet();
for (Map.Entry<String, String> m:entries)
String key = m.getKey();
String value = m.getValue();
System.out.println(key+":"+value);
HashMap与Hash table的区别
a.Hash Map和Hash table它们存储的都是一个个的键值对
b.Hash Map中允许key,value为null,而Hash table不允许
c.Hashtable是线程安全的,HashMap是不安全的
Collections类
Collections类概述
针对集合操作 的工具类
Collections类和Collection的区别
a.Collection是单列集合的顶层接口,有两大子类接口:List接口和Set接口
b.Collections是一个针对于集合操作的工具类,可以对集合进行排序,还有查找(二分查找)
Collections成员方法
public static <T> void sort(List<T> list) 集合排序
import java.util.ArrayList;
import java.util.Collections;
public class CollectionsTest1
public static void main(String[] args)
//创建集合对象
ArrayList<Integer> list = new ArrayList<>();
//向集合添加元素
list.add(54);
list.add(23);
list.add(123);
list.add(42);
list.add(32);
list.add(24);
//public static <T> void sort(List<T> list) 排序
System.out.println("原集合:"+list);
Collections.sort(list);
System.out.println("排序后:"+list);
public static <T> int binarySearch(List<?> list,T key) 二分查找,返回索引
System.out.println("原集合:"+list);
int i = Collections.binarySearch(list, 123);
System.out.println(i);
public static <T> T max(Collection<?> coll) 集合中最大值
Integer max = Collections.max(list);
System.out.println(max); //123
public static void reverse(List<?> list) 反转
System.out.println("原集合:"+list);
Collections.reverse(list);
System.out.println("反转后:"+list);
public static void shuffle(List<?> list) 随机置换(随机排序)
System.out.println("原集合:"+list);
Collections.shuffle(list);
System.out.println("随机置换后:"+list);
Collections中的方法能线程不安全的集合变成安全的
例: static <T> List<T> synchronizedList(List<T> list) (还有很多,不一一举例了)
返回由指定列表支持的同步(线程安全)列表。
List<Integer> list1 = Collections.synchronizedList(list);
System.out.println(list);
System.out.println(list1);
可以看出两个list和list1是一样的,Collections只是给list套了一层,让它变成安全的,在Vector类中说过虽然Vector是安全的,但Collections工具类比它更好。
以上是关于大数据Java基础DAY21——集合完结(Map接口,HashMap,Linked Hash Map,TreeMap,Collections类)的主要内容,如果未能解决你的问题,请参考以下文章
JAVA零基础小白学习免费教程day14-Set&HashMap