Map:地图、映射关系。
ORM:对象关系映射 类对象 <==> 数据库数据
双边队列:数据存储形式都是键(Key)值(Value)对形式
如:表格:
姓名——Tom
年龄——16
性别——男
Map双边队列中对于数据存储
(1)有限制:存储数据类型在创建Map双边队列时进行数据约束,保证数据类型一致化
(2)没限制:Map可以满足任意类型
Map使用了两个泛型:Map
interface Map
(1)class HashMap
(2)class TreeMap
常用API(Application Programing Interface)
SDK(Software Development Kit)
(1)增
put(K key, V value);
添加符合Map要求的键值对存入到双边队列中
putAll(Map<? extends K, ? extends V> map)
添加另一个Map到当前Map中,要求K是当前Map本身对应的K,或者其子类
V是当前Map本身对应的V,或者其子类
(2)删
remove(Object key);
删除对应的Key键值对
(3)改
put(K key, V value);
使用value修改已存在的Key对应的值
(4)查
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集合
总结:
(1)set开头:设置方法
(2)get开头:获取方法
(3)Set结尾:返回值是Set集合,数据唯一
(4)-s结尾:表示复数,一般返回值类型都是Collection、List或者数组
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);
}
}
/*
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
}
Map双边队列中把Key和Value进行一个封装操作,完全按照一个数据类型来处理
例如:
class Entry<K, V> {
K k;
V v;
······
}
Map双边队列中提供了操作Entry的方法
Set<Map.Entry<K, V>> entrySet();
解释:(1)返回值类型是Entry键值对形式数据的Set集合
(2)Set
其中,Map.Entry
因为返回值是Set集合,集合带有泛型Set
Entry对应的API
(1)K getKey();
(2)V getValue();
(3)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("都比较贵"));
}
}
}
Map很重要,尤其是HashMap,键值对操作在后期开发中非常常见,数据库、Session、Cookies、数据传递、Json、XML…
比较器接口一定要是学会使用
(1)Comparator【重点】自由度非常高,满足各种条件
(2)Comparable
对排序方法的期望:
(1)排序的内容有用户决定
a. 数组
b. 泛型
(2)排序的规则由用户决定【暂时决定】
方法声明
public static < T > void delectSort(T[ ] arr, Comparator< T > com)
这是一个工具方法? √
还是属于哪一个类的成员方法?×
package com.qfedu.student.system.util;
import java.util.Comparator;
/**
* 自定义工具类
*
* @author Anonymous
*
*/
public class MyUtils {
/**
* 自定义工具类内的选择排序算法,用于排序任意数据类型,但是要求需要提供对应数据类型的
* Comparator接口规范比较方式。
*
* @param 自定义泛型
* @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;
}
}
}
}
目前,Comparator接口的使用过程
(1)方法的参数是Comparator接口
(2)需要完成Comparator接口实现类
(3)Comparator接口实现类中完成compare方法
(4)compare方法约束比较规则
实现类的名字很重要吗?
(1)知道数据类型
(2)方便new对象操作
(3)方便调用方法
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();
}
}; // 注意这里有一个分号
这就是一个匿名内部类的对象.
【注意】注意大括号最后的分号!!!
package com.qfedu.student.system.util;
import java.util.Comparator;
/**
* 自定义工具类
*
* @author Anonymous
*
*/
public class MyUtils {
/**
* 自定义工具类内的选择排序算法,用于排序任意数据类型,但是要求需要提供对应数据类型的
* Comparator接口规范比较方式。
*
* @param 自定义泛型
* @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;
}
}
}
}
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);
}
}
}
SprigBoot、SpringCloud 框架涉及到JDK1.8 新特征一定要会。比如Lamda、Stream 函数式接口
匿名内部类格式:
(1)最原始格式
接口名 接口引用数据类型变量 = new 接口名() {
// 当前接口要求实现类完成的方法
}
接口引用的数据类型变量调用方法使用,或者作为方法的参数传入。
(2)匿名内部类的匿名对象直接作为方法参数
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.println("匿名部类的匿名对象直接作为方法参数");
}
});
}
public static void testInterface(A a) {
a.test();
}