Map和学生管理项目优化

Map和学生管理项目优化

1.Map

1.1 Map概述
  1. Map:地图、映射关系。

  2. ORM:对象关系映射 类对象 <==> 数据库数据

  3. 双边队列:数据存储形式都是键(Key)值(Value)对形式

    如:表格:

    姓名——Tom

    年龄——16

    性别——男

  4. Map双边队列中对于数据存储

    (1)有限制:存储数据类型在创建Map双边队列时进行数据约束,保证数据类型一致化

    (2)没限制:Map可以满足任意类型

  5. Map使用了两个泛型:Map

1.2 Map整体结构和常用API
  1. interface Map

    (1)class HashMap :底层存储数据的结构采用的方式是哈希表方式。存储数据是根据当前存储Key作为计算存储位置和查询元素的唯一表示。

    (2)class TreeMap :底层存储数据额的结构是一个二叉树结构,要求存储的键值对,Key必须有对应排序方式。这里就需要Comparator 或者Comparable

  2. 常用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集合
  3. 总结:

    (1)set开头:设置方法

    (2)get开头:获取方法

    (3)Set结尾:返回值是Set集合,数据唯一

    (4)-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();

解释:(1)返回值类型是Entry键值对形式数据的Set集合

(2)Set>

其中,Map.Entry:Map接口的内部接口Entry,使用的泛型K,V对应Map创建过程中约束的K,V

因为返回值是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("都比较贵"));
			
 		}
	}
}
1.6 小总结
  1. Map很重要,尤其是HashMap,键值对操作在后期开发中非常常见,数据库、Session、Cookies、数据传递、Json、XML…

  2. 比较器接口一定要是学会使用

    (1)Comparator【重点】自由度非常高,满足各种条件

    (2)Comparable

2. 项目更新

2.1 Comparator接口升级改造
  1. 对排序方法的期望:

    (1)排序的内容有用户决定

    ​ a. 数组

    ​ b. 泛型

    (2)排序的规则由用户决定【暂时决定】

  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;
			}
		}
	}
}
2.2 匿名内部类使用【重点】
2.2.1 说重点思想
  1. 目前,Comparator接口的使用过程

    (1)方法的参数是Comparator接口

    (2)需要完成Comparator接口实现类

    (3)Comparator接口实现类中完成compare方法

    (4)compare方法约束比较规则

  2. 实现类的名字很重要吗?

    (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.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);
		}
		
	}
}
2.2.4 匿名内部类总结
  1. SprigBoot、SpringCloud 框架涉及到JDK1.8 新特征一定要会。比如Lamda、Stream 函数式接口

  2. 匿名内部类格式:

    (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();
}

你可能感兴趣的:(java)