java基础第十四篇之Map
一,Map集合的特点:
*
* 1.Map集合和Collection集合,没有关系
*
* 2.Map集合的元素是成对存在(夫妻关系)
* Collection集合的元素是独立存在的(单身关系)
*
* 3.Map集合的元素不能重复(是元素的key值不能重复)
*
* 总结:
* Collection集合我们一般称为单列集合
* Map集合我们称为双列集合
* 二,Map接口下常用的实现类
*
* HashMap<K,V>:底层是哈希表结构,无序的(存取顺序不一致)
*
*
* LinkedHashMap<K,V>:底层链表+哈希表结构,有序的(存取顺序一致)
* 这里<K,V>是两个泛型,这里的K和V可以相同 也可以不同
* K代表键的类型,V代表的是值的类型
*
* 以上所有的实现类,保证键的唯一性(键不能重复),那么我们需要重写K这种类型的hashCode和equals方法
* 比如:K的类型是String,Integer...(java提供的类型),那么我们不需要管他
* K的类型是Person,Dog等自定义类型 那么我们就需要重写hashCode和equals方法
*
* 三,Map接口中定义的常用方法:
*
* 1.增加:
* public V put(K key,V value);//向Map集合中添加一个元素(键值对)
* 返回值:表示被新的键值对 覆盖的那个旧的键值对的值
* 如果没有覆盖,返回值是null
*
* 2.删除:
* public V remove(Object key);//删除一个键值对(根据键来删除)
*
* 3.改:实际上就是put方法,只要put的时候键和map集合中原有的键重复,就可以达到改的目的
*
* 4.查
* public V get(Object key);//根据键 来查找键所对应的值
public interface InterfaceA {
public abstract void showA();
interface InterfaceB{//内部接口
public abstract void showB();
}
}
//定义一个类 去实现接口
class MyClass1 implements InterfaceA{
@Override
public void showA() {
// TODO Auto-generated method stub
}
// @Override
// public void showA() {
// // TODO Auto-generated method stub
//
// }
}
class MyClass2 implements InterfaceA.InterfaceB{
@Override
public void showB() {
// TODO Auto-generated method stub
}
}
/*
* 1.因为Map集合 和Collection集合 没有继承关系
* map集合中是没有迭代器
*
* 2.java为map集合提供了另外两种迭代的方式:
* 方式一:以键找值的方法:
* 获取所有的键的集合 map.keySet();
* 方式二:键值对的方式
* public Set<Map.Entry<K,V>> entrySet()
*/
//创建内部类对象
//OuterClass.InnerClass oi = new OuterClass().new InnerClass();
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("张三", 18);
map.put("李四", 28);
map.put("王五", 38);
map.put("赵六", 48);
//1.获取map集合的entry 集合
Set<Map.Entry<String, Integer>> entries = map.entrySet();
//2.用迭代器 遍历这个entries这个Set集合
Iterator<Map.Entry<String, Integer>> it = entries.iterator();
//3.遍历
while(it.hasNext()){
Map.Entry<String, Integer> entry = it.next();
//一个entry中 有两个属性
String key = entry.getKey();
Integer value = entry.getValue();
System.out.println(key+"="+value);
}
* 练习1:使用map存储:键为学号,值为一个学生的对象,学生对象有属性(姓名,年龄)
*
*
* 练习2:使用map存储:键为学生(姓名,年龄)值为学生自己的家庭住址。
* Map<Student,String>
public class MapDemo {
public static void main(String[] args) {
//定义一个Map集合 存储键为学生(姓名,年龄)值为学生自己的家庭住址。
Map<Student, String> map = new HashMap<Student, String>();
//向集合添加数据
map.put(new Student("王宝强", 40), "北京五环外");
map.put(new Student("谢霆锋", 50), "北京180环外");
map.put(new Student("马蓉", 45), "上海交通路");
map.put(new Student("郭德纲", 55), "广州德云社");
map.put(new Student("马蓉", 45), "我家");
//map判断键重复不重复,是通过hashCode和equals方法
//如果 我要求一个学生的姓名和年龄一样 就认为是同一个学生
//遍历集合 keySet entrySet
//1.获取entry的集合
Set<Map.Entry<Student, String>> entries = map.entrySet();
//2.迭代器遍历 foreach
for (Map.Entry<Student, String> entry : entries) {
Student key = entry.getKey();
String value = entry.getValue();
System.out.println(key+"="+value);
}
}
}
/*
* LinkedHashMap: 采用链表+哈希表结构
* 元素是有序的
Collection和Map都可以嵌套
*
* ArrayList<ArrayList<String>>
*
* ArrayList<Map<K,V>>
*
* Map<String,ArrayList<String>>
*
* Map<String,Map<String,Student>>
*
* 比如我们传智博客学生(有iOS Android UI JavaEE)
* Map<学号,学生> UI = new HashMap<学号,学生>();
*
* Map<学号,学生> JavaEE = new HashMap<学号,学生>();
*
* Map<学号,学生> android = new HashMap<学号,学生>();
*
*
* ArrayList<Map<学号,学生>> al= new ....
* al.add(UI);
* al.add(JavaEE);
* al.add(android);
*
* Map<学院名,Map<学号,学生>> map = new ....
* map.put("UI学院",UI);
* map.put("JavaEE学院",JavaEE);
* map.put("安卓学院",android);
*
*
*
*
*
*/
public class MapMapDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
//1.创建一个UI学院的map集合
Map<String, Student> uiMap = new HashMap<String, Student>();
uiMap.put("黑马001", new Student("小丽", 18));
uiMap.put("黑马003", new Student("小美", 19));
uiMap.put("黑马004", new Student("小雨", 20));
//2.创建一个JavaEE学院map集合
Map<String, Student> eeMap = new HashMap<String, Student>();
eeMap.put("黑马001", new Student("小诗", 18));
eeMap.put("黑马002", new Student("小公", 19));
eeMap.put("黑马004", new Student("小龙", 20));
//3.创建一个android学院map集合
Map<String, Student> anMap = new HashMap<String, Student>();
anMap.put("黑马002", new Student("小k", 18));
anMap.put("黑马003", new Student("小Q", 19));
anMap.put("黑马004", new Student("小A", 20));
//4.定义一个存储所有学院名字和map对象的集合
Map<String,Map<String, Student>> map = new HashMap<String, Map<String,Student>>();
map.put("UI学院", uiMap);
map.put("EE学院", eeMap);
map.put("AN学院", anMap);
//遍历map 打印是每一个学生
//1.keySet() 2.entrySet()
Set<Map.Entry<String,Map<String, Student>>> entries = map.entrySet();
//2.遍历 entries 迭代器,foreach
Iterator<Map.Entry<String,Map<String, Student>>> it = entries.iterator();
//标准代码
while(it.hasNext()){
Map.Entry<String,Map<String, Student>> entry = it.next();
String key = entry.getKey();
Map<String, Student> valueMap = entry.getValue();
//遍历value这个map集合 keySet entrySet
Set<Map.Entry<String, Student>> xyentries = valueMap.entrySet();
//迭代器 foreach
Iterator<Map.Entry<String, Student>> xyit = xyentries.iterator();
//标准代码
while(xyit.hasNext()){
Map.Entry<String, Student> xyentry = xyit.next();
String xykey = xyentry.getKey();
Student xyValue = xyentry.getValue();
//System.out.println("学院,学号,学生名字,学生年龄");
System.out.println(key+"-"+xykey+"-"+xyValue.getName()+"-"+xyValue.getAge());
}
}
}
}
* Collections集合工具类中的两个方法:
*
* public static void sort(List<T> list);//按照自然顺序(123 321 abc cba)排序一个List集合
*
* public static void shuffle(List<?> list);//打乱集合中顺序
* 可变参数: 这里说的可变 不是参数的数据类型 而是参数的个数
* JDK1.5之后的新特性
*
* 格式: public void showNum(int... num){
*
* }
*
* 注意事项:
* 当一个方法具有多个参数,而且其中有一个是可变参数,那么可变参数必须写到 参数的最后一个
*
public class VariableArgDemo01 {
public static void main(String[] args) {
// TODO Auto-generated method stub
// show(1);
// show(1,2);
// show(1,2,3);
show(1,2,3,4,5);
}
//定义带有可变参数的方法
public static void show(int count,int... num){
//在方法中怎么获取实际传递进来的参数,可变参数本质就是一个数组
System.out.println(num.length);
for (int i = 0; i < num.length; i++) {
System.out.println(num[i]);
}
}
}
/*
* 1.定义自定义规则的map集合
*
* 2.产生一副牌(存储的是序号)
*
* 3.洗牌(序号的集合)
*
* 4.发牌(发的就是序号)
*
* 5.要求三个玩家以及地主牌进行排序(sort方法)
*
* 6.看牌(根据序号从自定义的map集合中取值)
*
*
*/
public class DouDiZhuDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
//1.定义规则的map集合
Map<Integer, String> map = new LinkedHashMap<Integer, String>();
//2.定义一个牌集合
ArrayList<Integer> cards = new ArrayList<Integer>();
//添加牌 一张牌 数值+花色
String[] nums = {"3","4","5","6","7","8","9","10","J","Q","K","A","2"};
String[] colors = {"♠","♥","♣","♦"};
//拼接一个张牌
int id = 54;//1234
for (String num : nums) {
for (String color : colors) {
String card = color+num;
map.put(id, card);
cards.add(id);
id--;
//System.out.println(card);
}
}
//添加大王小王
map.put(2, "小S");
cards.add(2);
map.put(1, "大S");
cards.add(1);
//3.洗牌
Collections.shuffle(cards);
//4.发牌
//定义三个集合
ArrayList<Integer> p1 = new ArrayList<Integer>();
ArrayList<Integer> p2 = new ArrayList<Integer>();
ArrayList<Integer> p3 = new ArrayList<Integer>();
//定义地主牌的集合
ArrayList<Integer> dp = new ArrayList<Integer>();
//遍历54张牌
for (int i = 0; i < cards.size(); i++) {
Integer card = cards.get(i);
//如果是最后三张,不发,保存到地主牌的集合中
//i 53 52 51
if(i>=51){
//不发
dp.add(card);
}else{
//0 p1 1 p2 2 p3 3 p1
if(i%3==0){
//给p1发牌
p1.add(card);
}else if(i%3==1){
p2.add(card);
}else{
p3.add(card);
}
}
}
//5.排序
Collections.sort(p1);
Collections.sort(p2);
Collections.sort(p3);
Collections.sort(dp);
//看牌
lookCards(p1,map);
lookCards(p2,map);
lookCards(p3,map);
lookCards(dp,map);
}
/*
* 看牌
*/
public static void lookCards(ArrayList<Integer> cards,Map<Integer, String> map){
//根据每一张的编号从 map中取出打印
for (Integer id : cards) {
String card = map.get(id);
System.out.print(card+" ");
}
System.out.println();
}
}
/*
Map 里面有个方法: boolean containsKey : 判断Map集合中是否包含指定值
HashSet:底层是哈希算法实现.
LinkedHashSet:底层是链表实现,但是也是可以保证元素唯一,和HashSet原理一样.
TreeSet:底层是二叉树算法实现.
一般在开发的时候不需要对存储的元素排序,所有在开发的时候大多用HashSet,HashSet的效率比较高
TreeSet在面试的时候比较多,问你有几种排序方式,和几种排序方式的区别?
2. TreeSet总结
1). TreeSet的特点
(1). 可以对元素进行排序
有两种排序方式。
(2). TreeSet保证元素的唯一性依据
在实现的Comparable的compareTo或者Comparator的compare方法中,如果这两个方法的返回值为0,那么TreeSet就认为这两个元素一样。按照Set的唯一性规则,在一次重复的元素不能被添加到TreeSet这个集合中。
2). TreeSet的两种排序方式
(1). 让元素本身具有比较性
元素本身要实现Comparable接口并实现里面的compareTo方法以保证元素本身具有比较性
(2). 让容器自身具有比较性
当元素本身不具有比较性或者具备的比较性不是所需要的,就在TreeSet建立实例的时候,传入Comparator接口的实现子类的实例。这个Comparator子类必须实现compare方法。
(3). 元素的可存储性
[1]. 自定义的类,如果重写了hashCode和equals两个方法,可以存入HashSet容器
[2]. 自定义的类,如果实现了Comparable的compareTo()方法,可以存入TreeSet容器。
【总结】如果自定义的类既重写了hashCode和equals,又实现了compareTo,那么这个类的元素既可以存入HashSet容器,也可以存入TreeSet容器。
Map
HashMap :底层是哈希算法,针对键
LinkedHashMap:底层是链表,针对键.
TreeMap:底层是二叉树算法,针对键.(开发中HashMap比较多)
Collection
List(存取有序,有索引,可以重复)
ArrayList:底层是数组实现的,线程不安全,查找和修改快,增和删比较慢.
LinkedList:底层是链表实现的,线程不安全,增和删比较快,查找和修改比较慢
Vector : 底层是数组实现的,线程安全的,无论增删改查都慢.
如果查找和修改多,用ArrayList.
如果增和删多,用LinkedList.
如果都多,用ArrayList
Set(存取无序,无索引,不可以重复)
HashSet
LinkedHashSet
TreeSet
//获取字符串中每个字符的个数
public class Demo11 {
public static void main(String[] args) {
String sbc = "kalsdjfoisoigjsljlfklkadaooaijfa";
//将字符串变成一个字符数组
char[] chs = sbc.toCharArray();
//遍历这个字符数组,一个一个的进行比较,但是要计算数量,那么用那个集合好点?Map,为什么Map,可以显示效果,'a',1 'b'2
Map<Character, Integer> map = new HashMap<>();
//遍历字符数组
for(char c : chs) {
//判断Map里面有没有键是c的?
boolean flag = map.containsKey(c);
//代表map里面有键是c的,那么数量就需要++
if(flag) {
//在原先的数量上加上1,根据键找值
map.put(c, map.get(c)+1);
}else {
//就是map集合里面没用这个字符,如果说是没有的话,那么说明是第一次.
map.put(c, 1);
}
}
System.out.println(map);
}
}
java基础第十四篇之Map的更多相关文章
- java基础第十九篇之Xml
1:xml的概述 1.1 xml是什么 标记语言:语言中出现了<a></a>的标签 a:HTML 超文本标记语言 (语法非常严格,不能随意的定义标签) b:XML 可扩展的标记 ...
- java基础第十五篇之IO流和递归算法
FileInputStream : 输入流 int available() : 一次读取所有的字节数 read() : 将文件上的字节读取到内存的数组中 FileOutputStream : 输出流 ...
- Java基础(十四):泛型
一.Java 泛型: Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型. 泛型的本质是参数化类型,也就 ...
- 正则表达式、Calendar类、SimpleDateFormat类、Date类、BigDecimal类、BigInteger类、System类、Random类、Math类(Java基础知识十四)
1.正则表达式的概述和简单使用 * A:正则表达式(一个字符串,是规则) * 是指一个用来描述或者匹配一系列符合某个语法规则的字符串的单个字符串.其实就是一种规则.有自己特殊的应用. * B: ...
- 夯实Java基础(十四)——Java8新的日期处理类
1.前言 Java8之前处理日期一直是Java程序员比较头疼的问题,从Java 8之后,Java里面添加了许多的新特性,其中一个最常见也是最实用的便是日期处理的类——LocalDate.LocalDa ...
- java基础(十四)集合(一)
这里有我之前上课总结的一些知识点以及代码大部分是老师讲的笔记 个人认为是非常好的,,也是比较经典的内容,真诚的希望这些对于那些想学习的人有所帮助! 由于代码是分模块的上传非常的不便.也比较多,讲的也是 ...
- java基础(十四章)
1.Java中的包(package) 2.1 包,对应到磁盘中的文件夹 2.2 新建一个class,默认保存在缺省包中 2.3 声明包的关键字:package package语句,置顶位置 2.4 导 ...
- java基础第十二篇之集合、增强for循环、迭代器和泛型
Collection接口中的常用方法: * 所有的子类子接口都是具有的 * 集合的方法:增删改查 * * public boolean add(E e);//添加元素 返回值表示是否添加成功 * pu ...
- java基础第十八篇之单元测试、注解和动态代理
1:单元测试 1)JUnit是一个Java语言的单元测试框架,这里的单元指的就是方法 2)单元测试用来替换以前的main方法 1.1 Junit测试的步骤 1:在方法的上面加上 @Test 2:将ju ...
随机推荐
- Failed to execute ‘createObjectURL’ on ‘URL’: No function was found that matched the signature provided.
这个报错是因为在浏览器上开启了手机模拟调试.Web SDK 不支持手机模拟调试的.
- SpringCloud中Feign的适配器的实现方案
前言 最近在做微服务的项目,各个系统之间需要进行调用,然后用一个适配器来实现服务之间的feign调用,使用适配器进行统一管理. 实现方案 首先我们需要将服务的名称进行单独的配置,可以方便的进行切换和扩 ...
- BeautifulSoup的重要操作
BeautifulSoup相关概念总结:https://www.cnblogs.com/pythonywy/p/11134481.html css基础以及选择器基础:https://www.cnblo ...
- Java基础专题
Java后端知识点汇总——Java基础专题 全套Java知识点汇总目录,见https://www.cnblogs.com/autism-dong/p/11831922.html 1.解释下什么是面向对 ...
- PostgreSQL 常用函数
类似Oracle ,PostgreSQL也有强大的类型转换函数, 下面仅举两个类型转换例子. --1 例子 postgres; ?column? ---------- ( row) 在PG里如果想做除 ...
- error: (-215:Assertion failed) !_src.empty() in function 'cv::cvtColor'
这个报错一般是因为你图像的路径写错了,找不到图像而导致的. 解决问题的朋友麻烦点个推荐呗!嘿嘿
- ABP入门教程7 - 基础设施层更新数据库
点这里进入ABP入门教程目录 设置数据库 在基础设施层(即JD.CRS.EntityFrameworkCore)打开数据库环境设置 JD.CRS.EntityFrameworkCore/EntityF ...
- Saltstack_使用指南18_API
1. 主机规划 salt 版本 [root@salt100 ~]# salt --version salt (Oxygen) [root@salt100 ~]# salt-minion --versi ...
- echarts自定义颜色主题
1. 进入地址: https://echarts.baidu.com/theme-builder/ 2. 配置主题 2.1. 可以选择挑选默认方案 2.2 可以进行一些样式配置 2.3 配置背景颜色 ...
- JVM-3-JVM内存结构
JVM内存结构可以大致可划分为线程私有区域和共享区域, 线程私有区域由虚拟机栈.本地方法栈.程序计数器组成,而共享区域由堆.元数据空间(方法区)组成.