java -- Map接口和可变参数
Map
Map: 映射, 是双列集合顶层接口
java.util.Map<k,v>
k: key 键 唯一
v: value 值 可重复
常用方法和Entry
public V put(K key,V Value)
// 指定的键与指定值添加到Map集合中, 添加成功返回null, 添加失败返回之前的值
public V putIfAbsent(K key,V Value)
// jdk1.8后新增 键相同值不覆盖返回原来的值
public V get(Object key)
// 根据指定的键, 获取对应值, 不存在返回null
public V getOrDefault(Object key, V defaultValue)
// jdk1.8后新增 不存在返回defaultValue
public boolean containsKey(Object key)
// 判断集合中是否包含指定的键
public V remove(Object key)
// 根据指定的键, 删除一对元素, 返回被删除的值
public V remove(Object key, Object value)
// 根据指定的键和值, 都一致则删除, 返回被删除的值
Set<K> keySet()
// 获取存放所有键的Set集合
Collection<V> values()
// 获取存放所有值的集合
Set<Map.Entry<K, V>> entrySet()
// 获取键值对映射关系对象的Set集合
interface Entry<K,V>
K getKey()
// 获取映射关系对象中的键
V getValue()
// 获取映射关系对象中的值
LinkedHashMap
底层数据结构: 链表 + 哈希表
链表保证元素有序 哈希表保证元素唯一
public class Demo {
public static void main(String[] args) {
Map<String, Integer> map = new LinkedHashMap<>();
map.put("1张三",14);
map.put("2李四",17);
// put
// 添加成功返回 null
System.out.println(map.put("3王五", null));
// 添加失败返回之前的值, 并用新值覆盖
System.out.println(map.put("2李四", 19));
// putIfAbsent
// 键不存在添加新的键值对, 添加成功返回null
System.out.println(map.putIfAbsent("4刘六", 19));
// 若键存在 原有值不改变 并返回原有值
System.out.println(map.putIfAbsent("1张三", 11));
// get
// 根据键找值, 存在则返回键对应的值
System.out.println(map.get("1张三"));
// 不存在则返回null
System.out.println(map.get("2"));
// getOrDefault
// 键存在 返回对应值
System.out.println(map.getOrDefault("1张三", -1));
// 若不存在 则返回defaultValue
System.out.println(map.getOrDefault("2", -1));
// 判断集合中是否包含指定的键, 存在返回true, 不存在返回false
System.out.println(map.containsKey("2李四"));
// 根据键删除一对元素 返回被删除的值
// 不存在则返回null
System.out.println(map.remove("1"));
System.out.println(map.remove("1张三"));
System.out.println(map);
// 遍历
// 方式1
// 获取存放所有键的集合
Set<String> set = map.keySet();
// 获取存放所有值的集合
Collection<Integer> values = map.values();
// 迭代器
Iterator<Integer> iterator = values.iterator();
while (iterator.hasNext()) {
System.out.print(iterator.next() + " ");
}
System.out.println();
// 增强for
for (Integer value : values) {
System.out.print(value + " ");
}
System.out.println();
// 迭代器
Iterator<String> it = set.iterator();
while (it.hasNext()) {
String key = it.next();
System.out.print(key + " = " + map.get(key) + "\t");
}
System.out.println();
// 增强for
for (String s : set) {
System.out.print(s + " = " + map.get(s) + "\t");
}
System.out.println();
// 方式2
// Entry是Map的内部类 所以调用时需要Map.Entry
Set<Map.Entry<String, Integer>> entrySet = map.entrySet();
// 迭代器
Iterator< Map.Entry<String, Integer>> entries = entrySet.iterator();
while (entries.hasNext()) {
Map.Entry<String, Integer> next = entries.next();
System.out.print(next.getKey() + " = " + next.getValue() + "\t");
}
System.out.println();
// 增强for
for (Map.Entry<String, Integer> entry : entrySet) {
System.out.print(entry.getKey() + " = "+entry.getValue() + "\t");
}
}
}
TreeMap
java.util.TreeMap
底层数据结构是红黑树 键 排序 具有唯一性 不允许null键 允许null值
/*
java.util.TreeMap
底层数据结构是红黑树 键 排序 具有唯一性 不允许null键 允许null值
构造方法:
public TreeMap() 空参构建, 集合中的键必须实现自然排序接口 Comparable 的方法 CompareTo
public TreeMap(Comparator<? super K> comparator) 需传入比较器对象
*/
public class Demo {
public static void main(String[] args) {
TreeMap<Person, String> map = new TreeMap<>();
map.put(new Person("张三",12),"bj");
map.put(new Person("张三",14),"sh");
map.put(new Person("李四",15),null);
map.put(new Person("王五",11),"gz");
map.put(new Person("宫本",19),"jp");
// 不允许null键
// map.put(null,"us");
System.out.println(map);
// 获取第一个键
System.out.println(map.firstKey());
// 获取最后一个键
System.out.println(map.lastKey());
// 获取第一个键值对
System.out.println(map.firstEntry());
// 获取最后一个键值对
System.out.println(map.lastEntry());
// 获取 按排序方法 取索引 >= 指定键的最小键(>=指定键并距离最近)
System.out.println(map.ceilingKey(new Person("李四", 13)));
// 获取 按排序方法 取索引 >= 指定键的最小键值对(>=指定键并距离最近)
System.out.println(map.ceilingEntry(new Person("李四", 13)));
// 获取 按排序方法 取索引 <= 指定键的最小键(<=指定键并距离最近)
System.out.println(map.floorKey(new Person("李四", 13)));
// 获取 按排序方法 取索引 <= 指定键的最小键值对(<=指定键并距离最近)
System.out.println(map.floorEntry(new Person("李四", 13)));
System.out.println("=================");
TreeMap<Person, String> treeMap = new TreeMap<>(new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
if (o1.age == o2.age) {
return o2.name.compareTo(o1.name);
}
return o1.age - o2.age;
}
});
treeMap.put(new Person("张三",12),"bj");
treeMap.put(new Person("张三",14),"sh");
treeMap.put(new Person("李四",15),null);
treeMap.put(new Person("王五",11),"gz");
treeMap.put(new Person("宫本",19),"jp");
System.out.println(treeMap);
}
}
class Person implements Comparable<Person> {
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public int compareTo(Person o) {
if (o.age == this.age) {
return o.name.compareTo(this.name);
}
return o.age - this.age;
}
@Override
public String toString() {
return "{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
HashMap
/*
java.util.HashMap
底层数据结构是哈希表 允许null键和null值 键是无序的 具有唯一性
先比较hashCode
不同 元素不相同
相同 继续比较equals
相同
不同
因此必须重写hashCode和equals方法
*/
public class Demo {
public static void main(String[] args) {
Map<Person, String> map = new HashMap<Person, String>();
map.put(new Person("张三",12),"bj");
map.put(new Person("李四",12),"sh");
map.put(new Person("王五",12),"gz");
map.put(new Person("宫本",12),"jp");
map.put(null,"us");
Set<Person> peopleSet = map.keySet();
for (Person person : peopleSet) {
if (person == null) {
System.out.println(person + " " + map.get(person));
continue;
}
System.out.println(person.getName() + " " + person.getAge() + " " + map.get(person));
}
Set<Map.Entry<Person, String>> entries = map.entrySet();
for (Map.Entry<Person, String> entry : entries) {
Person key = entry.getKey();
if (key == null) {
System.out.println(key + " " + entry.getValue());
continue;
}
System.out.println(key.getName() + " "+ key.getAge() + " "+entry.getValue());
}
}
}
class Person {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
if (age != person.age) return false;
return name != null ? name.equals(person.name) : person.name == null;
}
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + age;
return result;
}
}
可变参数
在JDK1.5之后,如果我们定义一个方法需要接受多个参数,并且多个参数类型一致,我们可以对其简化.
// 格式
修饰符 返回值类型 方法名(参数类型... 形参名){ }
/*
可变参数 指参数的个数可变
当参数数据类型确定,且需要较多次重载时, 可以使用可变参数
可变参数必须放在参数列表的最后, 且只能有一个可变参数
格式: 本质上就是数组
public static int avg(int... nums)
当不传入参数时, 相当于传了空数组
由于本质是数组, 因此传入数组也可以
*/
public class function {
public static void main(String[] args) {
System.out.println(avg(1,2,3,4,5,7,8,9,2));
System.out.println(avg(18,9,2));
System.out.println(avg(1,2));
int[] arr = {1,23,42,45,34,21};
System.out.println(avg(arr));
}
public static int avg(int... nums) {
int sum = 0;
for (int i = 0; i < nums.length; i++) {
sum += nums[i];
}
return sum / nums.length;
}
}
练习
使用54张牌打乱顺序,三个玩家参与游戏,三人交替摸牌,每人17张牌,最后三张留作底牌.
import java.util.*;
public class PokerDemo {
public static void main(String[] args) {
Map<Integer, String> pokerMap = new HashMap<Integer, String>();
ArrayList<Integer> pokerIndex = new ArrayList<Integer>();
String[] colors = {"♥","♠","♣","♦"};
String[] numbers = "2-A-K-Q-J-10-9-8-7-6-5-4-3".split("-");
int index = 2;
pokerMap.put(0, "大王");
pokerMap.put(1, "小王");
for (String number : numbers) {
for (String color : colors) {
pokerMap.put(index, color+number);
index++;
}
}
for (int i = 0; i < 54; i++) {
pokerIndex.add(i);
}
Collections.shuffle(pokerIndex);
ArrayList<Integer> player1 = new ArrayList<Integer>();
ArrayList<Integer> player2 = new ArrayList<Integer>();
ArrayList<Integer> player3 = new ArrayList<Integer>();
ArrayList<Integer> dipai = new ArrayList<Integer>();
for (int i = 0; i < pokerIndex.size(); i++) {
if (i >= 51){
dipai.add(pokerIndex.get(i));
} else if (i % 3 == 0) {
player1.add(pokerIndex.get(i));
} else if (i % 3 == 1) {
player2.add(pokerIndex.get(i));
} else {
player3.add(pokerIndex.get(i));
}
}
System.out.println("玩家1: " + showPoker(player1, pokerMap));
System.out.println("玩家2: " + showPoker(player2, pokerMap));
System.out.println("玩家3: " + showPoker(player3, pokerMap));
System.out.println("底牌: " + showPoker(dipai, pokerMap));
}
public static String showPoker(ArrayList<Integer> player, Map<Integer, String> pokerMap) {
Collections.sort(player);
StringBuilder sb = new StringBuilder("[");
for (int i = 0; i < player.size(); i++) {
sb.append(pokerMap.get(player.get(i)));
if (i == player.size() - 1) {
sb.append("]");
} else {
sb.append(", ");
}
}
return sb.toString();
}
}