集合框架之Map

一、Map

①map的特点

键值对 增删查改

package com.maomao.map;

import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;


public class Demo1 {
	public static void main(String[] args) {
		Hashtable<String , Integer> table=new Hashtable<>();
//		public synchronized V put(K key, V value)
		table.put("a", 1);
		table.put(null, null);
		
		
		Map<String,Integer> map = new HashMap<>();
		map.put("a", 1);
		map.put("b", 2);
		map.put("c", 3);
		map.put("d", 4);
		map.put(null, null);
		System.out.println(map);
		Object remove = map.remove("b");
		System.out.println(remove);
		System.out.println(map);
		//修改  也是调用put方法
		map.put("c", 77);
		System.out.println(map);
		
		//查询
		System.out.println(map.get("c"));
		
		
		//查询全部
//		1.先拿到map集合中的所有key
		Set keySet = map.keySet();
		for (Object key : keySet) {
			System.out.println("键:"+key+"   值:"+map.get(key));
		}
		
//		2.拿到映射关系
		Set<Entry<String, Integer>> entrySet = map.entrySet();
		for (Entry<String, Integer> entry : entrySet) {
			System.out.println("键:"+entry.getKey()+"   值:"+entry.getValue());
		}
		
	}
	
}

HashMap与hashtable的区别

hashtable是线程安全的
jdk1.8以前key是可以存放null值的

②遍历的方式

拿到key,再拿值
拿到映射关系,键值都有了

1.keySet

先拿到map集合中的所有key

Set keySet = map.keySet();
		for (Object key : keySet) {
			System.out.println("键:"+key+"   值:"+map.get(key));
		}

2.entrySet

拿到映射关系

Set<Entry<String, Integer>> entrySet = map.entrySet();
		for (Entry<String, Integer> entry : entrySet) {
			System.out.println("键:"+entry.getKey()+"   值:"+entry.getValue());
		}

③常用实现类hashMap

案例1:统计各个字母出现的次数

package com.maomao.map;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.Map.Entry;

public class Demo2 {
	public static void main(String[] args) {
		String s="sjdjdjeoeoejffasssalflfdsssqwrewqroeowqwgjde";
		
		/*
		 * 实现思路:
		 * 	1.做字符串切割,再到一个字符数组
		 * 	2.接下来遍历,拿到单个字符
		 * 	3.如果该字符没有出现过,那value值为null,那么连字符为KEY, 值初始化为1
		 * 4.如果已经出现过,拿到原来的值+1
		 * 
		 */
		
		char[] arr = s.toCharArray();
		Map<Character, Integer> map=new TreeMap<>();
		for (char c : arr) {
			Integer value=map.get(c);
			if(value==null) {
				map.put(c, 1);
			}
			else {
				map.put(c, value+1);
			}
//			System.out.println(value);
		}
		
		Set<Entry<Character, Integer>> entrySet = map.entrySet();
		for (Entry<Character, Integer> entry : entrySet) {
			System.out.println(entry.getKey()+":"+entry.getValue());
		}
		
	}

}

案例2:根据出现的次数排序

List<Map.Entry<Character, Integer>> list = new ArrayList<Map.Entry<Character, Integer>>(map.entrySet());
        Collections.sort(list, new Comparator<Map.Entry<Character, Integer>>() {
            @Override
            public int compare(Map.Entry<Character, Integer> o1, Map.Entry<Character, Integer> o2) {
                return o1.getValue() - o2.getValue();
            }
        });
	for (Entry<Character, Integer> entry : list) {
		System.out.println(entry.getKey()+":"+entry.getValue());
	}

④泛型

之前:不健壮的代码会在运行时才会把错误暴露出来
之后:将潜在的问题暴露出来

1.作用

将运行期出现的异常转换为编译期的错误

package com.maomao.map;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class Demo3 {
	public static void main(String[] args) {
		Set<Integer> set = new HashSet<>();
		set.add(1);
		set.add(2);
		set.add(3);
		set.add(4);
		set.add(5);
		for (Object obj : set) {
			if(Integer.valueOf(obj.toString())%2==0) {
				System.out.println(obj);
			}
		}
		
	}
	
}

2.泛型类

是在实例化类的时候指明泛型的具体类型
泛型类可能有多个参数,此时应将多个参数一起放在尖括号内。比如:<E1,E2,E3>

泛型类的构造器如下:public GenericClass(){}。而下面是错误的:public GenericClass(){}

实例化后,操作原来泛型位置的结构必须与指定的泛型类型一致。

泛型不同的引用不能相互赋值。

尽管在编译时ArrayList和ArrayList是两种类型,但是,在运行时只有一个ArrayList被加载到JVM中。

泛型如果不指定,将被擦除,泛型对应的类型均按照Object处理,但不等价于Object。

如果泛型结构是一个接口或抽象类,则不可创建泛型类的对象。

泛型的指定中不能使用基本数据类型,可以使用包装类替换。

class Test {
	public static void main(String[] args) {
		// 1、使用时:类似于Object,不等同于Object
		ArrayList list = new ArrayList();
		// list.add(new Date());//有风险
		list.add("aa");
		test(list);// 泛型擦除,编译不会类型检查
		// ArrayList<Object> list2 = new ArrayList<Object>();
		// test(list2);//一旦指定Object,编译会类型检查,必须按照Object处理
	}
	public static void test(ArrayList<String> list) {
		String str = "";
		for (String s : list) {
			str += s + ",";
		}
		System.out.println(str);
	}
}

3.泛型方法

是在调用方法的时候指明泛型的具体类型
方法,也可以被泛型化,不管此时定义在其中的类是不是泛型类。在泛型 方法中可以定义泛型参数,此时,参数的类型就是传入数据的类型。

泛型方法的格式:
[访问权限] <泛型> 返回类型 方法名([泛型标识 参数名称]) 抛出的异常

泛型方法声明泛型时也可以指定上限

⑤集合框架工具类

1.Collections

排序

/*List<String> list = new ArrayList<>();
		list.add("b");
		list.add("c");
		list.add("a");
		System.out.println(list);
		Collections.sort(list);
		System.out.println(list);
//		这里面的x,y指的是集合中的元素
		Collections.sort(list,(x,y) -> y.compareTo(x));
		System.out.println(list);*/

组合转数组 toArray

package com.maomao.map;

import java.util.Arrays;
import java.util.List;

/**
 * 
 * 集合之间的转换:
 * 1.数组转成集合,本质上依然是一个数组,长度是不可变的
 * 2.集合与数组所具备的方法是不一样的,如对于数组而言,就没有判断内部包含哪个元素
 * 
 * @author Administrator
 *
 */
public class Demo4 {
		public static void main(String[] args) {
			String[] arr= {"a","b","c","d"};
			List<String> list=Arrays.asList(arr);
//			Object[] array = list.toArray();
			list.add("e");
//			 java.lang.UnsupportedOperationException
			System.out.println(list.size());
			
		}
	
}

2.Arrays

sort&&tostring

package com.maomao.map;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

public class Demo5 {
	public static void main(String[] args) {
		
		
		List<Person> list = new ArrayList<>();
		list.add(new Person("b", 16));
		list.add(new Person("c", 18));
		list.add(new Person("a", 19));
		System.out.println(list);
		Collections.sort(list,(x,y) -> x.getName().compareTo(y.getName()));
		System.out.println(list);
		
		Integer[] arr= {3,6,9,2,5,8};
		Arrays.sort(arr,(x,y) -> y-x);
		
	}
	
}
class Person/* implements Comparable<Person>*/{
	private String name;
	private int 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 Person() {
		// TODO Auto-generated constructor stub
	}
	public Person(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;
		Person other = (Person) 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 int compareTo(Person o) {
		return o.getName().compareTo(this.name);
	}*/
	
	
}

Debugger的使用:调试代码

1.打断点

双击左侧标记的蓝色区域,需要调试哪一行就双击哪一行
在这里插入图片描述

2.采用debug的方式运行程序

右键找到Debug As
在这里插入图片描述

3.进入调试窗口

点击yes进入调试窗口
在这里插入图片描述

左上方有一个step over调试箭头,快捷键F6
在这里插入图片描述

4.接下来可以通过F6一步步调试当前程序对应的每一个变量值
5.调试好后退出debug

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值