一、LinkedHashSet
特点:
具有可预知迭代顺序 即有序
数据结构为:哈希表和链接列表(链表)实现
此实现是不同步的,即在多线程中是不安全的
二、案例
需求:键盘录入一串字符 abcabdc 按照顺序排列这一串字符(去除重复 ) ==> abcd
代码:
package com.qf.test.test01;
import java.lang.reflect.Array;
import java.util.*;
public class Test01 {
public static void main(String[] args) {
//实例化Scanner
Scanner input = new Scanner(System.in);
System.out.println("请输入一串字符");
String line = input.next();
//将字符转换为字符数组
char[] array = line.toCharArray();
Arrays.sort(array);
//实例化集合
LinkedHashSet link = new LinkedHashSet();
//使用增强for循环遍历数组
for (char c :array){
link.add(c);
}
System.out.println(link);
}
}
三、Map
1.简介
Map是双列集合的顶级接口
2.特点:
将键映射到值的对象 键:key 值:value
一个映射不能包含重复的键,每个键最多只能映射一个值 即键值对 键是唯一的
3.主要实现类:
HashMap TreeMap
4.总结:
Map是 键值对映射的集合
5.单列集合与双列集合的比较:
6.Map集合常用的方法:
7.方法测试:
package com.qf.test.test02;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class Test {
public static void main(String[] args) {
//实例化集合
Map m = new HashMap();
//存入数据
m.put("阿陆","班长");
m.put("黑福","屌丝");
m.put("阿甘","肝王");
//打印集合
System.out.println(m);
//修改集合数据
m.put("阿陆","足浴小王子");
System.out.println(m);
//判断是否有该键
System.out.println(m.containsKey("阿陆"));
System.out.println(m.containsKey("阿文"));
//判断是否有该值
System.out.println(m.containsValue("足浴小王子"));
System.out.println(m.containsValue("爆写"));
//通过键查找值
System.out.println(m.get("阿陆"));
//返回所有键
Set set = m.keySet();
System.out.println(set);
//返回所有值
Collection values = m.values();
System.out.println(values);
//返回集合大小
System.out.println(m.size());
//通过键删除值
m.remove("阿甘");
System.out.println(m);
//清除所有键值
m.clear();
//判断集合是否为空
System.out.println(m.isEmpty());
}
}
8..Map集合遍历的方法
第一种方法:
先获取所有的key,然后使用增强for循环遍历,获取对应的值
第二种方法:
通过entrySet方法,然后使用增强for循环 使用getKey 和 getValue 方法获取键值
测试代码
package com.qf.test.test03;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class Test {
public static void main(String[] args) {
//实例化集合
Map m = new HashMap();
//给集合添加数据
m.put("阿陆","足浴小王子");
m.put("阿甘","卷王");
m.put("黑福","阴阳虚");
//第一种遍历方法
Set set = m.keySet();
for (Object obj :set) {
System.out.println(obj+"\t"+m.get(obj));
}
System.out.println("==================================");
//第二种遍历方法
Set set1 = m.entrySet();
for (Object obj:set1){
Map.Entry entry = (Map.Entry) obj;
System.out.println(entry.getKey()+"\t"+entry.getValue());
}
}
}
9.案例
需求:键盘输入一串字符串,打印每个字符出现的次数
分析:先实例化Scanner 然后将字符串转换为字符数组 在使用增强for循环遍历字符数组 使用Map集合中的containsKey()方法判断
代码:
package com.qf.test.test04;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
//实例化Scanner
Scanner input =new Scanner(System.in);
System.out.println("请输入一串字符串");
String line = input.next();
//将字符串转换为字符数组
char[] array = line.toCharArray();
//实例化集合
Map m = new HashMap();
//使用增强for循环
for (char c : array){
//使用if语句判断
// if(m.containsKey(c)){
// m.put(c,(Integer)(m.get(c))+1);
// }else{
// m.put(c,1);
// }
//使用三元运算符简化代码
m.put(c,m.containsKey(c) ? (Integer)(m.get(c))+1 : 1);
}
System.out.println(m);
}
}
四、HashMap
1.简介:
HashMap是Map接口的实现类
HashMap基于哈希表结构存储
HashMap运行使用null键和null值
HashMap此实现是不同步的,所以在多线程中是不安全的
HashMap的构造默认初始值为16
2.HashMap与HashSet的比较
两个集合都是使用 哈希表结构 来进行存储 HashSet底层使用的是HashMap来进行存储
HashSet使用了HashMap的键的数据结构 来保证数据的唯一性
五、LinkedHashMap
特点:
A.Map 接口的哈希表和链接列表实现
B.具有可预知的迭代顺序
C.此实现不是同步的 在多线程中是不安全的
六、泛型
1.简介:
在定义集合的时候不确定其数据类型,但是在实例化集合的时候可以确定其数据类型的时候,就可以使用泛型。 泛型其实就是一个变量,这个变量用于接收其数据类型
2.泛型的使用:
在实例化对象的时候必须确定其数据类型
如:List<泛型> 对象名 = new ArrayList<泛型>();
3.泛型的好处:
避免强制类型转换
将运行时的错误提前到编译期间
4.泛型的符号:
泛型的符号可以是任意的大写字母,常用的有:E T K W Z......
5.定义泛型类:
语法:
访问修饰符 class 类名<泛型>{
类中的所有成员都可以使用类的泛型,除了静态方法
}
例子:代码
package com.qf.test.test06;
public class MyArrays<K> {
public K[] showInfo(K [] array,int index1,int index2){
K temp = array[index1];
array[index1] = array[index2];
array[index2] = temp;
return array;
}
}
package com.qf.test.test06;
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
MyArrays<Integer> my = new MyArrays();
Integer[] nums=my.showInfo(new Integer[]{11,22,354,74,31},2,4);
System.out.println(Arrays.toString(nums));
}
}
6.定义泛型方法:
语法:
访问修饰符<泛型> 返回值类型 方法名称(参数列表){
方法体;
return 返回值;
}
说明:可以给普通方法加泛型 也可以给静态方法加泛型
注意点:
A.普通成员方法可以使用类的泛型
B.静态方法不能使用类的泛型 因为静态资源优先加载
例子:
package com.qf.test.test07;
public class MyShow {
public <T> void showInfo(T t){
System.out.println(t);
}
public static <T> void show(T t){
System.out.println(t);
}
}
package com.qf.test.test07;
public class Test {
public static void main(String[] args) {
MyShow m = new MyShow();
m.showInfo("ss");
m.showInfo(11);
MyShow.show("ss");
MyShow.show(222);
}
}
7.定义泛型接口:
体现:
A.实现类确定其泛型
B.实现类不确定其泛型
语法:
实现类确定型:
public interface Iterator<E>{
E next()
}
public final class Scanner implements Iterator<String>{
public String next()
}
实现类不确定型:
public interface List<E> {
boolean add(E e)
}
public class ArrayList<E> implements List<E>{
public boolean add(E e)
}
//实现类确定型
package com.qf.test.test08;
public interface Inte<T> {
void show(T t);
}
package com.qf.test.test08;
public class My implements Inte<String> {
@Override
public void show(String s) {
System.out.println(s);
}
}
package com.qf.test.test08;
public class Test {
public static void main(String[] args) {
My m = new My();
m.show("sss");
}
}
//实现类不确定型
package com.qf.test.test09;
public interface Inte<T> {
void show(T t);
}
package com.qf.test.test09;
public class My<T> implements Inte<T> {
@Override
public void show(T t) {
System.out.println(t);
}
}
package com.qf.test.test09;
public class Test {
public static void main(String[] args) {
Inte m = new My();
m.show("ssss");
m.show('a');
m.show(132);
}
}
8.泛型通配符
1.泛型通配符 可以表示任意的数据类型 泛型通配符使用?来进行表示
2.泛型通配符一般作为方法的参数使用 不能实例化集合的时候使用泛型通配符
3.泛型没有继承的概念
4.泛型通配符特殊符号
? extends E E本身或者是其子类
? super T T本身或者是其父类
9.案例
需求:千锋有两个学科 Html5 与java 使用map集合来存储不同的学员 遍历获取学员的信息
代码:
package com.qf.test.test10;
public class Student {
private int sid;
private String name;
private String sex;
private String hobby;
public Student() {
}
public Student(int sid, String name, String sex, String hobby) {
this.sid = sid;
this.name = name;
this.sex = sex;
this.hobby = hobby;
}
public int getSid() {
return sid;
}
public void setSid(int sid) {
this.sid = sid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getHobby() {
return hobby;
}
public void setHobby(String hobby) {
this.hobby = hobby;
}
@Override
public String toString() {
return "Student{" +
"sid=" + sid +
", name='" + name + '\'' +
", sex='" + sex + '\'' +
", hobby='" + hobby + '\'' +
'}';
}
}
package com.qf.test.test10;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class Test {
public static void main(String[] args) {
//实例化学生对象
//java学生
Student stu01 = new Student(10001,"阿陆","男","洗脚");
Student stu02 = new Student(10002,"阿甘","男","卷王");
//定义一个集合存储对象
HashMap<Integer,Student> map1 = new HashMap<>();
map1.put(10001,stu01);
map1.put(10002,stu02);
//HTML5学生
Student stu03 = new Student(10003,"黑福","女","按摩");
Student stu04 = new Student(10004,"阿文","男","观摩");
//定义一个集合存储对象
HashMap<Integer,Student> map2 = new HashMap<>();
map2.put(10003,stu03);
map2.put(10004,stu04);
//定义一个大集合存储两个学生集合
HashMap<String , Map<Integer,Student>> bigMap= new HashMap<>();
bigMap.put("java学生",map1);
bigMap.put("HTML学生",map2);
//打印学生信息 第一种方法
//获取大集合的键
Set<String> strings = bigMap.keySet();
//使用增强for循环遍历
for (String s : strings){
//打印大集合的键
System.out.println(s);
//根据键获取大集合的值 类型为Map集合
Map<Integer, Student> m1 = bigMap.get(s);
//获取学生集合的所有键
Set<Integer> set = m1.keySet();
//使用增强for循环遍历
for (Integer in : set){
//打印学生集合的键和值
System.out.println(in +"\t"+m1.get(in));
}
}
System.out.println("===========================================");
//第二种方法 大集合调用entrySet方法
Set<Map.Entry<String, Map<Integer, Student>>> entries = bigMap.entrySet();
//使用增强循环遍历Set集合
for (Map.Entry<String, Map<Integer, Student>> m :entries){
//打印大集合的键
System.out.println(m.getKey());
//获取大集合的值 值的类型为Map集合
Map<Integer, Student> m2 = m.getValue();
//学生集合将调用entrySet方法
Set<Map.Entry<Integer, Student>> entries1 = m2.entrySet();
//使用增强for循环遍历Set集合
for (Map.Entry<Integer, Student> m3 :entries1){
//打印学生集合的键和值
System.out.println(m3.getKey()+"\t"+m3.getValue());
}
}
}
}
七、案例---斗地主
需求:生成54张扑克牌,然后随机发给三个人 和三张底牌
分析:
代码:
package com.qf.test.test11;
import java.util.*;
public class Test {
public static void main(String[] args) {
//生成扑克牌
//定义一个数组表示花色
String [] color = {"♦","♣","♥","♠"};
//定义一个数组表示点数
String [] nums = {"3","4","5","6","7","8","9","10","J","Q","K","A","2"};
//定义一个变量表示索引
int index = 0;
//定义一个Map集合存储点数
Map<Integer,String> map = new HashMap<>();
//定义一个list集合存储索引
List<Integer> list = new ArrayList<>();
//使用嵌套for循环生成52张牌
for (String n : nums){
for (String c : color){
//将花色与点数拼接
String s = c+n;
//将索引和牌存入map集合
map.put(index,s);
//将索引存入list集合
list.add(index);
//索引自增
index++;
}
}
//生成大小王
map.put(index,"小王");
list.add(index);
map.put(index+1,"大王");
list.add(index+1);
//洗牌 将索引随机排序
//调用jdk提供方法
Collections.shuffle(list);
//发牌 发索引
//使用TreeSet集合存储 因为可以自动排序
//底牌
TreeSet<Integer> dipai = new TreeSet<>();
TreeSet<Integer> lu = new TreeSet<>();
TreeSet<Integer> zhong = new TreeSet<>();
TreeSet<Integer> gan = new TreeSet<>();
//使用循环遍历集合list
for (int i=0;i<list.size();i++){
//使用if语句进行判断
if (i>=list.size()-3){
//发给底牌
dipai.add(list.get(i));
}else if (i%3==0){
//发给lu
lu.add(list.get(i));
}else if (i%3==1){
//发给zhong
zhong.add(list.get(i));
}else if (i%3==2){
//发给gan
gan.add(list.get(i));
}
}
//看牌
show("底牌",dipai,map);
show("阿陆",lu,map);
show("黑福",zhong,map);
show("阿甘",gan,map);
}
public static void show(String name,TreeSet<Integer> t,Map<Integer,String> map){
//定义一个空字符串变量
String s = "";
//使用循环遍历TreeSet集合
for (Integer in : t){
String s1 = map.get(in);
s +=s1+" ";
}
System.out.println(name+"\t"+s);
}
}