java|| 集合基础知识随笔(二)

中午好朋友们。吃撑炸鸡的小柳开始脑子发懵低效学习啦。

首先呢为了助于理解Java库中的具体集合,先简要阐述一下集合之间的功能和关系。

  • ArrayList 一种可以动态增长和缩减的索引序列
  • LinkedList 一种可以在任何位置进行高效插入和删除操作的有序序列
  • ArrayQeque 一种用循环数组实现的双端队列
  • HashSet 一种没有重复元素的无序集合
  • TreeSet 一种有序集
  • EnumSet 一种包含枚举类型值的集
  • LinkedHasSet 一种可以记住元素插入次序的集
  • PriorityQuequ 一种允许搞笑删除最小元素的集合
  • HashMap 一种存储键/值关联的数据结构
  • TreeMap 一种键值有序排列的映射表
  • EnumMap 一种键值属于枚举类型的映射表
  • LinkedHashMap 一种可以记住键/值项添加次序的映射表
  • WeakHashMap 一种其值无用武之地后可以被垃圾回收站回收的映射
  • IdentityHashMap 一种用==而不是equals比较键值的映射表

(可对照下图理解记忆。)

集合框架中的类图
是的,这张图反复出现了

  • 散列集
    数组和链表可以按照大家的意愿排列元素的顺序。但当你不确定具体位置时就要逐个查询,消耗很多时间。
    所以,如果不在意元素的顺序,有几种能够快速查找的数据结构。比如散列集。

这是一种众所周知的快速查询数据结构。它根据每个对象的实例域,使用hashCode()方法计算出一个独特的整数,称为散列码。

如果你的对象属于一个自定义类,那么需要额外实现这个类的hashCode()方法。【注:自己实现的hashCode()方法要与equals()方法兼容。即:a.equals(b)==true,则a,b必须有相同的散列码。】
(噢剩下的不想写了因为我有点懂了 走 下一题!)

  • 树集
    TreeSet类和散列集十分类似,不过它有改进,成为了一个有序集合。元素在被任意add()之后,树集会自动对它进行排布,送它去该去的位置。
    例:
SortedSet<String> sorter=new TreeSet<>();//TreeSet implements SortedSet
sorter.add("Bob");
sorter.add("Amy");
sorter.add("Clerk");
for(String s:sorter) System.out.println(s);

结果将输出:Amy Bob Clerk

但是树集添加新元素的速度显然要比散列集慢。但比数组和链表还是要快很多的啦。
如果书中包含n个元素,那么按照树的特性,查找新元素的正确位置平均需要log2n(2是下标)次比较。

因为树集具比较功能,所以这些元素必须实现Comparable接口,或者构造集时必须提供一个Comparator。

  • 优先级队列
    这个队列厉害了。给大家上一个示例程序先,就懂了。
public class PriorityQueueTest{
    public static void main(String[] args) {
        PriorityQueue<LocalDate> qp=new PriorityQueue<LocalDate>();
        qp.add(LocalDate.of(1906,12,9));
        qp.add(LocalDate.of(1815,12,10));
        qp.add(LocalDate.of(1903,12,3));
        qp.add(LocalDate.of(1910,6,22));
        
        System.out.println("Iterating over elements...");
        for (LocalDate date:qp
             ) {
            System.out.println(date);
        }
        System.out.println("Removing elements...");
        while(!qp.isEmpty())
             System.out.println(qp.remove());
    }
}

注:程序先实现常规输出 再实现一边remove一边输出remove的返回值。

输出如下:
在这里插入图片描述
很容易看出,插入是无序随意的,但remove时每次都会将优先级最低的,最小的元素删除。

  • 映射
    如果每次要查询某一数据结构里的元素,都要精确知道元素值才能查找的话未免太不近人情。通常,我们只知道某些键的信息,想要找与它相对应的值。
    映射(map),这种数据结构应运而生。

映射用来存放键/值对。提供了键,就能找到值。
1.基本映射操作
Java类库为映射提供了两个通用的实现:HashMap和TreeMap。这两个类都实现了Map接口。关于接口的详细信息参考Java|| 集合基础知识随笔(一)

HashMap对键进行散列。TreeMap用键的整体顺序对元素进行排列,形成一整棵搜索树。
由此可见,Map是对键起作用的,它操作键而不是值。

键必须是唯一的,不能对一个键同时存放两个值。
如果对一个键两次调用put()方法,第二个值就会取代第一个值,同时返回上一个值。

想检索一个对象:

String id="987-93-3332";
e=staff.get(id);

注:如果映射中没有给定键对应的值,get()返回null。

返回null值有时并不方便,所以可以给定一个替代null的默认值,getOrDefault()方法:

Map<String,Integer> scores=...;
int score=scores.getOrDefault(id,0);

最后遍历键值对最容易的方法是使用forEach方法+lambda表达式:

scores.forEach((k,v)-> 
       System.out.println("key="+k,",value="+v));

好der,不说空话,一个例子给到大家。

public class MapTest {
    public static void main(String[] args) {
        Map<String,Employee> staff=new HashMap<>();
        staff.put("144-25-5464", new Employee("Amy Lee"));
        staff.put("567-24-2546", new Employee("Harry Hacker"));
        staff.put("157-62-7935", new Employee("Gary Cooper"));
        staff.put("456-62-5527", new Employee("Francesca Cruz"));

        //打印所有成员
        System.out.println(staff);
        //删除某一成员
        staff.remove("567-24-2546");
        //替代一个成员
        staff.put("456-62-5527", new Employee("Francesca Miller"));
        //查看一个成员
        System.out.println(staff.get("157-62-7935"));
        //遍历映射
        staff.forEach((k,v)->System.out.println("key="+k+",value="+v));
    }
}
class Employee {
    public String name;

    public Employee(String name) {
        this.name = name;
    }

    public String toString() {
        return "[name=" + name + "]";
    }
}

输出:
在这里插入图片描述
2.更新映射项
这里介绍一个merge()方法,非常好用。

merge() 适用于两种情况。
(1)给定的Key值不存在,它当作put(key, value)使用。
(2)key存在,remappingFunction 可以操作合并,大体来讲有四种情况可供选择(当然你想使用其他操作 sure 可以):

只需返回新值覆盖旧值: (old, new) -> new
只需返回旧值保留旧值: (old, new) -> old
以某种方式合并两者,例如: (old, new) -> old + new
甚至删除旧值: (old, new) -> null

例1:(完整例子可借鉴这位作者大大:merge()的使用,这里只写了merge方法的格式。我觉得不需要看例子,知道方法格式会用就OK)

operations.forEach(op ->
        balances.merge(op.getAccNo(), op.getAmount(), BigDecimal::add)
);

例2:

counts.merge(word,1,Integer::sum);

例3:

result.merge(tag, 1, (a, b) -> a + b);

3.映射视图
映射视图有3种:
键集,值集合(不是一个集),键/值对集。
(啊我懒了 下面截图 应该讲的很明白没什么需要额外总结的了。)
在这里插入图片描述
在这里插入图片描述

好嘞!溜了!
朋友们下篇见!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值