JAVA复习 集合 Day17+Day18+Day19 Map接口,泛型

14集合(集合需要重新在看第二遍,重新总结)

14.3Map接口

14.3.1Map接口实现类的特点

Map和Collection并列存在,用于保存具有映射关系的数据

Map中的key和value可以是任何引用类型的数据,会封装到HashMap$Node对象中

Map中的key不允许重复,原因和HashSet一样

Map中的value可以重复

Map的key可以为null,value也可以为null,key为空只能有一个,但是value为空可以有多个

常用String类作为Map的key

key和value之间存在单向一对一关系,通过指定的key总能找到对应的key

在这里插入图片描述
k-v为了方便程序员的遍历,还会创建EntrySet集合,该集合存放的元素的类型Entry,而一个Entry对象就有k-v EntrySet<Entry<k,v>>
就是将hashmap的node结点存入到entryset中

14.3.2Map接口的常用方法

put:添加
remove:根据键删除映射关系
get:根据键获取值
size:获取元素个数
isEmpty:判断个数是否为0
clear:清除
containsKey:查找键是否存在

14.3.3Map的遍历方法

containsKey:查找键是否存在
keySet:获取所有的键
entrySet:获取所有关系k-v
values:获取所有的值

@SuppressWarnings({"all"})
public class exe07 {
    public static void main(String[] args) {
     Map map=new HashMap();
     //向上转型
     map.put("邓超","孙俪");
     map.put("王宝强","马蓉");
     map.put("关晓彤","鹿晗");
     map.put(null,"刘亦菲");
     map.put("刘令博",null);

     //遍历的第一种,先取出所有的key,通过key取出对应的value
        Set keyset=map.keySet();
        //用增强for
        System.out.println("--------第一种-------");
        for (Object key:keyset){
            System.out.println(key+"-"+map.get(key));
        }
        //通过迭代器
        System.out.println("-----第二种-----");
        Iterator iterator =keyset.iterator();
        while(iterator.hasNext()){
            Object key=iterator.next();
            System.out.println(key+"-"+map.get(key));
        }

        //第二组:把所有的values取出

        Collection values =map.values();
        //这里可以使用所有的Collection使用的遍历方法
        //(1)增强for
        System.out.println("-----取出所有值-------增强for-------");
        for (Object o :values) {
            System.out.println(o);
        }
        //(2)迭代器
        System.out.println("-----取出所有值-------迭代器-------");
        Iterator iterator2 =values.iterator();
        while(iterator2.hasNext()){
            Object value=iterator2.next();
            System.out.println(value);
        }
        //通过entryset来获取
        //第三组:使用Entry来取k-v
        Set entrySet=map.entrySet();
        //使用增强for
        System.out.println("-----------使用EntrySet的增强for------");
        for (Object entry: entrySet){
            Map.Entry m=(Map.Entry)entry;
            System.out.println(m.getKey()+"-"+m.getValue());
        }
        //使用迭代器
        System.out.println("-------使用EntrySet的迭代器---------");
        Iterator  iterator3=entrySet.iterator();
        while(iterator3.hasNext()){
            Object next=iterator3.next();
            //这里的next的类型是一个HashMap$Node
            System.out.println(next.getClass());
            Map.Entry m = (Map.Entry)next;
            //在这里需要进行向下转型
            // static class Node<K,V> implements Map.Entry<K,V>
            //由源码可知,Node实现了接口,所以需要向下转型
            System.out.println(m.getKey()+"-"+m.getValue());
        }
    }
}

14.3.4HashMap的小结

Map的接口常用实现类:HashMap、Hashtable和Properties
HashMap是Map接口使用频率最高的实现类
HashMap是以key-value对的方式来存储数据的
key不能重复,但是值可以重复,允许null键和null值
如果添加相同的key,则会覆盖原来的key-value,等同于修改
HashMap没有实现同步,因此是线程不安全的,方法没有做同步互斥的操作,没有synchronize
于HashSet一样,不保证映射的顺序,因为底层是以hash表的方式来存储的

14.3.5HashMap的底层机制及源码解析

和HashSet一样
在这里插入图片描述
底层维护的是一个Node类型的数组table,默认为null
当创建对象时,将加载因子初始化为0.75
当添加K-v时,通过key的哈希值得到在table的索引,然后判断该索引处是否有元素,如果没有元素直接添加,如果该索引处有元素,继续判断该元素的key是否和准备加入的key相等如果相等,则直接替换,如果不相等需要判断是树结构还是链表结构,做出相应的处理,如果添加时发现容量不够,进行扩容
第一次添加时,则需扩容table容量为16,临界值为12
以后再扩容,则需要扩容table容量为原来的2倍,临界值为原来的2倍,即24,依次类推
在Java中,如果一条链表的元素个数超过默认的8,并且tabel的大小大于64,就会进行树化,红黑树;当一个链表超过8的时候,但是table的并未大于64,先进行扩容,然后再进行树化

14.3.6HashTable的基本介绍

存放的元素是键值对
Hashtable的键和值都不能为null
HashTable使用方法基本上和HashMap一样
HashTable是线程安全的HashMap是线程不安全的

14.3.7HashTable的使用

1、底层有数组Hashtable$Entry [ ] 初始化大小为11
2、临界值threshold 8 =12*0.75
3、扩容:按照自己的扩容机制来扩容:查看源码
4、执行方法addEntry(hash,key,value,index);添加K-V封装到Entry
在这里插入图片描述

14.3.8Map接口实现类Properties

1、这个类继承自Hashtable并且实现了Map接口,也是使用一种键值对的形式来保存数据
2、Properties还可以用于从xxx.properties文件中,加载数据到Properties类对象,并进行读取和修改

remove是进行删除
put是进行修改,当键值一样的时候就是进行修改或者增加

14.3.9TreeSet

是可以排序

//构造器把传入的比较器对象,赋给了TreeSet的底层的TreeMap的属性this.comparator
public TreeSet(Comparator<? super E> comparator) {
        this(new TreeMap<>(comparator));
    }
if (cpr != null) {//cpr就是我们的匿名内部类对象
            do {
                parent = t;
                cmp = cpr.compare(key, t.key);//动态绑定匿名内部类的compare方法
                if (cmp < 0)
                    t = t.left;
                else if (cmp > 0)
                    t = t.right;
                else
                //如果相等,即返回0,不加入数据,只是进行重新设置
                    return t.setValue(value);
            } while (t != null);
        }

14.3.9TreeMap

 Comparator<? super K> cpr = comparator;
        if (cpr != null) {
            do {
                parent = t;
                cmp = cpr.compare(key, t.key);  //由于返回的是0
                if (cmp < 0)
                    t = t.left;
                else if (cmp > 0)
                    t = t.right;
                else
                    return t.setValue(value);
                    //在这个里面k不会改变,但是键对应的值会改变
            } while (t != null);
        }
        

在这里插入图片描述

14.4开发中如何选择集合实现类

1、首先判断存储的对象(一组对象或者一组键值对)
2、一组对象Collection接口
允许重复:List
增删多:LinkedList[底层维护一个双向链表]
改查多:ArrayList[底层维护的是一个Object类型的可变数组]
不允许重复:Set
无序:HashSet[底层是HashMap,维护了一个哈希表即数组+链表+红黑树]
排序:Treeset
插入和取出顺序一致:LinkedHashSet[维护数组+双向链表]
3、一组键值对:Map
键无序:HashMap[底层是哈希表]
键排序:TreeMap
键插入和取出顺序一致:LinkedHashMap
读取文件Properties

14.5Collections工具类

Collections是一个操作Set、List和Map等集合的工具类
Collections中提供了一系列静态的方法对集合元素进行排序、查询和修改等操作

排序操作
reverse(List):反转List中元素的属性顺序
shuffle(List):对List集合元素进行随机排序
sort(List):根据元素的自然顺序对指定的List集合元素按升序排序
sort(List,Compare):根据指定的Comparator产生的顺序对List集合元素进行排序
swap(List,int,int):将指定List集合中的i处元素和j处元素进行交换

查找和替换
Object max(Collection):根据元素的自然顺序,返回给定集合中的最大元素
Object max(Collection ,Comparator):根据Comparator指定的顺序,返回给定集合中的最大元素
Object min(Collection);Object min(Collection ,Comparator)
int frequency(Collection,Object):返回指定集合中指定元素的出现次数
void copy(List dest,List src):将src中的内容复制到dest中
boolean replaceAll(List list,Object oldVal,Object newVal):使用新值替换List对象的所有旧值

public class homework01 {
    public static void main(String[] args) {
        ArrayList<news> news1 = new ArrayList<news>();
        news1.add(new news("新冠确诊病例超千万,数百万印度教信徒赴恒河“圣浴引民众担忧”"));
        news1.add(new news("男子突然想起2个月前钓的鱼还在网兜里,捞起一看赶紧放生"));
        System.out.println("未逆置之前:");
        for (news o :news1) {
            System.out.println(o);
        }
        System.out.println("逆置之后:");
        Collections.reverse(news1);//利用工具类将其逆置
        for (news o :news1) {
            System.out.println(o);
        }

        System.out.println("进行处理之后");
        for (news o :news1) {
            if(o.getTopic().length()>15)//判断String的长度
            {
                String o1=o.getTopic();
                System.out.println(o1.substring(0,15)+"...");
                //利用其String的方法进行截取获取前15个
            }
            else{
                System.out.println(o);
            }
        }

    }
}
class  news{
    private String topic;//标题
    private  String  cons;//内容

    public news(String topic) {
        this.topic = topic;
    }

    public String getTopic() {
        return topic;
    }

    public void setTopic(String topic) {
        this.topic = topic;
    }

    public String getCons() {
        return cons;
    }

    public void setCons(String cons) {
        this.cons = cons;
    }

    @Override
    public String toString() {
        return "news{" +
                "topic='" + topic + '\'' +
                '}';
    }
}
HashSet去重机制:hashCode()+equals(),底层先通过存入对象,进行hash值的索引,如果索引处没有元素则加入,如果有数据则进行equals()比较
TreeSet()去重机制:如果传入一个Comparator()匿名对象,就使用实现的compare去重,如果方法返回0,就认为是相同的元素,就不添加,如果没有传入Comparetor匿名对象,则以添加的对象实现的Compareable接口的compareTo去重
String中实现了compareTo的接口,比较的内容

15泛型

15.1泛型的好处和引入

使用传统方法的话,不能对加入到ArrayList中的数据类型进行约束(不安全)
遍历的时候,需要进行类型转化,数据量比较大的时候,对效率影响比较大

泛型引入的好处
编译的时候会自动检测类型
减少类型转换次数
不再提示编译警告

15.2泛型的介绍

在类声明或实例化时只要指定好需要的具体类型即可
JAVA泛型可以保证如果程序在编译时没有发出警告,运行时就不会产生ClassCastException异常
泛型的作用:可以在类声明时通过一个标识表示类中某个属性的类型,或者是某个方法的返回值类型,或者是参数类型
getClass()输出运行类型

15.3泛型的语法

泛型的声明
interface 接口 {}和class类<K,V> {}
T,K,V不代表值,而是表示类型
任意字母都可以,常用T表示,是Type的缩写

泛型的实例化
要在类名的后面指定类型参数的值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值