java-----hashset,hashmap等接口对比

255目录

1,HashTable几乎可以等价HashMap

2,HashSet和HashList

目录

255目录

1,HashTable几乎可以等价HashMap

2,HashSet和HashList

重写equals()的原因

重写equals()后要重写hashCode()的理由

3,(map不实现collection接口)为什么引入ConcurrentHashMap

4,Collection常见方法

5,遍历Collection集合的方式

 6,map的两种遍历方式KeySet、entrySet


重写equals()的原因

重写equals()后要重写hashCode()的理由


preview

1,HashTable几乎可以等价HashMap

HashTable是JDK1.0的java特性,它是线程安全的,而HashMap非线程安全的,HashTable支持序列化,因此在单线程的环境下HashTable相比HashMap效率要第。HashTable不支持key和value为空,而HashMap没有这个限制。

2,HashSet和HashList

HashSet实现了Set接口,它不允许集合中有重复的值,当我们提到HashSet时,第一件事情就是在将对象存储在HashSet之前,要先确保对象重写equals()和hashCode()方法

如果不重写上述两个方法,那么将使用下面方法默认实现:


 public boolean add(Object obj)方法用在Set添加元素时,如果元素值重复时返回 "false",如果添加成功则返回"true"


这样才能比较对象的值是否相等,以确保set中没有储存相等的对象。如果我们没有重写这两个方法,将会使用这个方法的默认实现

重写equals()的原因

Object的equal方法默认是两个对象的引用的比较,意思就是指向同一内存。

但是,String对象中equals方法是判断值的,而==是地址判断(因为JDK重写了)。

我们很大部分时间都是进行两个对象的比较(而不是比较引用),这个时候Object的equals()方法就不可以了,所以才会有String这些类对equals方法的改写,依次类推Double、Integer、Math等等这些类都是重写了equals()方法的,从而进行的是内容的比较。

重写equals()后要重写hashCode()的理由

java.lnag.Object中对hashCode的约定:

  1. 在一个应用程序执行期间,如果一个对象的equals方法做比较所用到的信息没有被修改的话,则对该对象调用hashCode方法多次,它必须始终如一地返回同一个整数。
  2. 如果两个对象根据equals(Object o)方法是相等的,则调用这两个对象中任一对象的hashCode方法必须产生相同的整数结果。
  3. 如果两个对象根据equals(Object o)方法是不相等的,则调用这两个对象中任一个对象的hashCode方法,不要求产生不同的整数结果。但如果能不同,则可能提高散列表的性能。

只要改写了就会违约,所以要继续改写。

3,(map不实现collection接口)为什么引入ConcurrentHashMap

preview

  • HashMap和HashTable:HashMap去掉了HashTable的contains方法,但是加上了containsValue()和containsKey()方法。
  • HashTable同步的,而HashMap是非同步的,效率上比HashTable要高。
  • HashMap允许空键值,而HashTable不允许。
  • HashMap:适用于Map中插入、删除和定位元素。 Treemap:适用于按自然顺序或自定义顺序遍历键(key)

HashMap线程不安全,它的线程不安全主要发生在put等对HashEntry有直接写操作的地方:

  1. 从put操作的源码不难看出,线程不安全主要可能发生在这两个地方:

  • key已经存在,需要修改HashEntry对应的value;

  • key不存在,在HashEntry中做插入。

Hashtable线程安全,但是效率低下

4,Collection常见方法

  1. 添加功能 boolean add(E e) 添加一个元素 boolean addAll(Collection c)
    添加一批元素
  2. 删除功能 boolean remove(Object o) 删除一个元素
  3. 判断功能 boolean contains(Object o) 判断集合是否包含指定的元素 boolean isEmpty()
    判断集合是否为空(集合中没有元素)
  4. 获取功能 int size()
    获取集合的长度
  5. 转换功能 Object[] toArray() 把集合转换为数组
  6. 使用技巧:

5,遍历Collection集合的方式

1.普通的for循环【必须要有索引,可以修改元素】

  • 注意set集合是无序的不能使用普通for循环遍历,只能使用增强for或者迭代器遍历
import java.util.*;

public class test{
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<String>();
        list.add("Hello");
        list.add("Java");
        list.add("World");
        for (int i = 0; i < list.size(); i++){
            String s = (String) list.get(i);
            System.out.println(s);
        }
    }
}

2.迭代器遍历【任何集合都可以遍历,只能获取元素】

  • 只要是Collection集合都适合
  • 它是Java集合的顶层接口(不包括map系列的集合,Map接口是map系列集合的顶层接口)

1. Object next():返回迭代器刚越过的元素的引用,返回值是Object,需要强制转换成自己需要的类型。

2. boolean hasNext():判断容器内是否还有可供访问的元素。

3. void remove():删除迭代器刚越过的元素。

  • 所以除了map系列的集合,我么都能通过迭代器来对集合中的元素进行遍历。
  • 注意:我们可以在源码中追溯到集合的顶层接口,比如Collection接口,可以看到它继承的是类Iterable
import java.util.*;

public class test{
    public static void main(String[] args) {
        Collection<String> c = new ArrayList<String>();
        c.add("Hello");
        c.add("Java");
        c.add("World");
        c.add("轩成笔记");
        //获取迭代器对象
        Iterator<String> it = c.iterator();
        //hasNext()判断是否有下一个元素,如果有就用next()获取
        while(it.hasNext()){
            //获取下一个元素
            String s = it.next();
            System.out.println(s);
        }
    }
}

3.高级for循环【就是迭代器的简化方式】

import java.util.*;

public class test{
    public static void main(String[] args) {
        Collection<String> c = new HashSet<String>();
        c.add("Hello");
        c.add("Java");
        c.add("World");
        c.add("轩成笔记");
        //高级for遍历集合
        for (String s : c){
            System.out.println(s);
        }

        int[] arr = {1, 2, 3, 4, 5};
        //高级for遍历数组
        for (int a : arr){
            System.out.println(a);
        }
    }
}

 6,map的两种遍历方式KeySet、entrySet

1. Map集合的第一 种遍历方式:通过键找值的方式

方法: Set keySet() 返回此地图中包含的键的Set视图。 实现步骤:

  1. 使用keySet() ,把Map集合中的所有的key取出来,存入到一-个Set集合中
  2. 遍历set集合,获取到Map集合中的每一 个key
  3. 通过Map集合中的V get(0bject key), 获取到所有的Value值,输出
public class MapTest02 {
    public static void main(String[] args) {
        Map<String, Integer> map = new HashMap<>();
        map. put( "赵丽颖", 168);
        map. put("杨颖" ,165);
        map. put("林志颖" ,155);
        Set<String> Set = map.keySet();//返回的是一个set集合
        for (String key : Set) {
            Integer value = map.get(key);
            System.out.println(key+" "+value);
        }


    }
}

2.Map集合的第二种遍历方式: 使用Entry 对象遍历

  • Entry:键值对(key-value)
  • 方法:
  • Map接口:
  • Set<Map. Entry<K, V>> entrySet() 返回此地图中包含的映射的Set视图。
  • java. util Interface Map. Entry<K, V>:
  • K getKey()返回与此条目相对应的键。
  • V getValue() 返回与此条目相对应的值。
  • 实现步骤:
  1. 使用Map集合中的entrySet()方法,把集合中多个Entry对象取出来,存储到一个Set 集合中
  2. 遍历Set集合,获取到每一个Entry
  3. 调用Entry中的getKey()和IgetValue()方法获取键和值
public class MapTest03 {
    public static void main(String[] args) {
        Map<String, Integer> map = new HashMap<>();
        map. put( "赵丽颖", 168);
        map. put("杨颖" ,165);
        map. put("林志颖" ,155);
        Set<Map.Entry<String, Integer>> set = map.entrySet();
        for (Map.Entry<String, Integer> entry : set) {
            System.out.println(entry.getKey()+entry.getValue());
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

洋气月

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值