目录
get(Object key) - 根据指定的键返回对应的值。如果Map中不包含该键,则返回null。
values() - 返回Map中所有值的集合。同keySet()一样,这也是一个视图。
Java集合框架概述
Java集合框架提供了一组用于存储和操作数据的类和接口,主要分为两大体系:Collection
接口体系和Map
接口体系。Collection
包括List
、Set
和Queue
,而Map
则用于存储键值对。
Set集合
Set
接口是一个不包含重复元素的集合。主要实现类有HashSet
、LinkedHashSet
和TreeSet
。这些集合没有索引,因此不能通过索引进行访问。
HashSet
HashSet
基于哈希表实现,特点是无序、元素不重复。
import java.util.HashSet;
import java.util.Set;
public class HashSetExample {
public static void main(String[] args) {
Set<String> set = new HashSet<>();
set.add("Apple");
set.add("Banana");
set.add("Apple"); // 重复元素不会被添加
for (String item : set) {
System.out.println(item);
}
}
}
注释:HashSet
使用哈希表来存储元素,不能保证元素的顺序。添加重复元素时,不会抛出异常,只是简单地忽略它。
LinkedHashSet
LinkedHashSet
是HashSet
的子类,具有有序性,按照插入顺序保存元素。
import java.util.LinkedHashSet;
import java.util.Set;
public class LinkedHashSetExample {
public static void main(String[] args) {
Set<String> set = new LinkedHashSet<>();
set.add("Apple");
set.add("Banana");
set.add("Apple"); // 重复元素不会被添加
for (String item : set) {
System.out.println(item);
}
}
}
注释:LinkedHashSet
在维护一个双向链表的同时,使用哈希表来存储元素。可以确保迭代顺序与插入顺序一致。
TreeSet
TreeSet
基于红黑树实现,能够对元素进行排序。
import java.util.Set;
import java.util.TreeSet;
public class TreeSetExample {
public static void main(String[] args) {
Set<String> set = new TreeSet<>();
set.add("Banana");
set.add("Apple");
set.add("Cherry");
for (String item : set) {
System.out.println(item); // 输出将按字母顺序排序
}
}
}
注释:TreeSet
确保集合中的元素按照自然顺序(或者通过提供的比较器)进行排序。
Map集合
Map
接口用于存储键值对,每个键对应一个值,键不允许重复。
Map集合常用API
put(K key, V value)
- 向Map中添加键值对。如果Map已包含该键,其关联的值将被新值替换。
Map<String, Integer> stock = new HashMap<>();
stock.put("Apple", 50);
stock.put("Orange", 75);
get(Object key)
- 根据指定的键返回对应的值。如果Map中不包含该键,则返回null
。
Integer appleStock = stock.get("Apple"); // 返回50
Integer bananaStock = stock.get("Banana"); // 由于"Banana"键不存在,返回null
remove(Object key)
- 根据键移除Map中的键值对。如果键存在,则移除键值对并返回对应的值,如果键不存在,则返回null
。
Integer removedStock = stock.remove("Orange"); // 移除"Orange"键,返回75
containsKey(Object key)
- 检查Map中是否包含指定的键。返回true
如果键存在,否则返回false
。
boolean hasApple = stock.containsKey("Apple"); // 检查是否包含"Apple"键,返回true
boolean hasBanana = stock.containsKey("Banana"); // 检查是否包含"Banana"键,返回false
keySet()
- 返回Map中所有键的集合。这个集合是Map的视图,对其的修改会反映到原始Map中。
Set<String> keys = stock.keySet(); // 获取所有键
for (String key : keys) {
System.out.println(key);
}
values()
- 返回Map中所有值的集合。同keySet()
一样,这也是一个视图。
Collection<Integer> values = stock.values();
for (Integer value : values) {
System.out.println(value);
}
entrySet()
- 返回Map中所有键值对的集合。这个集合包含实现了Map.Entry<K, V>
接口的对象。
Set<Map.Entry<String, Integer>> entries = stock.entrySet();
for (Map.Entry<String, Integer> entry : entries) {
System.out.println(entry.getKey() + " has " + entry.getValue() + " units");
}
遍历方式
1. 键找值方式
通过keySet()
方法获取Map中所有键的集合,然后通过循环键集合,使用get(key)
方法获取每个键对应的值。
Map<String, Integer> map = new HashMap<>();
map.put("Apple", 3);
map.put("Banana", 2);
for (String key : map.keySet()) {
System.out.println(key + " -> " + map.get(key));
}
2. 键值对方式
通过entrySet()
方法直接获取Map中的键值对集合,这种方式在遍历时可以同时获取到键和值。
for (Map.Entry<String, Integer> entry : map.entrySet()) {
System.out.println(entry.getKey() + " -> " + entry.getValue());
}
3. Lambda表达式(JDK 8+)
利用Lambda表达式可以更简洁地遍历Map。
map.forEach((key, value) -> System.out.println(key + " -> " + value));
综合案例
假设我们要实现一个简单的投票统计程序,其中Map集合用于存储每个候选人和他们的票数。
Map<String, Integer> votes = new HashMap<>();
votes.put("Alice", 10);
votes.put("Bob", 15);
votes.forEach((candidate, count) -> System.out.println(candidate + " has " + count + " votes"));
HashMap
HashMap
是一个最常用的Map实现,允许存储键值对,键是无序的。
import java.util.HashMap;
import java.util.Map;
public class HashMapExample {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<>();
map.put("Apple", 3);
map.put("Banana", 2);
map.put("Apple", 5); // 覆盖之前的值
for (Map.Entry<String, Integer> entry : map.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
}
}
注释:HashMap
使用哈希表来存储键值对,键值对中的键是无序的。如果插入的键已经存在,则更新其对应的值。
LinkedHashMap
LinkedHashMap
继承自HashMap
,能够保持插入顺序。
import java.util.LinkedHashMap;
import java.util.Map;
public class LinkedHashMapExample {
public static void main(String[] args) {
Map<String, Integer> map = new LinkedHashMap<>();
map.put("Apple", 3);
map.put("Banana", 2);
for (Map.Entry<String, Integer> entry : map.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
}
}
注释:LinkedHashMap
使用链表来维护键值对的顺序,从而可以按插入顺序迭代。
TreeMap
TreeMap
基于红黑树实现,可以对键进行排序。
import java.util.Map;
import java.util.TreeMap;
public class TreeMapExample {
public static void main(String[] args) {
Map<String, Integer> map = new TreeMap<>();
map.put("Banana", 2);
map.put("Apple", 3);
map.put("Cherry", 1);
for (Map.Entry<String, Integer> entry : map.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
}
}
注释:TreeMap
按键的自然顺序进行排序(或按提供的比较器排序)。
集合工具类 Collections
Collections
是一个操作集合的工具类,提供了一些静态方法来操作或返回集合。
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class CollectionsExample {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(3);
list.add(1);
list.add(2);
Collections.sort(list);
System.out.println("Sorted List: " + list);
Collections.shuffle(list);
System.out.println("Shuffled List: " + list);
}
}
注释:Collections.sort()
方法用于对列表进行排序,而Collections.shuffle()
用于随机打乱列表中的元素顺序。
模拟斗地主游戏
1. 创建牌的模型 - Card
类
首先,我们需要一个Card
类来表示每张扑克牌。每张牌由点数(size)、花色(color)和一个用于确定牌大小的索引(index)组成。
public class Card {
private String size; // 点数
private String color; // 花色
private int index; // 牌的大小索引
public Card(String size, String color, int index) {
this.size = size;
this.color = color;
this.index = index;
}
@Override
public String toString() {
return size + color;
}
}
2. 初始化和洗牌 - GameDemo
类
接下来,在GameDemo
类中,我们定义了一个allCards
静态集合来存储全部54张牌,并在静态代码块中初始化牌组。
public static List<Card> allCards = new ArrayList<>();
static {
String[] sizes = {"3","4","5","6","7","8","9","10","J","Q","K","A","2"};
String[] colors = {"♠", "♥", "♣", "♦"};
int index = 0;
for (String size : sizes) {
for (String color : colors) {
allCards.add(new Card(size, color, ++index));
}
}
allCards.add(new Card("", "🃏", ++index));
allCards.add(new Card("", "👲", ++index));
System.out.println("新牌:" + allCards);
}
在主方法中,我们使用Collections.shuffle(allCards);
方法来洗牌,确保牌的随机性。
3. 发牌和排序
定义三个玩家,每个玩家用一个List<Card>
来存储其手中的牌。通过循环分发除底牌外的所有牌:
List<Card> linhuchong = new ArrayList<>();
List<Card> jiumozhi = new ArrayList<>();
List<Card> renyingying = new ArrayList<>();
for (int i = 0; i < allCards.size() - 3; i++) {
Card c = allCards.get(i);
if (i % 3 == 0) linhuchong.add(c);
else if (i % 3 == 1) jiumozhi.add(c);
else renyingying.add(c);
}
使用自定义的sortCards
方法来对玩家手中的牌进行排序:
private static void sortCards(List<Card> cards) {
Collections.sort(cards, (o1, o2) -> o2.getIndex() - o1.getIndex());
}
4. 看牌
最后,打印出每个玩家的手牌和底牌,查看洗牌和发牌的结果:
System.out.println("啊冲:" + linhuchong);
System.out.println("啊鸠:" + jiumozhi);
System.out.println("盈盈:" + renyingying);
System.out.println("三张底牌:" + lastThreeCards);
集合嵌套
在实际开发中,经常会遇到集合嵌套的情况,即集合中的元素本身也是集合。例如,一个Map
的值可以是一个List
。
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class NestedCollectionsExample {
public static void main(String[] args) {
Map<String, List<String>> map = new HashMap<>();
List<String> fruits = new ArrayList<>();
fruits.add("Apple");
fruits.add("Banana");
map.put("Fruits", fruits);
for (Map.Entry<String, List<String>> entry : map.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
}
}