JAVA 基础知识整理-14(集合)Map集合,HashMap、LinkedHashMap,TreeMap

1. Map接口
Map 接口提供三种collection 视图,允许以键集值集合键-值映射关系集的形式查看某个映射的内容。映射的顺序 定义为迭代器在映射的 collection 视图中返回其元素的顺序。某些映射实现可明确保证其顺序,如 TreeMap 类;某些映射实现则不保证顺序,如 HashMap 类。

其常用实现类:HashMap,Hashtable,LinkedHashMap,TreeMap

void clear()
从该地图中删除所有的映射(可选操作)。
default V compute(K key, BiFunction<? super K,? super V,? extends V> remappingFunction)
尝试计算指定键的映射及其当前映射的值(如果没有当前映射, null )。
default V computeIfAbsent(K key, Function<? super K,? extends V> mappingFunction)
如果指定的键尚未与值相关联(或映射到 null ),则尝试使用给定的映射函数计算其值,并将其输入到此映射中,除非 null 。
default V computeIfPresent(K key, BiFunction<? super K,? super V,? extends V> remappingFunction)
如果指定的密钥的值存在且非空,则尝试计算给定密钥及其当前映射值的新映射。
boolean containsKey(Object key)
如果此映射包含指定键的映射,则返回 true 。
boolean containsValue(Object value)
如果此地图将一个或多个键映射到指定的值,则返回 true 。
Set<Map.Entry<K,V>> entrySet()
返回此地图中包含的映射的Set视图。
boolean equals(Object o)
将指定的对象与此映射进行比较以获得相等性。
default void forEach(BiConsumer<? super K,? super V> action)
对此映射中的每个条目执行给定的操作,直到所有条目都被处理或操作引发异常。
V get(Object key)
返回到指定键所映射的值,或 null如果此映射包含该键的映射。
default V getOrDefault(Object key, V defaultValue)
返回到指定键所映射的值,或 defaultValue如果此映射包含该键的映射。
int hashCode()
返回此地图的哈希码值。
boolean isEmpty()
如果此地图不包含键值映射,则返回 true 。
Set keySet()
返回此地图中包含的键的Set视图。
default V merge(K key, V value, BiFunction<? super V,? super V,? extends V> remappingFunction)
如果指定的键尚未与值相关联或与null相关联,则将其与给定的非空值相关联。
V put(K key, V value)
将指定的值与该映射中的指定键相关联(可选操作)。
void putAll(Map<? extends K,? extends V> m)
将指定地图的所有映射复制到此映射(可选操作)。
default V putIfAbsent(K key, V value)
如果指定的键尚未与某个值相关联(或映射到 null )将其与给定值相关联并返回 null ,否则返回当前值。
V remove(Object key)
如果存在(从可选的操作),从该地图中删除一个键的映射。
default boolean remove(Object key, Object value)
仅当指定的密钥当前映射到指定的值时删除该条目。
default V replace(K key, V value)
只有当目标映射到某个值时,才能替换指定键的条目。
default boolean replace(K key, V oldValue, V newValue)
仅当当前映射到指定的值时,才能替换指定键的条目。
default void replaceAll(BiFunction<? super K,? super V,? extends V> function)
将每个条目的值替换为对该条目调用给定函数的结果,直到所有条目都被处理或该函数抛出异常。
int size()
返回此地图中键值映射的数量。
Collection values()
返回此地图中包含的值的Collection视图。

package practicedemo;

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

public class CountLetter1 {
	public static void main(String[] args) {
		String s = "hgfayrgfbhvbcghfvgkhgeuyeg";
		countLetter(s);
	}
	
	public static void countLetter(String s){
		//将字符串转成char[]
		//创建StringBuffer对象
		//创建HashMap
		//遍历char[]数组,并将数组元素和元素个数以键值对的形式添加到HashMap中
		char[] ch = s.toCharArray();
		StringBuffer sb = new StringBuffer();
		HashMap<Character,Integer> hm = new HashMap<Character,Integer>();
		for(char key: ch){
			if(hm.get(key)==null){
				hm.put(key,1);
			}else{
				int val = hm.get(key);
				val++;
				hm.put(key,val);
			}
		}
		Set<Character> keyset = hm.keySet();
		sb.append("{").append("  ");
		for(Character c:keyset){
			int val = hm.get(c);
			sb.append(c).append(":").append(val).append("  ");
		}
		sb.append("}");
		System.out.println(sb);
		
		
		Set<Map.Entry<Character, Integer>> kvset = hm.entrySet();
		for(Map.Entry<Character, Integer> map: kvset){
			System.out.println(map.getKey()+"-----"+map.getValue());
		}
		
		Collection<Integer> c = hm.values();
		for(Integer i:c){
			System.out.println(i);
		}
	}
}
输出:
{  f:3  v:2  g:6  u:1  e:2  b:2  c:1  r:1  a:1  k:1  y:2  h:4  }
f-----3
v-----2
g-----6
u-----1
e-----2
b-----2
c-----1
r-----1
a-----1
k-----1
y-----2
h-----4
3
2
6
1
2
2
1
1
1
1
2
4

2. HashMap
基于哈希表的实现的Map接口。 此实现提供了所有可选的地图操作,并允许null的值和null键。 ( HashMap类大致相当于Hashtable ,除了它是不同步的,并允许null)。

构造方法:

HashMap()
构造一个空的 HashMap ,默认初始容量(16)和默认负载系数(0.75)。
HashMap(int initialCapacity)
构造一个空的 HashMap具有指定的初始容量和默认负载因子(0.75)。
HashMap(int initialCapacity, float loadFactor)
构造一个空的 HashMap具有指定的初始容量和负载因子。
HashMap(Map<? extends K,? extends V> m)
构造一个新的 HashMap与指定的相同的映射 Map 。

常用方法:
void clear()
从这张地图中删除所有的映射。
boolean containsKey(Object key)
如果此映射包含指定键的映射,则返回 true 。
boolean containsValue(Object value)
如果此地图将一个或多个键映射到指定值,则返回 true 。
Set<Map.Entry<K,V>> entrySet()
返回此地图中包含的映射的Set视图。
V get(Object key)
返回到指定键所映射的值,或 null如果此映射包含该键的映射。
boolean isEmpty()
如果此地图不包含键值映射,则返回 true 。
Set keySet()
返回此地图中包含的键的Set视图。
V put(K key, V value)
将指定的值与此映射中的指定键相关联。
V remove(Object key)
从该地图中删除指定键的映射(如果存在)。
int size()
返回此地图中键值映射的数量。
Collection values()
返回此地图中包含的值的Collection视图。

package practicedemo;

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

public class ArrayListHashMap {
	public static void main(String[] args) {
		ArrayList<HashMap<String,Integer>> arr = new ArrayList<HashMap<String,Integer>>();
		HashMap<String,Integer> hm = new HashMap<String,Integer>();
		HashMap<String,Integer> hm1 = new HashMap<String,Integer>();
		HashMap<String,Integer> hm2 = new HashMap<String,Integer>();
		HashMap<String,Integer> hm3 = new HashMap<String,Integer>();
		hm.put("Hello", 12);
		hm.put("Java", 13);
		hm.put("Lingo", 15);
		hm1.put("Kathy", 33);
		hm1.put("Jenny", 30);
		hm2.put("Ruby", 50);
		hm2.put("gaga", 60);
		hm2.put("Ruby", 50);
		hm3.put("Judy", 23);
		arr.add(hm);
		arr.add(hm1);
		arr.add(hm2);
		arr.add(hm3);
		for(HashMap<String,Integer> h:arr){
			Set<Map.Entry<String,Integer>> s = h.entrySet();
			for(Map.Entry<String,Integer> map:s){
				System.out.println(map.getKey()+"----------"+map.getValue());
			}
		}
		
		
	}
}
Lingo----------15
Java----------13
Hello----------12
Kathy----------33
Jenny----------30
gaga----------60
Ruby----------50
Judy----------23

3. LinkedHashMap
哈希表和链表实现的Map接口,具有可预测的迭代次序。 这种实现不同于HashMap,它维持于所有条目的运行双向链表。 此链接列表定义迭代排序,通常是将键插入到地图(插入顺序 )中的顺序 。 请注意,如果将键重新插入到地图中,则插入顺序不受影响。 (A键k被重新插入到地图m如果当m.containsKey(k)将返回true之前立即调用m.put(k, v)被调用。)
注: 这里面的可预测的迭代顺序是指,存储和取出的顺序

构造方法:
LinkedHashMap()
LinkedHashMap(int initialCapacity)
构造具有指定初始容量和默认负载因子(0.75)的空插入订购 LinkedHashMap实例。
LinkedHashMap(int initialCapacity, float loadFactor)
构造具有指定初始容量和负载因子的空插入订购 LinkedHashMap实例。
LinkedHashMap(int initialCapacity, float loadFactor, boolean accessOrder)
构造一个空的 LinkedHashMap实例,具有指定的初始容量,负载因子和订购模式。
LinkedHashMap(Map<? extends K,? extends V> m)
构造具有与指定地图相同映射的插入序列 LinkedHashMap实例。

package practicedemo;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Set;

/**
*@author created by Kathy
*@date 2020年3月18日---上午9:30:33
*@description
*@version
*/
public class LinkedHashMapCountLetter {
	public static void main(String[] args) {
		String s = "hgfayrgfbhvbcghfvgkhgeuyeg我";
		countLetter(s);
	}
	
	public static void countLetter(String s){
		char[] ch = s.toCharArray();
		StringBuffer sb = new StringBuffer();
		LinkedHashMap<Character,Integer> hm = new LinkedHashMap<Character,Integer>();
		for(char key: ch){
			if(hm.get(key)==null){
				hm.put(key,1);
			}else{
				int val = hm.get(key);
				val++;
				hm.put(key,val);
			}
		}
		Set<Character> keyset = hm.keySet();
		sb.append("{").append("  ");
		for(Character c:keyset){
			int val = hm.get(c);
			sb.append(c).append(":").append(val).append("  ");
		}
		sb.append("}");
		System.out.println(sb);
	}
}
{  f:3  g:6  e:2  b:2  c:1  a:1  k:1  h:4  v:2:1  u:1  r:1  y:2  }

4. TreeMap
基于红黑树,如何比较取决于创建时所使用的的构造方法。

构造方法:
TreeMap()
使用其键的自然排序构造一个新的空树状图。
TreeMap(Comparator<? super K> comparator)
构造一个新的,空的树图,按照给定的比较器排序。
TreeMap(Map<? extends K,? extends V> m)
构造一个新的树状图,其中包含与给定地图相同的映射,根据其键的 自然顺序进行排序 。
TreeMap(SortedMap<K,? extends V> m)
构造一个包含相同映射并使用与指定排序映射相同顺序的新树映射。

常用方法:
void clear()
从这张地图中删除所有的映射。
Object clone()
返回此 TreeMap实例的浅拷贝。
Comparator<? super K> comparator()
返回用于订购此地图中的键的比较器,或null如果此地图使用其键的natural ordering 。
boolean containsKey(Object key)
如果此映射包含指定键的映射,则返回 true 。
boolean containsValue(Object value)
如果此地图将一个或多个键映射到指定值,则返回 true 。
Set<Map.Entry<K,V>> entrySet()
返回此地图中包含的映射的Set视图。
K firstKey()
返回此地图中当前的第一个(最低)键。
Map.Entry<K,V> floorEntry(K key)
返回与小于或等于给定键的最大键相关联的键值映射,如果没有此键,则 null 。
V get(Object key)
返回到指定键所映射的值,或 null如果此映射包含该键的映射。
Set keySet()
返回此地图中包含的键的Set视图。
NavigableSet navigableKeySet()
返回此地图中包含的键的NavigableSet视图。
V put(K key, V value)
将指定的值与此映射中的指定键相关联。
void putAll(Map<? extends K,? extends V> map)
将指定地图的所有映射复制到此地图。
V remove(Object key)
从此TreeMap中删除此键的映射(如果存在)。
V replace(K key, V value)
只有当目标映射到某个值时,才能替换指定键的条目。
boolean replace(K key, V oldValue, V newValue)
仅当当前映射到指定的值时,才能替换指定键的条目。
void replaceAll(BiFunction<? super K,? super V,? extends V> function)
将每个条目的值替换为对该条目调用给定函数的结果,直到所有条目都被处理或该函数抛出异常。
int size()
返回此地图中键值映射的数量。
NavigableMap<K,V> subMap(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive)
返回此地图部分的视图,其关键范围为 fromKey至 toKey 。
SortedMap<K,V> subMap(K fromKey, K toKey)
返回此地图部分的视图,其关键字范围从 fromKey (含)到 toKey ,独占。
SortedMap<K,V> tailMap(K fromKey)
返回此地图部分的视图,其键大于等于 fromKey 。
NavigableMap<K,V> tailMap(K fromKey, boolean inclusive)
返回此地图部分的视图,其键大于(或等于,如果 inclusive为真) fromKey 。
Collection values()
返回此地图中包含的值的Collection视图。

注:实现排序要实现Comparable接口,或者在创建对象时传入比较器。Character,String等包装类因为已经实现了Comparable的compareTo方法所以不需要做上述的处理,如果比较的是自定义的对象那么就必须要实现接口或者传入比较器。

package practicedemo;

import java.util.Set;
import java.util.TreeMap;

/**
*@author created by Kathy
*@date 2020年3月18日---上午9:44:22
*@description
*@version
*/
public class TreeMapCountLetters {
	public static void main(String[] args) {
		String s = "hgfayrgfbhvbcghfvgkhgeuyeg我";
		countLetter(s);
	}
	public static void countLetter(String s){
		char[] ch = s.toCharArray();
		StringBuffer sb = new StringBuffer();
		TreeMap<Character,Integer> hm = new TreeMap<Character,Integer>();
		for(char key: ch){
			if(hm.get(key)==null){
				hm.put(key,1);
			}else{
				int val = hm.get(key);
				val++;
				hm.put(key,val);
			}
		}
		Set<Character> keyset = hm.keySet();
		sb.append("{").append("  ");
		for(Character c:keyset){
			int val = hm.get(c);
			sb.append(c).append(":").append(val).append("  ");
		}
		sb.append("}");
		System.out.println(sb);
	}
	
}
{  a:1  b:2  c:1  e:2  f:3  g:6  h:4  k:1  r:1  u:1  v:2  y:2:1  }

5. Collections
此类仅由静态方法组合或返回集合。 它包含对集合进行操作的多态算法,“包装器”,返回由指定集合支持的新集合,以及其他一些可能的和最终的。
如果提供给它们的集合或类对象为null,则此类的方法都抛出一个NullPointerException 。

方法:
static boolean addAll(Collection<? super T> c, T… elements)
将所有指定的元素添加到指定的集合。
static Queue asLifoQueue(Deque deque)
返回Deque作为先进先出( Lifo ) Queue的视图 。
static int binarySearch(List<? extends Comparable<? super T>> list, T key)
使用二叉搜索算法搜索指定对象的指定列表。
static int binarySearch(List<? extends T> list, T key, Comparator<? super T> c)
使用二叉搜索算法搜索指定对象的指定列表。
static Collection checkedCollection(Collection c, 类 type)
返回指定集合的动态类型安全视图。
static List checkedList(List list, 类 type)
返回指定列表的动态类型安全视图。
static <K,V> Map<K,V> checkedMap(Map<K,V> m, 类 keyType, 类 valueType)
返回指定地图的动态类型安全视图。
static <K,V> NavigableMap<K,V> checkedNavigableMap(NavigableMap<K,V> m, 类 keyType, 类 valueType)
返回指定可导航地图的动态类型安全视图。
static NavigableSet checkedNavigableSet(NavigableSet s, 类 type)
返回指定的可导航集的动态类型安全视图。
static Queue checkedQueue(Queue queue, 类 type)
返回指定队列的动态类型安全视图。
static Set checkedSet(Set s, 类 type)
返回指定集合的动态类型安全视图。
static <K,V> SortedMap<K,V> checkedSortedMap(SortedMap<K,V> m, 类 keyType, 类 valueType)
返回指定排序映射的动态类型安全视图。
static SortedSet checkedSortedSet(SortedSet s, 类 type)
返回指定排序集的动态类型安全视图。
static void copy(List<? super T> dest, List<? extends T> src)
将所有元素从一个列表复制到另一个列表中。
static boolean disjoint(Collection<?> c1, Collection<?> c2)
如果两个指定的集合没有共同的元素,则返回 true 。
static Enumeration emptyEnumeration()
返回没有元素的枚举。
static Iterator emptyIterator()
返回没有元素的迭代器。
static List emptyList()
返回空列表(immutable)。
static ListIterator emptyListIterator()
返回没有元素的列表迭代器。
static <K,V> Map<K,V> emptyMap()
返回空的地图(不可变)。
static <K,V> NavigableMap<K,V> emptyNavigableMap()
返回空导航地图(不可变)。
static NavigableSet emptyNavigableSet()
返回一个空导航集(immutable)。
static Set emptySet()
返回一个空集(immutable)。
static <K,V> SortedMap<K,V> emptySortedMap()
返回空的排序映射(immutable)。
static SortedSet emptySortedSet()
返回一个空的排序集(immutable)。
static Enumeration enumeration(Collection c)
返回指定集合的枚举。
static void fill(List<? super T> list, T obj)
用指定的元素代替指定列表的所有元素。
static int frequency(Collection<?> c, Object o)
返回指定集合中与指定对象相等的元素数。
static int indexOfSubList(List<?> source, List<?> target)
返回指定源列表中指定目标列表的第一次出现的起始位置,如果没有此类事件,则返回-1。
static int lastIndexOfSubList(List<?> source, List<?> target)
返回指定源列表中指定目标列表的最后一次出现的起始位置,如果没有此类事件则返回-1。
static ArrayList list(Enumeration e)
返回一个数组列表,其中包含由枚举返回的顺序由指定的枚举返回的元素。
static <T extends Object & Comparable<? super T>>
T max(Collection<? extends T> coll)
根据其元素的 自然顺序返回给定集合的最大元素。
static T max(Collection<? extends T> coll, Comparator<? super T> comp)
根据指定的比较器引发的顺序返回给定集合的最大元素。
static <T extends Object & Comparable<? super T>>
T min(Collection<? extends T> coll)
根据其元素的 自然顺序返回给定集合的最小元素。
static T min(Collection<? extends T> coll, Comparator<? super T> comp)
根据指定的比较器引发的顺序返回给定集合的最小元素。
static List nCopies(int n, T o)
返回由指定对象的 n副本组成的不可变列表。
static Set newSetFromMap(Map<E,Boolean> map)
返回由指定地图支持的集合。
static boolean replaceAll(List list, T oldVal, T newVal)
将列表中一个指定值的所有出现替换为另一个。
static void reverse(List<?> list)
反转指定列表中元素的顺序。
static Comparator reverseOrder()
返回一个比较器,它对实现 Comparable接口的对象集合施加了 自然排序的相反。
static Comparator reverseOrder(Comparator cmp)
返回一个比较器,它强制指定比较器的反向排序。
static void rotate(List<?> list, int distance)
将指定列表中的元素旋转指定的距离。
static void shuffle(List<?> list)
使用默认的随机源随机排列指定的列表。
static void shuffle(List<?> list, Random rnd)
使用指定的随机源随机排列指定的列表。
static Set singleton(T o)
返回一个只包含指定对象的不可变集。
static List singletonList(T o)
返回一个只包含指定对象的不可变列表。
static <K,V> Map<K,V> singletonMap(K key, V value)
返回一个不可变的地图,只将指定的键映射到指定的值。
static <T extends Comparable<? super T>>
void sort(List list)
根据其元素的natural ordering对指定的列表进行排序。
static void sort(List list, Comparator<? super T> c)
根据指定的比较器引起的顺序对指定的列表进行排序。
static void swap(List<?> list, int i, int j)
交换指定列表中指定位置的元素。
static Collection synchronizedCollection(Collection c)
返回由指定集合支持的同步(线程安全)集合。
static List synchronizedList(List list)
返回由指定列表支持的同步(线程安全)列表。
static <K,V> Map<K,V> synchronizedMap(Map<K,V> m)
返回由指定地图支持的同步(线程安全)映射。
static <K,V> NavigableMap<K,V> synchronizedNavigableMap(NavigableMap<K,V> m)
返回由指定的可导航地图支持的同步(线程安全)可导航地图。
static NavigableSet synchronizedNavigableSet(NavigableSet s)
返回由指定的可导航集支持的同步(线程安全)可导航集。
static Set synchronizedSet(Set s)
返回由指定集合支持的同步(线程安全)集。
static <K,V> SortedMap<K,V> synchronizedSortedMap(SortedMap<K,V> m)
返回由指定的排序映射支持的同步(线程安全)排序映射。
static SortedSet synchronizedSortedSet(SortedSet s)
返回由指定的排序集支持的同步(线程安全)排序集。
static Collection unmodifiableCollection(Collection<? extends T> c)
返回指定集合的不可修改视图。
static List unmodifiableList(List<? extends T> list)
返回指定列表的不可修改视图。
static <K,V> Map<K,V> unmodifiableMap(Map<? extends K,? extends V> m)
返回指定地图的不可修改视图。
static <K,V> NavigableMap<K,V> unmodifiableNavigableMap(NavigableMap<K,? extends V> m)
返回指定可导航地图的不可修改视图。
static NavigableSet unmodifiableNavigableSet(NavigableSet s)
返回指定的可导航集合的不可修改的视图。
static Set unmodifiableSet(Set<? extends T> s)
返回指定集合的不可修改视图。
static <K,V> SortedMap<K,V> unmodifiableSortedMap(SortedMap<K,? extends V> m)
返回指定排序映射的不可修改视图。
static SortedSet unmodifiableSortedSet(SortedSet s)
返回指定排序集的不可修改视图。

案例,模拟洗牌和发牌

package playcards;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Set;
import java.util.TreeMap;

public class PlayCardsDemo {
	private static  HashMap<Integer,String> hm = new HashMap<Integer,String>();
	private static ArrayList<Integer> arr = new ArrayList<Integer>();
	private static TreeMap<Integer,String> tskathy = new  TreeMap<Integer,String>() ;
	private static TreeMap<Integer,String> tsjohn= new  TreeMap<Integer,String>() ;
	private static TreeMap<Integer,String> tszhang= new  TreeMap<Integer,String>() ;
	//private TreeMap<Integer,String> tsliu;
	private static TreeMap<Integer,String> dipai= new  TreeMap<Integer,String>() ;
	private static HashMap<String,TreeMap<Integer,String>> h = new HashMap<String,TreeMap<Integer,String>>();
	//private static Integer index=0;
	
	public static void buildCards(){
		String[] num = {"A","2","3","4","5","6","7","8","9","10","J","Q","K"};
		String[] color = {"♠","♥","♣","♢"};
		int index = 0;
		for(String n:num){
			for(String c: color){
				String card = n.concat(c);
				//System.out.println(card);
				arr.add(index);
				hm.put(index, card);
				index++;
			}			
		}
		
		hm.put(index, "小王");
		index++;
		hm.put(index, "大王");
		Collections.shuffle(arr);
		//System.out.println(arr);
		Set<Integer> keyset = hm.keySet();

		
		for(int i=0;i<arr.size();i++){
			if(i>(arr.size()-3)){
				String val =hm.get(arr.get(i));
				dipai.put(i,val);
			}else if(i%3==0){
				String val =hm.get(arr.get(i));
				tskathy.put(i,val);
			}else if(i%3==1){
				String val =hm.get(arr.get(i));
				tsjohn.put(i,val);
			}else if(i%3==2){
				String val =hm.get(arr.get(i));
				tszhang.put(i,val);
			}
		}
		h.put("dipai:", dipai);
		h.put("Kathy:", tskathy);
		h.put("John:", tsjohn);
		h.put("tszhang:", tszhang);
		checkCards( h);
	}
	
	public static void checkCards(HashMap<String,TreeMap<Integer,String>> h){
		Set<String> keyset = h.keySet();		
		//sb.append("{ ");
		for(String key: keyset){
			StringBuffer sb = new StringBuffer();
			sb.append(key).append("{  ");
			TreeMap<Integer,String> val = h.get(key);
			Set<Integer> innerkeyset = val.keySet();
			for(Integer innerkey: innerkeyset){
				String v = val.get(innerkey);
				sb.append(v+"  ");
			}
			sb.append("  }");
			System.out.println(sb);
		}
		
		
	}
	
	public static void main(String[] args) {
		buildCards();
	}
}

John:{  1094♥  J♣  78458♥  K♠  K♣  3102262}
Kathy:{  633♣  A♢  J♥  A♥  54♢  K♢  891067710♥  J♢    }
dipai:{  9♠  Q♥    }
tszhang:{  Q♢  K♥  5♥  A♠  9♥  Q♣  235♢  A♣  784♠  J♠  Q♠  6}
发布了55 篇原创文章 · 获赞 0 · 访问量 2068

猜你喜欢

转载自blog.csdn.net/KathyLJQ/article/details/104916402