Map和项目

1. Map
1.1 Map概述
Map 地图,映射关系。
	ORM 对象关系映射 类对象 <==> 数据库数据

双边队列
	数据存储形式都是键(Key)值(Value)对形式
	表格??
	姓名 骚磊
	年龄 16
	性别 男
	
	Map双边队列中对于数据存储类型
		有限制 存储数据类型在创建Map双边队列时进行约束,保证数据类型一致化
		但是也没限制 Map可以满足任意类型
	
	Map使用了两个泛型!!!
		Map<K, V>
1.2 Map整体结构和常用API
interface Map<K, V>
--| class HashMap<K, V> 
	底层存储数据结构采用的方式是哈希表方式。存储数据时根据当前存储Key作为计算存储位置,和查询元素的唯一表示。
--| class TreeMap<K, V> 
	底层存储数据结构是一个二叉树结构,要求存储的键值对,Key必须有对应排序方式。这里就需要Comparator<T> 或者 Comparable<T>
	
常用
	API Application Programing Interface
	SDK Software Development Kits
	增
		put(K key, V value);
			添加符合Map要求的键值对存入到双边队列中
		putAll(Map<? extends K, ? extends V> map)
			添加另一个Map到当前Map中,要求K是当前Map本身对应的K,或者其子类
			V是当前Map本身对应的V,或者其子类
	删
		remove(Object key); 
			删除对应Key键值对
	改
		put(K key, V value);
			使用value修改已存在的key对应的值
	查
		int size();
			Map双边队列个数
		boolean isEmpty();
			判断当前Map双边队列中是否为空
		boolean containsKey(Object key);
			判断指定Key是否存在
		boolean containsValue(Object value);
			判断指定Value是否存在
		Set<K> keySet();
			返回Map双边队列中所有Key对应的Set集合
		Collection<V> values();
			返回Map双边队列中所有value对应Collection集合
【补充】
	setId
	setName
		以上方法是Setter方法,设置类对象属性的方法
	keySet	
		返回值类型是一个Set集合,具有数据存储唯一性
	values
		以s结尾的方法,表示复数,一般返回值类型都是Collection,List或者数组
	总结:
		set开头 设置方法
		get开头 获取方法
		Set结尾,返回值是Set集合,数据唯一
		s结尾,返回值类是Collection,List或者数组
1.3 HashMap方法演示
package com.qfedu.a_map;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/*
 * Map方法演示
 */
public class Demo1 {
	public static void main(String[] args) {
		/*
		 * Map是一个接口,没有自己的类对象,这里是Map接口的实现类HashMap做方法演示
		 */
		Map<String, Integer> map1 = new HashMap<String, Integer>();
		
		map1.put("Dior 999", 280);
		map1.put("YSL", 220);
		map1.put("Mac", 180);
		map1.put("阿玛尼 405", 230);
		
		System.out.println(map1);
		
		Map<String, Integer> map2 = new HashMap<String, Integer>();
		
		map2.put("TF", 179);
		map2.put("雅诗兰黛", 229);
		
		map1.putAll(map2);
		System.out.println(map1);
		
		map1.remove("Mac");
		System.out.println(map1);
		
		map1.put("阿玛尼 405", 280);
		System.out.println(map1);
		
		System.out.println(map1.size());
		System.out.println(map1.isEmpty());
		//map1.clear();
		//System.out.println(map1.isEmpty());
		
		System.out.println(map1.containsKey("YSL"));
		System.out.println(map1.containsKey("杨树林"));
		
		System.out.println(map1.containsValue(179));
		System.out.println(map1.containsValue(100));
		
		Set<String> keySet = map1.keySet();
		System.out.println(keySet);
		
		Collection<Integer> values = map1.values();
		System.out.println(values);
	}	
}
1.4. TreeMap演示
/*
Map中的Key需要对应的排序方式
*/
package com.qfedu.a_map;

import java.util.TreeMap;

public class Demo2 {
	public static void main(String[] args) {
		TreeMap<Person, Integer> treeMap = new TreeMap<Person, Integer>(new MyComparator());
		Person person = new Person(1, "骚磊", 16);
		treeMap.put(person, 100);
		treeMap.put(new Person(2, "骚杰", 26), 100);
		treeMap.put(new Person(3, "宝哥", 16), 200);
		treeMap.put(new Person(4, "茂林", 56), 100);
		treeMap.put(new Person(5, "康爷", 76), 100);
		treeMap.put(new Person(6, "大熊", 96), 100);
		
		System.out.println(treeMap);
		System.out.println(treeMap.size());
		
		treeMap.put(new Person(6, "大熊", 96), 200);
		
		System.out.println(treeMap);
		System.out.println(treeMap.size());
		
		person.setAge(96);
		System.out.println(treeMap);
	}
}
package com.qfedu.a_map;

import java.util.Comparator;

public class MyComparator implements Comparator<Person> {

	@Override
	public int compare(Person o1, Person o2) {
		System.out.println("Comparator接口操作");
		return o1.getAge() - o2.getAge();
	}

}
public class Person {
	private int id;
	private String name;
	private int age;
	// 按照需求完成Constructor,Setter and Getter
}
1.5 关于Map键值对整体思想
Map双边队列中把Key和Value进行一个封装操作,完全按照一个数据类型来处理
例如:
	class Entry<K, V> {
		K k;
		V v;
		......
	}
	
Map双边队列中提供了操作Entry的方法
	Set<Map.Entry<K, V>> entrySet();
		返回值类型是Entry键值对形式数据的Set集合
		Set<Map.Entry<K, V>>
			Map.Entry<K, V> Map接口的内部接口Entry,使用的泛型 K,V对应Map
			创建过程中约束的K,V
			因为返回值是Set集合,集合带有泛型 Set<Map接口中的内部接口Entry>
			
	Entry对应的API	
		K getKey();
		V getValue();
		V setValue(V value);
package com.qfedu.a_map;

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

public class Demo3 {
	public static void main(String[] args) {
		HashMap<String, String> map = new HashMap<String, String>();
		
		map.put("迈巴赫", "好");
		map.put("兰博基尼", null);
		map.put("科尼塞克", "太贵了。。。");
		map.put("布加迪", "威龙");
		map.put("五菱宏光", "神车");
		
		Set<Entry<String,String>> entrySet = map.entrySet();
		
		for (Entry<String, String> entry : entrySet) {
			System.out.println("Key : " + entry.getKey() + " Value : " + entry.getValue());
			
			System.out.println(entry.setValue("都比较贵"));
			
 		}
	}
}
1.6 小总结
1. Map很重要,尤其是HashMap,键值对操作在后期开发中非常常见。
	数据库,Session Cookie 数据传递 Json XML...

2. 比较器接口一定要学会使用!!!
	Comparator [重点] 自由度非常高,满足各种条件!!!
	Comparable 
2. 项目更新
2.1 Comparator接口升级改造
希望该排序方法
	1. 排序的内容由用户决定
		a. 数组
		b. 泛型
	2. 排序的规则由用户决定【暂时完成!!!】
方法声明:
	public static <T> void selectSort(T[] arr, Comparator<T> com)
	这是一个工具方法?	√
	还是属于哪一个类的成员方法?
package com.qfedu.student.system.util;

import java.util.Comparator;

/**
 * 自定义工具类
 * 
 * @author Anonymous
 *
 */
public class MyUtils {
	/**
	 * 自定义工具类内的选择排序算法,用于排序任意数据类型,但是要求需要提供对应数据类型的
	 * Comparator接口规范比较方式。	
	 * 
	 * @param <T> 自定义泛型
	 * @param arr T类型数组,用户指定类型数组。
	 * @param c 符合当前用户传入数组对应数据类型的比较器Comparator实现类对象
	 */
	public static <T> void selectSort(T[] arr, Comparator<T> c) {
		for (int i = 0; i < arr.length - 1; i++) {
			int index = i;
			
			for (int j = i + 1; j < arr.length; j++) {
				if (c.compare(arr[index], arr[j]) > 0) {
					index = j;
				}
			}
			
			if (index != i) {
				T temp = arr[index];
				arr[index] = arr[i];
				arr[i] = temp;
			}
		}
	}
}
2.2 匿名内部类使用【重点】
2.2.1 说重点思想
说重点!!!

目前Comparator接口的使用过程
	1. 方法参数是Comparator接口
	2. 需要完成Comparator接口实现类
	3. Comparator接口实现类中完成compare方法
	4. compare方法约束比较规则

实现类的名字很重要吗???
	1. 知道数据类型
	2. 方便new对象操作
	3. 方便调用方法
2.2.2 类的本体
class Person {
	private int id;
	
	public void test() {
		
	}
}

大括号里面的所有内容都是类的本体!!!
Person只不过是大括号内容一个名字,方便我们操作。
    
class MyComparator implements Comparator<Person> {
    @Override
    public int compare(Person o1, Person o2) {
        return o1.getAge() - o2.getAge();
    }
}

大括号里面的内容就是MyComparator类的本体
大括号里面的内容是强迫实现的!!!因为遵从Comparator接口
类定义完毕之后,需要创建对象
	MyComparator com = new MyComparator();
	com.compare(arg1, arg2);

匿名内部类没有类名,只有类的本体!!!
{
    @Override
    public int compare(Person o1, Person o2) {
        return o1.getAge() - o2.getAge();
    }
}
这部分代码,可不说随便完成的,是需要【遵从Comparator】之后完成的。
使用过程中,compare方法是一个成员方法,需要一个类对象来调用。
    Comparator<Person> com = new Comparator<Person>() {
        @Override
        public int compare(Person o1, Person o2) {
            return o1.getAge() - o2.getAge();
        }
    };
	这就是一个匿名内部的对象
2.2.3 体会一下匿名内部类
package com.qfedu.b_anonymous;

import java.util.Comparator;

public class Demo1 {
	public static void main(String[] args) {
		
		Person[] personArr = new Person[10];
		
		for (int i = 0; i < personArr.length; i++) {
			int id = i + 1;
			String name = "Person" + i;
			int age = (int) (Math.random() * 100);
			
			personArr[i] = new Person(id, name, age);
		}
		
		/*
		 * 这里完成的是一个Comparator接口的匿名内部类对象
		 * 
		 * 1. 大括号里面的内容是在遵从Comparator接口的情况下,必须完成的代码
		 * 2. new Comparator<Person>() 这里创建的不是Comparator接口对象,接口没有对象
		 * 而是创建了一个遵从Comparator接口的匿名类对象。
		 * 3. 赋值号右侧new创建的对象,赋值给接口Comparator的引用数据类型变量。
		 * 这里隐含一个多态思想,接口的引用指向遵从接口的类对象。
		 */
		Comparator<Person> com = new Comparator<Person>() {

			@Override
			public int compare(Person o1, Person o2) {
				return o2.getAge() - o1.getAge();
			}
		};
				
		MyUtils.selectSort(personArr, com);
		// 增强for循环
		for (Person person : personArr) {
			System.out.println(person);
		}
	}
}
package com.qfedu.b_anonymous;

import java.util.Comparator;

public class Demo2 {
	public static void main(String[] args) {
		Dog[] dogArr = new Dog[10];
		
	
		for (int i = 0; i < dogArr.length; i++) {
			int id = i + 1;
			String name = "Dog" + i;
			int age = (int) (Math.random() * 100);
			
			dogArr[i] = new Dog(id, name, age);
		}
	
		/*
		 * 匿名内部类的匿名对象,直接作为方法的参数!!!
		 * 这种用法才是最贴合使用的用法!!!
		 */
		MyUtils.selectSort(dogArr, new Comparator<Dog>() {

			@Override
			public int compare(Dog o1, Dog o2) {
				return o2.getAge() - o1.getAge();
			}
		});
		
		// 增强for循环
		for (Dog dog : dogArr) {
			System.out.println(dog);
		}
		
	}
}
2.2.4 匿名内部类总结
SpringBoot SpringCloud
	JDK1.8新特征一定要会!!!
		Lambda Stream 函数式接口

匿名内部类格式:
	最原始格式
	接口名 接口引用数据类型变量 = new 接口名() {
		// 当前接口要求实现类完成的方法。
	}
	接口引用数据类型变量调用方法使用,或者作为方法的参数传入
	
	匿名内部类的匿名对象直接作为方法参数
	Method(new 接口名() {
		// 当前接口要求实现类完成的方法。
	});
	
	简化代码冗余度,提高效率,增强功能。
interface A {
    public void test();
}

main() {
    // 第一个种格式
    A a = new A() {
        @Override
        public void test() {
            System.out.println("匿名内部类的对象赋值给接口的引用数据类型变量");
        }
    };
    
    a.test();
    
    // 第二种格式:匿名内部类的匿名对象,直接调用方法
    new A() {
        @Override
        public void test() {
            System.out.println("匿名内部类的匿名对象直接调用成员方法");
        }
    }.test();
    
    // 第三种格式: 匿名内部类的匿名对象,直接作为方法的参数
    testInterface(new A() {
        @Override
        public void test() {
            System.out.prinltn("匿名内部类的匿名对象直接作为方法参数");
        }
    });
}

public static void testInterface(A a) {
    a.test();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值