Map集合不继承Collection,Map是映射键值对,存储对象的时候,一次性存储两个对象,一个作为键(K),一个作为值(V)。
区别:
Collection一个对象存储方式是add
Map 两个对象存储方式 put()
Map集合中,不能出现重复键,每一个键最多只能映射一个值,但是不同键可以有相同值
一、Map中的方法
直接上demo
package map;
/*
* Map中的方法
*/
import java.util.*;
public class MapDemo {
public static void main(String[] args) {
/*method1();
method2();
method3();
method4();*/
method5();
}
/*
* put(k,v)将键值存储到集合中
*/
public static void method(){
Map<String,Integer> map = new HashMap<>();
map.put("a", 1);
map.put("b", 1);
map.put("c", 1);
map.put("d", 4);
map.put("e", 6);
System.out.println(map);
}
/*
* putAll(Map map)把一个集合全部插入另一个集合
*
*/
public static void method1(){
Map<String,Integer> map = new HashMap<>();
map.put("a", 1);
map.put("b", 1);
map.put("c", 1);
Map<String,Integer> map2 = new HashMap<>();
map2.put("e", 2);
map2.put("f", 3);
map2.put("g", 4);
map.putAll(map2);
System.out.println(map);
}
/*
* V get(Key) 传递一个键,返回键对应的值,如果此键不存在,返回为空
*/
public static void method2(){
Map<String,Integer> map = new HashMap<>();
map.put("a", 234);
map.put("b", 1);
map.put("c", 1);
System.out.println(map.get("z"));
}
/*
* void clear() 清除所有对象
* void isEmpty() 判断是为空
* int size() 返回映射关系对的个数
* boolean containsKey(Key) 判断键是否存在,存在返回真,否则返回假
* boolean containsValue(Value) 同理判断值是否存在,存在返回真,不存在返回假
*/
public static void method3(){
Map<String,Integer> map = new HashMap<>();
map.put("a", 1);
map.put("b", 123);
map.put("c", 124);
System.out.println(map.size());
System.out.println(map.containsKey("A"));
//自动装箱,会调用equals判断,所以为真
System.out.println(map.containsValue(new Integer(124)));
map.clear();
System.out.println(map.isEmpty());
}
/*
* V remove(K)
* 移除指定的键值对,传递键,返回值
* 没有移除成功返回null
*/
public static void method4(){
Map<String,Integer> map = new HashMap<>();
map.put("a", 1);
map.put("b", 123);
map.put("c", 124);
System.out.println(map.remove("a"));
System.out.println(map);
}
/*
* Collection<V> values()将Map中的所有值,存储到Collection集合
*/
public static void method5(){
Map<String,Integer> map = new HashMap<>();
map.put("a", 1);
map.put("b", 123);
map.put("c", 124);
Collection<Integer> c = new ArrayList<>();
c = map.values();
System.out.println(map);
System.out.println(c);
}
}
二、Map集合的取出方法
遍历Map集合有两种方法,一种是利用set集合遍历,另外一种是利用内部类原理进行遍历。
Demo
package map;
import java.util.*;
public class MapDemo1 {
/*
* 练习map的两种数据取出方式
*/
public static void main(String[] args) {
method1();
}
/*
* 利用set取出
*/
public static void method(){
Map<String, Integer> map = new HashMap<>();
map.put("a",1);
map.put("b",2);
map.put("c",3);
map.put("d",4);
Set<String> set = map.keySet();
Iterator<String> it = set.iterator();
while(it.hasNext()){
System.out.println(map.get(it.next()));
}
}
/*
* 利用集合的键值对关系对象获取 entrySet,这是一个内部类
*/
public static void method1(){
Map<String, Integer> map = new HashMap<>();
map.put("a",1);
map.put("b",2);
map.put("c",3);
map.put("d",4);
Set<Map.Entry<String, Integer>> o = new HashSet<>();
o = map.entrySet();
Iterator<Map.Entry<String, Integer>> it = o.iterator();
while(it.hasNext()){
//利用多态,next返回实现类对象给接口,可以不用管具体的实现类原理
Map.Entry<String, Integer> entry = it.next();
System.out.println(entry.getKey());
System.out.println(entry.getValue());
}
}
}
三、增强for循环间接遍历map
实现的原理其实和上面的set遍历相似,因为map小的小弟们没有实现接口Iterable,所有不能使用增强for循环,因此map也就没有办法使用增强for循环来遍历了。所以,借助Key的set集合来使用for循环,从而间接遍历可以获取到map集合中的数据,同样,这种方式也可以和map的取出方法一样,有两种写法。
demo
package map;
/*
* for循环遍历间接遍历map
*/
import java.util.*;
public class MapDemo2 {
public static void main(String[] args) {
Map<String, Integer> m = new HashMap<>();
m.put("a", 1);
m.put("b", 2);
m.put("c", 3);
//1.利用普通的set方法for循环遍历,平时中推荐使用
/*for(String s : m.keySet()){
System.out.println(s+"----" + m.get(s));
}*/
//2.同样,使用内部类来进行实现
for(Map.Entry<String, Integer> entry : m.entrySet()){
System.out.println(entry.getKey() + "..."+ entry.getValue());
}
}
}
四、HashMap类
基于哈希表的映射键值对,线程不安全,可以存储null值和null键,没有顺序。要求键是唯一的,对象必须重写hashCode方法和equals方法。
demo
package map;
/*
* HashMap集合的存取自定义对象
* Person是之前自定义的对象
*/
import SetDemo.Person;
import java.util.*;
public class HashMapDemo {
public static void main(String[] args) {
HashMap<Person,String> hm = new HashMap<>();
hm.put(new Person("张三",22), "加拿大");
hm.put(new Person("李四",42), "澳大利亚");
hm.put(new Person("王五",71), "美国");
hm.put(new Person("赵六",54), "英国");
method1(hm);
}
/*
* 实现map集合的第一种获取方法
*/
public static void method(HashMap<Person,String> hm){
Set<Person> set = hm.keySet();
Iterator<Person> it = set.iterator();
while(it.hasNext()){
Person p = it.next();
String s = hm.get(p);
System.out.println(p + ".." + s);
}
}
/*
* 第二种方法获取,entry
*/
public static void method1(HashMap<Person,String> hm){
Set<Map.Entry<Person, String>> set = hm.entrySet();
Iterator<Map.Entry<Person, String>> it = set.iterator();
while(it.hasNext()){
Map.Entry<Person, String> e = it.next();
System.out.println(e.getKey() + ".." + e.getValue());
}
}
}
五、LinkedMap类
LinkedMap是HashMap的子类,基于链表的哈希表实现,有序的Map集合,线程不安全的,开始版本于JDK1.4。
package map;
import java.util.*;
/*
* LinkedHashMap的存储和遍历
* 按put的顺序排序
*/
public class LinkedHashMapDemo {
public static void main(String[] args) {
LinkedHashMap<String, String> lhm = new LinkedHashMap<>();
lhm.put("a","65" );
lhm.put("c","67" );
lhm.put("b","668" );
lhm.put("A","786" );
lhm.put("d","786786" );
for(String key : lhm.keySet()){
System.out.println(lhm.get(key));
}
}
}
六、HashTable
底层数据结构也是哈希表,但是不允许存储null,线程安全,运行速度慢。开始版本JDK1.0,没有集合框架以前,存储键值对,只能依靠Hashtable,被HashMap取代,郁郁而终了。但是他有一个子类Properties,依然活跃在开发舞台,这个集合可以和IO流配合使用。
七、TreeMap集合
对存储的键进行排序,需要对象的自然顺序,或者比较器,用法和实现代码,直接参考HashSet集合,线程不安全集合,运行速度快,底层实现红黑树,自然平衡算法二叉树。
package cn.itcast.map;
/*
* TreeMap存储自定义对象
* 提供两个排序方式,自然顺序,一个是比较器
*/
import java.util.*;
import SetDemo.PersonComparator;
public class TreeMapDemo {
public static void main(String[] args) {
//传递一个自然比较对象进去
TreeMap<Person,String> tm = new TreeMap<Person, String>(new PersonComparator());
tm.put(new Person("lisi",18), "加拿大");
tm.put(new Person("zhangsa",17), "澳大利亚");
tm.put(new Person("zhangsa",17), "澳大利亚");
tm.put(new Person("wangwu",20), "新加坡");
tm.put(new Person("zhaoliu",19), "新西兰");
tm.put(new Person("zhaoliu",19), "新西兰");
tm.put(new Person("lisa",22), "迪拜");
// keySet(tm);
entrySet(tm);
}
/*
* 增强for循环,遍历entrySet方式
*/
public static void entrySet(TreeMap<Person,String> hm){
for(Map.Entry<Person, String> entry : hm.entrySet()){
Person p = entry.getKey();
String value = entry.getValue();
System.out.println(p+"..."+value);
}
}
/*
* 增强for循环,遍历keySet方式
*/
public static void keySet(TreeMap<Person,String> tm){
for(Person p : tm.keySet()){
String value = tm.get(p);
System.out.println(p+"..."+value);
}
}
}
八、map集合的小练习
题目:统计一个字符串内每个字母出现的顺序,存储在集合之中
package map;
/*
* 练习:
* 统计字符串里面每个字符出现的次数,存储到map里面
* eg:a=1,b=3....
*
*/
import java.util.*;
public class HashMapTest {
public static void main(String[] args) {
String s = "xcvgbjhmklfdxhkuxck.jbjgcj,ckyfxckh";
System.out.println(method(s));
}
public static Map<Character,Integer> method(String s){
char[] c = s.toCharArray();
Map<Character,Integer> tongji = new HashMap<Character, Integer>();
for(int i = 0 ; i < c.length ; i++){
char temp = c[i];
if(tongji.containsKey(temp)){
tongji.put(temp,tongji.get(temp)+1);
}
else{
tongji.put(temp, 1);
}
}
return tongji;
}
}
九、Properties类
Hashtable的子类,也是一个线程安全的键值对的集合。这个类不同于其他集合,可以和IO流结合使用,实现数据的永久性存储。查看API发现这个集合没定义泛型,泛型已经被设定好了,键值对的数据类型都是字符串,完全适用于Map中的一切操作。
特有方法setProperty(String key,String value)等同于就是Map中的put,getProperty(String value)传递键,返回对应的值,等同于Map中的get方法, 以后可以用于配置文件。
demo
package map;
/*
* Properties类的练习
*/
import java.util.*;
public class PropertiesDemo {
public static void main(String[] args) {
method1();
Properties pro = System.getProperties();
System.out.println(pro);
System.out.println(pro.get("os.name"));
}
/*
* 使用Properties自己的方法操作
*/
public static void method1(){
Properties pro = new Properties();
pro.setProperty("a", "1");
pro.setProperty("b", "2");
pro.setProperty("c", "3");
pro.setProperty("d", "4");
pro.setProperty("e", "5");
System.out.println(pro.getProperty("a"));
System.out.println(pro.getProperty("bb"));
}
/*
* 像map一样操作Properties
*/
public static void method(){
Properties pro = new Properties();
pro.put(1, 321);
pro.put(2, 345321);
pro.put(3, 321);
pro.put(5, 321);
pro.put(4, 324534531);
System.out.println(pro.get(3));
Set set = pro.keySet();
Iterator it = set.iterator();
while(it.hasNext()){
Object key = it.next();
Object value = pro.get(key);
System.out.println(key + "..." + value);
}
}
}
十、Collections工具类
Collections中的方法都是静态的,用于操作集合类的。
- static void sort(List list)根据存储在集合的对象的自然顺序,对List集合排序
- static void sort(List list,Comparator com)根据比较器对List集合排序
- static Comparator reverseOrder()返回比较器,逆转对象的自然顺序
- static Comparator reverseOrder(Comparatorc)传递比较器,返回比较器,返回的比较器逆转了传递的比较器
- static int binarySearch(List list, Objectkey)集合的折半查找,传递List集合必须有序,找到返回下标,找不到返回,返回插入点-1
- static void fill(List list,Object obj)填充集合
- static void swap(List list ,int x,int y)指定下标,对List集合中的对象换位置
- static void shuffle(List list)对List集合中的对象,随机换位置
- 将线程不安全集合变成线程安全集合 synchronized开头的方法
package Collections;
/*
* 集合工具类的操作方法
*/
import java.util.*;
import SetDemo.Person;
import SetDemo.PersonComparator;
public class CollectionsDemo {
public static void main(String[] args) {
method_4();
}
/*
* static void swap(List list ,int x,int y)指定下标,对List集合中的对象换位置 static void
* shuffle(List list)对List集合中的对象,随机换位置
*/
public static void method_4() {
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
list.add(6);
list.add(7);
list.add(8);
System.out.println(list);
Collections.swap(list, 0, 1);
System.out.println(list);
Collections.shuffle(list);
System.out.println(list);
}
/*
* static void fill(List list,Object obj)填充集合
*/
public static void method_3() {
List<Integer> list = new ArrayList<>();
list.add(12);
list.add(13);
list.add(15);
list.add(78);
list.add(54);
Collections.fill(list, 2);
System.out.println(list);
}
/*
* static int binarySort(List list)集合的折半查找折半查找,
*/
public static void method_2() {
List<Integer> list = new ArrayList<>();
list.add(12);
list.add(13);
list.add(15);
list.add(78);
list.add(54);
list.add(84);
list.add(25);
list.add(65);
int i = Collections.binarySearch(list, 84);
System.out.println(i);
}
/*
* static Comparator reverseOrder()返回比较器,逆转对象的自然顺序 static Comparator
* reverseOrder(Comparatorc)传递比较器,返回比较器,返回的比较器逆转了传递的比较器
*
*/
public static void method_1() {
List<Person> list = new ArrayList<>();
list.add(new Person("liu", 23));
list.add(new Person("niu", 21));
list.add(new Person("fei", 222));
list.add(new Person("zi", 2323));
Collections.sort(list, Collections.reverseOrder(new PersonComparator()));
System.out.println(list);
}
/*
* static void sort(List list) 可以给集合排序 static void sort(List list,Comparator
* com)根据比较器对List集合排序
*/
public static void method() {
List<String> list = new ArrayList<>();
list.add("slkeghk");
list.add("aftytyj");
list.add("bturehk");
list.add("crgresr");
System.out.println(list);
Collections.sort(list);
System.out.println(list);
List<Person> l = new ArrayList<>();
l.add(new Person("liu", 23));
l.add(new Person("niu", 21));
l.add(new Person("fei", 222));
l.add(new Person("zi", 2323));
System.out.println(l);
Collections.sort(l);
System.out.println(l);
}
}
十一、集合数组的互转
数组转成集合 Arrays类方法isList , 传递数组,返回集合。
数组转成集合后,改变集合长度的操作不能做,如果做了,出现不支持的操作异常
集合转数组Collection中方法toArray() 将集合转成数组,传递数组,返回数组
写法:list.toArray(new Object[list.size()]);