【黑马程序员】集合框架(下)——Java复习笔记

——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-

Map

(1)将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。

(2)Map和Collection的区别?
A:Map 存储的是键值对形式的元素,键唯一,值可以重复。

B:Collection 存储的是单独出现的元素,子接口Set元素唯一,子接口List元素可重复。

注意:Map集合的数据结构只针对键有效,跟值无关

(3)Map接口功能概述
A:添加功能
put(key,val)添加并返回旧值。如果键不存在,则直接添加,返回null。如果键已存在,则把此值替代旧值,返回旧值

B:删除功能
clear()
remove(Obj key)根据键删除键值对 并返回值

C:判断功能
containsKey(Obj key)判断集合是否包含指定的键
containsValue(Obj val) 。。。。值
isEmpty()

D:获取功能
entrySet() 返回键值对对象的Set集合
get(Obj key)根据键获取值
keySet() 获取集合中所有键的Set集合
Collection values() 获取集合中所有值的Collection集合

E:长度功能
size() 键值对数量

(4)Map集合的遍历

方法1:键找值
        a:获取所有键的集合 keySet()
        b:遍历键的集合,得到每一个键 foreach keyset
        c:根据键到集合中去找值 map.get(key)

方法2:键值对对象找键和值
        a:获取所有的键值对对象的集合 Set<Map.Entry<K,V>> set = map.entrySet();
        b:遍历键值对对象的集合,获取每一个键值对对象for(Map.Entry<K,V> me:set){String key = me.getKey;String val = me.getValue;}
        c:根据键值对对象去获取键和值 for循环里sout(key,val)

(5)HashMap
是基于哈希表的Map接口实现,哈希表的作用是保证键的唯一性,依赖于equals和hashCode方法,如果键是自定义类的话需要重写这俩方法,否则不能保证唯一性

与Hashtable区别:
HashMap:用于替代Hashtable。不同步,效率高不安全,允许null键和值,
Hashtable(注意t是小写):同步,效率低,不允许null键和值

(6)LinkedHashMap
是Map接口的哈希表和链接列表实现,具有可预知的迭代顺序(不是排序,是存储与取出顺序一致)

(7)TreeMap
是基于红黑树的Map接口的实现

集合总结

(1)Collection (单列集合)
| - - List (有序,可重复)
    || - -ArrayList
        底层数据结构是数组,查询快,增删慢。
        线程不安全,效率高。
    || - -Vector
        底层数据结构是数组,查询快,增删慢。
        线程安全,效率低。
    || - -LinkedList
        底层数据结构是链表,查询慢,增删快。
        线程不安全,效率高。

| - -Set (无序,唯一)
    || - -HashSet
        底层结构式哈希表,依赖两个方法hashCode()和equals() 自动生成即可
        执行顺序:先判断hashCode()值是否相同
            相同:继续执行equals(),看返回值,true则不添加.false则添加
            不同:添加
        ||| - -LinkedHashSet
            底层数据结构由链表和哈希表组成,由链表保证元素有序,由哈希表保证唯一性

    || - -TreeSet(真正的排序)
        底层数据结构是红黑树
        根据比较的返回值是否是0来决定唯一性
        排序:自然排序和比较器排序
            自然排序(元素具备比较性):
                让元素所属的类实现Comparator接口
            比较器排序(集合具备比较性)
                让集合接收一个Comparator的实现类对象

(2)Map (双列集合)
Map集合的数据结构仅仅针对键有效,与值无关

| - -HashMap
    底层结构式哈希表,线程不安全,效率高,依赖两个方法hashCode()和equals() 自动生成即可
        执行顺序:先判断hashCode()值是否相同
            相同:继续执行equals(),看返回值,true则不添加.false则添加
            不同:添加

    || - -LinkedHashMap
        底层数据结构由链表和哈希表组成,由链表保证元素有序,由哈希表保证唯一性

| - -Hashtable(线程安全,效率低)  其他同HashMap

| - -TreeMap
    底层数据结构是红黑树
        根据比较的返回值是否是0来决定唯一性
        排序:自然排序和比较器排序
            自然排序(元素具备比较性):
                让元素所属的类实现Comparator接口
            比较器排序(集合具备比较性)
                让集合接收一个Comparator的实现类对象

集合常用方法及遍历方式

Collection:
    add()
    remove()
    contains()
    iterator()
    size()

    遍历:foreach或迭代器

    |—List
        get()
        遍历:普通for
    |—Set

Map:
    put()
    remove()
    containsKey()  containsValue()
    keySet()
    get()
    value()
    entrySet()
    size()
    遍历:根据键找值;
        根据键值对分别找键和值

Collections工具类

(1)是针对集合进行操作的工具类,都是静态方法

(2)面试题:Collection和Collections的区别
    A:Collection 是单列集合的顶层接口,有两个子接口List和Set
    B:Collections 是针对集合进行操作的工具类,可以对集合进行排序和查找等

(3)常见的几个小方法:
    A:public static <T> void sort(List<T> list) 排序,默认自然排序,储存自定义对象的时候记得在元素类中实现Comparator接口或者在sort方法的构造方法参数中用匿名内部类实现比较器(两者都实现,则按照比较器排序)   比较器实现:Collections.sort(list,new Comparator<>(){…})

    B:public static <T> int binarySearch(List<?> list,T key) 二分查找

C:public static <T> T max(Collection<?> coll) 最大值
    D:public static void reverse(List<?> list) 反转
    E:public static void shuffle(List<?> list) 随机置换

练习

1.模拟斗地主洗牌和发牌并对牌进行排序

牌堆用HashMap按牌从小到大存储,再把key值用ArrayList存储,洗牌洗的是key,发牌发的是key,每个人用TreeSet存牌即可排序,看牌只需按key去找对应的牌.代码如下

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.TreeSet;

/**
 * Created by mo on 15/11/12.
 * 模拟斗地主洗牌发牌看牌 + 排序
 */
public class DouDiZhu2 {
    public static void main(String[] args) {

        //用HashMap,按从小到大的顺序存储牌,洗牌 分牌 排序的时候只需对键操作,看牌的时候根据键显示值
        HashMap<Integer,String> pokes = new HashMap<>();

        //定义花色 数字 都按从小到大添加
        String[] numbers={"3","4","5","6","7","8","9","10","J","Q","K","A","2"};
        String[] colors = {"♦","♣","❤","♠"};

        //拼接花色 数字 并添加到集合
        //双重for 从numbers里按顺序取出 分别用四个花色和它拼 拼完添加到牌堆
        //再用一个ArrayList接收键
        ArrayList<Integer>  key = new ArrayList<>();
        int index = 0;
        for (String num : numbers){
            for (String color:colors){
                String b = color.concat(num);
                pokes.put(index,b);
                key.add(index);
                index++;
            }
        }

        //按顺序加入大小王
        pokes.put(52,"小王");
        pokes.put(53,"大王");
        key.add(52);
        key.add(53);

        //洗牌
        // shuffle接收List集合,所以用ArrayList存储key,然后对ArrayList随机置换
        Collections.shuffle(key);

        //发牌
        //用TreeSet存储每个人的牌,可以自动实现按key的自然顺序排序
        TreeSet<Integer> A = new TreeSet<>();
        TreeSet<Integer> B = new TreeSet<>();
        TreeSet<Integer> C = new TreeSet<>();
        TreeSet<Integer> diPai = new TreeSet<>();

        for (int x=0;x<54;x++){
            if (x >= 51){
                diPai.add(key.get(x));
            }else if (x % 3 == 0){
                A.add(key.get(x));
            }else if (x % 3 == 1){
                B.add(key.get(x));
            }else if (x % 3 == 2){
                C.add(key.get(x));
            }
        }

        //看牌
        //按key获取val值显示出来
        lookPoke("A",A,pokes);
        lookPoke("B",B,pokes);
        lookPoke("C",C,pokes);
        lookPoke("底牌",diPai,pokes);
    }

    //看牌
    public static void lookPoke(String name,TreeSet<Integer> ts,HashMap<Integer,String> hm){
        System.out.println(name+"的牌为:");
        for (Integer x : ts){
            System.out.print(hm.get(x)+"\t");
        }
        System.out.println();
    }
}

2.获取10个1-20之间的随机数,不能重复
3.键盘录入数据,用0结束,返回录入数据的最大值

import java.util.*;

/**
 * Created by mo on 15/11/10.
 * 1.获取10个1-20之间的随机数,不能重复
 * 2.键盘录入数据,用0结束,返回录入数据的最大值
 */
public class getRandomNoDupNum {
    public static void main(String[] args) {
        getNum();
        getMax();
    }

    /*
    需求1:获取10个1-20之间的随机数,不能重复
     */
    public static void getNum(){

        ArrayList newList = new ArrayList();

        while (newList.size() <10){

            int s = (int) (Math.random()*20+1);
            String ss = String.valueOf(s);

            if (!newList.contains(ss)){
                newList.add(ss);
            }

        }

        for (Object x:newList){
            System.out.println(x);
        }
    }

    //需求1的方法2 HashSet
    public static void getNum2(){
        HashSet<Integer> hs = new HashSet<>();
        Random r = new Random();
        while(hs.size()<10){
            hs.add(r.nextInt(20)+1);
        }
    }

    /*
    需求2:键盘录入数据,用0结束,返回录入数据的最大值
     */
    public static void getMax(){
        System.out.println("请输入数据.输入0退出");

        Scanner sc = new Scanner(System.in);

        ArrayList<Integer> list = new ArrayList<>();

        while(true){
            int num = sc.nextInt();
            if (num!=0){
                list.add(num);
            }else {
                break;
            }
        }

        //toArray(T[] a)方法把集合转为Integer类型数组, Integer[] arr1 = list.toArray(arr);  arr与arr1地址值一样 所以简化为如下
        Integer[] arr  = new Integer[list.size()];
        list.toArray(arr);

        Arrays.sort(arr);
        System.out.println(arr[arr.length-1]);
    }


}

4.”abcdcbdbzabcbadbddeaabcbdbcabaabc”要求获取字符串中每个字母出现的次数

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

/**
 * Created by mo on 15/11/11.
 * "abcdcbdbzabcbadbddeaabcbdbcabaabc"要求获取字符串中每个字母出现的次数
 * 要求结果为a(5)b(4)...
 *
 */
public class MapDemo {
    public static void main(String[] args) {
        String key = "aaaaabbbbzzzzzzssss";
        char[] arr = key.toCharArray();

        TreeMap<Character,Integer> tm = new TreeMap<Character, Integer>();

//        for (char x:arr){
//            if (!tm.containsKey(x)){
//                tm.put(x,1);
//            }else {
//                tm.put(x,(tm.get(x))+1);
//            }
//        }

        for(char x:arr){
            Integer i = tm.get(x);
            if (i == null){
                tm.put(x,1);
            }else {
                i++;
                tm.put(x,i);
            }
        }

        Set<Character> st = tm.keySet();

//        for (Character x:st){
//            System.out.print(x+"("+tm.get(x)+")");
//        }

        //用StringBuilder,效率更高
        StringBuilder sb = new StringBuilder();
        for (Character x:st){
            sb.append(x).append('(').append(tm.get(x)).append(')');
        }
        System.out.println(sb);
    }
}

5.用键盘录入5个学生姓名,语数外成绩,按总分从高到低输出

import java.util.Comparator;
import java.util.Scanner;
import java.util.TreeSet;

/**
 * Created by mo on 15/11/11.
 *
 * 用键盘录入5个学生姓名,语数外成绩,按总分从高到低输出
 *
 * 分析 写StudentScore类
 *      Scanner录入
 *      TreeSet储存数据 匿名内部类实现Comparator
 *      从高到低遍历  原理:compare方法从s1-s2改为s2-s1
 *
 */
public class StudentInformation {
    public static void main(String[] args) {

        TreeSet<StudentScore> ts = new TreeSet<>(new Comparator<StudentScore>() {
            @Override
            public int compare(StudentScore s1, StudentScore s2) {
                //从高到低则s2-s1
                //主要条件
                int num = s2.getSumScore() - s1.getSumScore() ;

                //次要条件
                int num2 = num == 0 ? s1.getName().compareTo(s2.getName()):num;
                int num3 = num2 ==0?s1.getChineseScore()-s2.getChineseScore():num2;
                int num4 = num3 ==0?s1.getEnglishScore()-s2.getEnglishScore():num3;
                int num5 = num4 ==0?s1.getMathScore()-s2.getMathScore():num4;
                return num5;
            }
        });

        for (int x= 1;x<=5;x++){
            Scanner sc = new Scanner(System.in);
            System.out.println("请输入第"+x+"位学生姓名");
            String name = sc.nextLine();

            System.out.println("请输入第"+x+"位学生数学成绩");
            int ms = sc.nextInt();

            System.out.println("请输入第"+x+"位学生语文成绩");
            int cs = sc.nextInt();

            System.out.println("请输入第"+x+"位学生英语成绩");
            int es = sc.nextInt();

            StudentScore stu = new StudentScore(es,name,cs,ms);
            ts.add(stu);
        }
        System.out.println("录入完毕");
        System.out.println("学生成绩如下:");
        System.out.printf("%-10s %-10s %-10s %-10s %-10s%n","姓名","语文成绩","数学成绩","英语成绩","总分");

        for (StudentScore x:ts){
            System.out.printf("%-10s %-10s %-10s %-10s %-10s%n",x.getName(),x.getChineseScore(),x.getMathScore(),x.getEnglishScore(),x.getSumScore());
        }
    }
}

class StudentScore{
    private String name;
    private int ChineseScore;
    private int MathScore;
    private int EnglishScore;


    public String getName() {
        return name;
    }


    public int getChineseScore() {
        return ChineseScore;
    }

    public int getMathScore() {
        return MathScore;
    }

    public int getEnglishScore() {
        return EnglishScore;
    }

    public int getSumScore() {
        return this.ChineseScore+this.MathScore+this.EnglishScore;
    }

    public StudentScore(int englishScore, String name, int chineseScore, int mathScore) {
        EnglishScore = englishScore;
        this.name = name;
        ChineseScore = chineseScore;
        MathScore = mathScore;

    }

    public StudentScore(){}
}

6.三层嵌套

import java.util.*;

/**
 * Created by mo on 15/11/11.
 * 三层嵌套 HashMap HashMap ArrayList
 *
 * 需求:
 *    黑马
 *        bj  北京
 *            javase    基础班
 *                              name    age
 *                              name    age
 *            javaee    就业班
 *        xa  西安
 *        sz  深圳
 *        sh  上海
 */
public class TwoHashMapOneArrayList {
    public static void main(String[] args) {
        //第一层集合HashMap 黑马
        //键 "XX校区"   值 HashMap 校区代号bj xa等
        HashMap<String,HashMap<String,ArrayList<Student>>> itheima = new HashMap<>();

        //第二层集合HashMap 各校区
        //键 XX班    值ArrayList<Student> XX班的学生
        HashMap<String,ArrayList<Student>> bj = new HashMap<>();
        HashMap<String,ArrayList<Student>> xa = new HashMap<>();
        HashMap<String,ArrayList<Student>> sz = new HashMap<>();
        HashMap<String,ArrayList<Student>> sh = new HashMap<>();

        //第三层集合ArrayList  XX班的学生
        //储存的是学生对象
        ArrayList<Student> BJSEstudents = new ArrayList<>();
        ArrayList<Student> BJEEstudents = new ArrayList<>();
        ArrayList<Student> XASEstudents = new ArrayList<>();
        ArrayList<Student> XAEEstudents = new ArrayList<>();
        ArrayList<Student> SZSEstudents = new ArrayList<>();
        ArrayList<Student> SZEEstudents = new ArrayList<>();
        ArrayList<Student> SHSEstudents = new ArrayList<>();
        ArrayList<Student> SHEEstudents = new ArrayList<>();


        Student stu1 = new Student("sb1",10,10001);
        Student stu2 = new Student("sb2",19,10002);
        Student stu3 = new Student("sb3",22,10003);
        Student stu4 = new Student("sb4",34,10004);
        Student stu5 = new Student("sb5",12,10005);
        Student stu6 = new Student("sb6",24,10006);
        Student stu7 = new Student("sb7",17,10007);
        Student stu8 = new Student("sb8",18,10008);

        BJSEstudents.add(stu1);
        BJEEstudents.add(stu2);
        XASEstudents.add(stu3);
        XAEEstudents.add(stu4);
        SZSEstudents.add(stu5);
        SZEEstudents.add(stu6);
        SHSEstudents.add(stu7);
        SHEEstudents.add(stu8);

        bj.put("基础班",BJSEstudents);
        bj.put("就业班",BJEEstudents);
        xa.put("基础班",XASEstudents);
        xa.put("就业班",XAEEstudents);
        sz.put("基础班",SZSEstudents);
        sz.put("就业班",SZEEstudents);
        sh.put("基础班",SHSEstudents);
        sh.put("就业班",SHEEstudents);

        itheima.put("北京校区",bj);
        itheima.put("西安校区",xa);
        itheima.put("深圳校区",sz);
        itheima.put("上海校区",sh);

        //遍历储存好的数据 显示在控制台
        Set<String> xqkey = itheima.keySet() ;
        System.out.println("黑马");

        for (String xq:xqkey){
            System.out.println("\t"+xq);

            HashMap<String,ArrayList<Student>> banji = itheima.get(xq);
            Set<String> banji1 = banji.keySet();

            for (String bjkey:banji1){
                System.out.println("\t\t"+bjkey);

                ArrayList<Student> stu = banji.get(bjkey);

                for (Student st:stu){
                    System.out.println("\t\t\t"+st);
                }
            }
        }

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值