day17学习笔记

一 回顾

1.hashcode值
   方法:public int hashCode() 返回该对象的哈希码值
2.不能根据hashcode值判断是否是同一对象
3.String 重写hashcode方法  字符串内容相同 hashcode值相同
4.注意点:字符串中存在hash冲突 字符串内容不相同 但是hashcode值相同
5.HasshSet
   A.此类实现 Set 接口
   B.由哈希表
       在jdk1.8 之前 数组+链表
       在jdk1.8之后  数组+链表 或者红黑树
   C.此实现不是同步的 在多线程中是不安全的
 6.TreeSet
   特点:
     A. 自然顺序对元素进行排序
     B.此实现不是同步的 在多线程中不安全
   排序规则:
      数值类型 按照升序(从小到大)来进行排列
      字符串类型 按照首字母的ascmall码表来进行排序
      自定义引用数据类型: 必须指定其排序规则  否则报错
   自定义引用数据类型排序
      A.在定义类的中实现  Comparable
           this -object  >0  升序
           this -object  =0 表示是相同的元素  不会插入元素
           this -object < 0  降序
         步骤:
            a.实现这个接口 Comparable
            b.int compareTo(T o)  
            
      B.在实例化集合指定排序规则
         public TreeSet(Comparator<? super E> comparator)
   

二 LinkedHashSet

1.特点:
    A.具有可预知迭代顺序  有序
    B.哈希表和链接列表实现
    C.此实现不是同步的 在多线程中是不安全 

三 案例

step01 需求 键盘录入一串字符 abcabdc 按照顺序排列这一串字符(去除重复 ) ==> abcd

step02 分析

A.有序 
B.唯一 去除重复
C.使用 LinkedHashSet

step03 代码

package com.qf.test01;
​
import java.util.LinkedHashSet;
import java.util.Scanner;
​
public class Test01 {
    public static void main(String[] args) {
        //实例化Scanner
        Scanner input  = new Scanner(System.in);
        System.out.println("请输入一串字符");
        //接收一串字符
        String line = input.nextLine();
        //将字符串转换为字符数组
        char[] array = line.toCharArray();
        //实例化集合存储数据
        LinkedHashSet linkedHash  = new LinkedHashSet();
        //使用循环遍历数组
        for (char c : array) {
            linkedHash.add(c);
​
        }
​
        System.out.println(linkedHash);
​
​
    }
}
​

四 Map

4.1 简介

1.Map 翻译: 地图   点====>具体的位置  Map是双列集合的顶级接口
  生活中对应关系: ip ==>主机    丈夫 ==>妻子   人 ==>身份证
2.特点:
    A.将键映射到值的对象 key 键   value 值   
    B.一个映射不能包含重复的键;每个键最多只能映射到一个值   键值对  键是唯一
3.实现类
    HashMap  TreeMap
4.总结: 键值对映射的集合

4.2 单列集合与双列集合的比较编辑

 

 

4.3 Map集合常用的方法

方法名称方法描述
void clear() 清除集合中所有元素
boolean containsKey(Object key) 判断键是否存在
boolean containsValue(Object value) 判断值是否存在
Set<Map.Entry<K,V>> entrySet() 用于遍历map集合
V get(Object key) 根据键来获取值
boolean isEmpty() 判断集合是否为空
Set<K> keySet() 获取所有的键(key)
V put(K key, V value) 增加(键不存在)/修改(键存在)
V remove(Object key) 根据键删除集合中键值对
int size() 获取集合长度
Collection<V> values() 获取所有的值

代码

package com.qf.test02;
​
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
​
public class Test01 {
    public static void main(String[] args) {
        //实例化集合
        Map  m  = new HashMap();
        //存入数据
        m.put("吴亦凡","都美竹");
        m.put("王宝强","马蓉");
        m.put("罗志祥","时间管理大师");
        m.put("严进林","小泽老师");
        System.out.println(m);
        //修改数据
        m.put("吴亦凡","18岁少女");
        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("吴亦凡"));
        //根据键删除键值对
        m.remove("吴亦凡");
        System.out.println(m);
​
        //获取所有键
        Set set = m.keySet();
        System.out.println(set);
        //获取所有值
        Collection coll = m.values();
        System.out.println(coll);
        //获取集合长度
        System.out.println(coll.size());
        //清空集合
        m.clear();
        //判断集合是否为空
        System.out.println(m.isEmpty());
​
​
    }
}
​

4.4 map集合遍历

4.4.1 第一种方式编辑

 

 

代码

package com.qf.test02;
​
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
​
public class Test02 {
    public static void main(String[] args) {
        //实例化集合
        Map  m = new HashMap();
        m.put("黄晓明","杨颖");
        m.put("邓超","孙丽");
        m.put("贾乃亮","李小璐");
        m.put("王宝强","马蓉");
        //获取所有键
        Set set = m.keySet();
        //使用循环遍历
        for(Object obj :set) {
            System.out.println(obj+"\t"+m.get(obj));
        }
​
    }
}
​

4.4.2 第二种遍历方式编辑

 

 

代码

package com.qf.test02;
​
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
​
public class Test03 {
    public static void main(String[] args) {
        Map m = new HashMap();
        m.put("黄晓明","杨颖");
        m.put("邓超","孙丽");
        m.put("贾乃亮","李小璐");
        m.put("王宝强","马蓉");
        //获取集合(每一组键值对的对象)
        Set set = m.entrySet();
        //使用循环遍历
        for (Object obj : set) {
            Map.Entry  entry = (Map.Entry) obj;
            //调用对象的方法获取键值对
            System.out.println(entry.getKey()+"\t"+entry.getValue());
​
        }
​
    }
}
​

4.5 案例

step01 需求:键盘录入一串字符 统计每一个字符出现的次数 例如 abcabcc ==> a ==2 b ==2 c==3

step02 分析

A.使用Scanner
B.将字符串转换为字符数组  public char[] toCharArray()
C.使用键值对的集合  Map集合  键: 字符   值 次数
    boolean containsKey(Object key)
   如果键在集合中存在
         获取上一次的记录+1
   如果键不存在
         将值设置为1
​

step03 代码

package com.qf.test02;
​
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
​
public class Test04 {
    public static void main(String[] args) {
        //实例化Scanner
        Scanner  input  = new Scanner(System.in);
        System.out.println("请输入一串字符");
        String line = input.nextLine();
        //将字符串转换为字符数组
        char[] array = line.toCharArray();
        //实例化集合
        Map m = new HashMap();
        //使用循环遍历
        for (char c: array) {
            //判断键是否存在
//            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

5.1 简介

1.Map接口的实现类
2.基于基于哈希表结构存储
3.允许使用 null 值和 null 键
4.此实现不是同步的 在多线程中不安全的
5.构造一个具有默认初始容量 16

5.2 HashMap 与HashSet的比较

  A.都是使用hash结构表来进行存储 HashSet集合的底层也是使用HashMap来进行存储
  B.HashSet使用 HashMap的键的数据结构 保证数据的唯一性

编辑

 

编辑

 

 

 

六 LinkedHashMap

A.Map 接口的哈希表和链接列表实现
B.具有可预知的迭代顺序
C.此实现不是同步的 在多线程中是不安全的

代码

package com.qf.test02;

import java.util.LinkedHashMap;

public class Test05 {
    public static void main(String[] args) {
        //实例化集合
        LinkedHashMap map  = new LinkedHashMap();
        map.put("a","薛之谦");
        map.put("c","周杰伦");
        map.put("b","林俊杰");
        map.put("d","毛不易");
        System.out.println(map);
    }
}


七 泛型

7.1 简介

1.使用场景:在定义集合时候不确定其数据类型  但是在实例化集合的时候可以确定其数据类型 就可以使用泛型
          泛型其实就是一个变量  这个变量用于来接收其数据类型
2.泛型使用:
    A.在实例化对象的时候必须确定其数据类型
    B.例子:List<泛型> 对象名 = new ArrayList<泛型>();
    C.注意点:
        a.前后的泛型都必须是一致
        b.在jdk1.7 之后 出现了菱形的泛型  后面的泛型可以省略
        c.泛型只能使用引用数据类型  不能使用基本数据类型
 3.泛型的好处:
     A.避免强制类型转换
     B.将运行时错误提前到编译期间
 4.使用泛型的符号
    泛型的符号使用的都是一些大写的字母 任意的大写字母都是可以
    常用的大写字母: E K  V  T   W  Z...... 
编辑

 

 

7.2 定义泛型类

1.语法:
   访问修饰符  class 类名<泛型> {
       类中的所有成员都可以使用类的泛型
   }
2.例子:
  public  class PageInfo<T>{
     
  }

step 01-代码-定义泛型类

package com.qf.test04;
​
import java.util.ArrayList;
import java.util.List;
​
/**
 * 定义泛型类
 * @param <T>
 */
public class MyArrayList<T>{
    //实例化集合
    List<T> list  = new ArrayList<>();
​
    //设置集合中元素
    public  void set(T  t){
        list.add(t);
    }
​
    //获取集合中元素
    public  T  get(int index){
        return list.get(index);
    }
​
​
}
​
​

step02 -代码-测试类

package com.qf.test04;
​
public class Test01 {
    public static void main(String[] args) {
        //实例化对象
        MyArrayList<Integer> list01  = new MyArrayList<>();
        list01.set(11);
        System.out.println(list01.get(0));
        //实例化对象
        MyArrayList<String> list02 = new MyArrayList<>();
        list02.set("张三");
        System.out.println(list02.get(0));
    }
}
​
​

7.3 定义泛型方法

1.语法:
  访问修饰符<泛型>返回值类型 方法名称(参数列表) {
      方法体;
      return 返回值;
  }
2.例子:
    public  <T>  void  showInfo(T t){
        
    }
3.说明:
    可以给普通方法加泛型  也可以给静态方法加泛型
4.注意点:
    A.普通成员方法可以使用类的泛型
    B.静态方法不能使用类的泛型 因为静态资源优先加载
​

step01-代码-定义泛型方法

package com.qf.test05;

public class My <T>{
    public    void  showInfo(T t){
        System.out.println(t);
    }

    public  static <T> void  show(T t){
        System.out.println(t);
    }


}


step02-代码-定义测试类

package com.qf.test05;

public class Test01 {
    public static void main(String[] args) {
        My m  = new My();
        m.showInfo("sss");
        m.showInfo(12);
        My.show("kk");

    }
}


7.4 案例

step01 需求

编辑

 

 

step02 分析

A.数组数据类型使用泛型
B.数组交换元素需要通过索引
C.定义成泛型方法

step03 代码-定义泛型方法

package com.qf.test06;

public class MyArrays {

    public static <T>T[] showInfo(T[] arrays, int index1,int index2) {
        //交互数组的元素
        T temp = arrays[index1];
        arrays[index1] =arrays[index2];
        arrays[index2] = temp;
       return    arrays;

    }
}


step04-代码-测试类

package com.qf.test06;

import java.util.Arrays;

public class Test01 {
    public static void main(String[] args) {
        Integer[] nums = MyArrays.showInfo(new Integer[]{2, 3, 4, 5}, 0, 1);
        System.out.println(Arrays.toString(nums));
    }
}


7.5 定义泛型接口

1.体现:A.实现类确定其泛型   B.实现类不确定其泛型
2.实现类确定其泛型
   public interface Iterator<E>{
       E next()
   }
   public final class Scanner implements Iterator<String>{
         public String next()
   
   }
3.实现类不确定其泛型
   public interface List<E> {
       boolean add(E e)
   }
   public class ArrayList<E> implements List<E>{
         public boolean add(E e)
   } 

第一种体现

step01-定义接口

package com.qf.test07;

public interface Inner <T>{

      void  showInfo(T t);
}


step02-定义实现类

package com.qf.test07;
​
public class Impl implements  Inner<String> {
    @Override
    public void showInfo(String s) {
        System.out.println(s);
    }
}
​
​

step03-测试类

package com.qf.test07;
​
public class Test01 {
    public static void main(String[] args) {
        //实例化实现类
        Impl im = new Impl();
        im.showInfo("sssss");
        //im.showInfo(12);
    }
}
​
​

第二种体现

step01-代码-定义接口

package com.qf.test08;
​
public interface Inner <T>{
    void showInfo(T t);
}
​
​

step02-代码-实现类

package com.qf.test08;

public class Impl<T> implements  Inner<T> {
    @Override
    public void showInfo(T t) {
        System.out.println(t);
    }
}


step03-代码-测试类

package com.qf.test08;

public class Test01 {
    public static void main(String[] args) {
        Inner in = new Impl();
        in.showInfo("111");
        in.showInfo(12);
    }
}


7.6 泛型通配符

1.泛型通配符 可以表示任意的数据类型  泛型通配符使用?来进行表示
2.泛型通配符一般作为方法的参数使用 不能实例化集合的时候使用泛型通配符 
3.泛型没有继承的概念
4.泛型通配符特殊符号
     ? extends E  E本身或者是其子类
     ? super T  T本身或者是其父类

代码

package com.qf.test09;
​
import javax.print.attribute.standard.NumberUp;
import java.util.ArrayList;
import java.util.List;
​
public class Test01 {
    public static void main(String[] args) {
//        List<String> li = new ArrayList<>();
//        li.add("张三");
//        li.add("李四");
//        li.add("王五");
        //showInfo(li);
        //实例化集合
        //List<?> list = new ArrayList<?>();
​
        List<Number> list01 = new ArrayList<>();
        showInfo(list01);
​
        List<Integer> list02 = new ArrayList<>();
        showInfo(list02);
        List<Object> list03 = new ArrayList<>();
        showInfo(list03);
    }
​
   //Integer  Number  Object
    //Integer extends Number
    //Number  extends Object
    public  static   void  showInfo(List<? super Number> list){
​
       /*  for (Object obj : list) {
             System.out.println(obj);
         }*/
    }
​
​
}
​
​

7.7 案例

step01 需求 千锋有两个学科 Html5 与java 使用map集合来存储不同的学员 遍历获取学员的信息

step02-代码-定义学生类

package com.qf.test09;
​
public class Student {
    private  int sid;
    private  String name;
    private  String sex;
    private  String hobbey;
​
    public Student() {
    }
​
    public Student(int sid, String name, String sex, String hobbey) {
        this.sid = sid;
        this.name = name;
        this.sex = sex;
        this.hobbey = hobbey;
    }
​
    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 getHobbey() {
        return hobbey;
    }
​
    public void setHobbey(String hobbey) {
        this.hobbey = hobbey;
    }
​
    @Override
    public String toString() {
        return "Student{" +
                "sid=" + sid +
                ", name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                ", hobbey='" + hobbey + '\'' +
                '}';
    }
}
​
​

step02-代码-定义测试类

package com.qf.test09;
​
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
​
public class Test02 {
    public static void main(String[] args) {
        //实例化java学生对象
        Student stu01 = new Student(1001,"阿飞","男","各种会所");
        Student stu02 = new Student(1002,"阿超","女","各种表妹");
        Student stu03 = new Student(1003,"李焕荣","男","超级按摩师");
        //实例化map集合存储java 学员
        Map<Integer,Student> map  = new HashMap<>();
        map.put(1001,stu01);
        map.put(1002,stu02);
        map.put(1003,stu03);
​
​
​
​
        //实例化Html5学生对象
        Student stu04 = new Student(1004,"王统一","男","洗脚");
        Student stu05 = new Student(1005,"李文强","男","撸代码");
        Student stu06 = new Student(1006,"江伟","男","各种老师");
        //实例化map集合存储Html学员
        Map<Integer,Student> map1 = new HashMap<>();
        map1.put(1004,stu04);
        map1.put(1005,stu05);
        map1.put(1006,stu06);
​
        //实例化大的map来存储html与java的学员
        Map<String,Map<Integer,Student>> bigMap =  new HashMap<>();
        bigMap.put("java",map);
        bigMap.put("html5",map1);
​
        //使用第一种遍历方式  获取键 通过键获取值
        Set<String> set = bigMap.keySet();
        for (String s :set){
            System.out.println(s);
            //根据键获取值
            Map<Integer, Student> m = bigMap.get(s);
            //获取所有键
            Set<Integer> set01 = m.keySet();
            //使用增强for循环遍历
            for (Integer in :set01) {
                System.out.println(in+"\t"+m.get(in));
​
            }
​
​
        }
​
        System.out.println("==============================================");
        //使用第二种遍历方式   将键值对封装对象 调用对象的方法获取
        Set<Map.Entry<String, Map<Integer, Student>>> entries = bigMap.entrySet();
        //使用迭代器遍历
        Iterator<Map.Entry<String, Map<Integer, Student>>> iterator = entries.iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, Map<Integer, Student>> next = iterator.next();
            System.out.println(next.getKey());
            Map<Integer, Student> map2 = next.getValue();
            Set<Map.Entry<Integer, Student>> entries1 = map2.entrySet();
            //转换迭代器
            Iterator<Map.Entry<Integer, Student>> iterator1 = entries1.iterator();
            while (iterator1.hasNext()) {
                Map.Entry<Integer, Student> entry = iterator1.next();
                System.out.println(entry.getKey() +"\t" + entry.getValue());
            }
        }
​
    }
}
​
​

7.8 斗地主案例

step01 需求-分析

编辑

 

 

step02 代码

package com.qf.test10;
​
import java.util.*;
​
public class Test01 {
    public static void main(String[] args) {
        //生成扑克牌
        //定义一个数组表示花色
        String  []  colors ={"♦","♣","♥","♠"};
        //定义一个数组表示点数
        String [] nums ={"3","4","5","6","7","8","9","10","J","Q","K","A","2"};
        //实例化Map集合 存储扑克牌
        Map<Integer,String> map = new HashMap<>();
        //定义一个集合来存储其索引值
        List<Integer> list  = new ArrayList<>();
        //定义一个变量来记录其索引
        int index=0;
        //使用循环生成52张牌
        for (String  n :nums) {
            for (String w: colors) {
                String num =w+n;
                map.put(index,num);
                list.add(index);
                //索引需要递增
                index++;
​
            }
        }
        //System.out.println(index);
        //生成小王
        map.put(index,"小王");
        list.add(index);
        //索引递增
        index++;
        map.put(index,"大王");
        list.add(index);
//        System.out.println(map);
//        System.out.println(list);
​
        //洗牌 洗索引
        Collections.shuffle(list);
​
        //发牌  发索引
        TreeSet dipai = new TreeSet();
        TreeSet gaojin = new TreeSet();
        TreeSet huazai = new TreeSet();
        TreeSet feige = new TreeSet();
        //使用循环遍历索引的集合
        for (int i=0;i<list.size();i++) {
            //发底牌
            if (i >= list.size() -3) {
                dipai.add(list.get(i));
            }else if (i % 3 ==0) {
                gaojin.add(list.get(i));
            }else if (i % 3 ==1) {
                huazai.add(list.get(i));
            }else if (i % 3 ==2) {
                feige.add(list.get(i));
            }
​
        }
​
        //看牌
         look("底牌",dipai,map);
         look("高进",gaojin,map);
         look("华仔",huazai,map);
         look("飞哥",feige,map);
​
​
    }
​
    public   static  void  look(String name,TreeSet<Integer> treeSet,Map<Integer,String> map){
        String world="";
        //遍历索引
        for(Integer in : treeSet) {
            String s = map.get(in);
            world+=s+"  ";
​
        }
        System.out.println(name+"\t"+world);
    }
}
​
​
posted @ 2022-08-02 21:57  真lyz  阅读(44)  评论(0)    收藏  举报