数据结构Map-----LinkedHashMap源码解析

基于LinkedHashMap实现FIFO(先进先出)淘汰算法 package com.bingo.frame; import java.util.LinkedHashMap; /** * b.基于LinkedHashMap实现FIFO(先进先出)淘汰算法 * @author bingo */ public class BingoTest { class SimpleFIFOCache extends LinkedHashMap<Object, Object> { private int maxCap; public Simpl 阅读详情

LinkedHashMap:重要的成员变量以及构造方法

public class LinkedHashMap<K, V> extends HashMap<K, V> {

    /**
     * 头节点,这是一个很重要的节点,用来维护一个双向循环链表
     */
    transient LinkedEntry<K, V> header;

    /**
     * True if access ordered, false if insertion ordered.
     * 关系到LinkedHashMap的排序方式,也决定了那个元素会是最近最少使用的元素。
     * 稍后我会详细的说一下true和false对于排序方式的区别。
     */
    private final boolean accessOrder;

    /**
     * 无参构造,注意accessOrder 默认是false
     */
    public LinkedHashMap() {
        init();
        accessOrder = false;
    }

    /**
     *最终调用了3个参数的构造方法
     */
    public LinkedHashMap(int initialCapacity) {
        this(initialCapacity, DEFAULT_LOAD_FACTOR);
    }

    /**
     *最终调用了3个参数的构造方法
     */
    public LinkedHashMap(int initialCapacity, float loadFactor) {
        this(initialCapacity, loadFactor, false);
    }

    /**
     *调用了super也就是父类HashMap的2参构造,同时跟无参构造一样调用了init方法和对于accessOrder的赋值方法
     */
    public LinkedHashMap(
            int initialCapacity, float loadFactor, boolean accessOrder) {
        super(initialCapacity, loadFactor);
        init();
        this.accessOrder = accessOrder;
    }

    //初始化了个LinkedEntry实例header
    @Override void init() {
        header = new LinkedEntry<K, V>();
    }  
}

LinkedEntry 和 HashMapEntry :

/**
 * LinkedEntry
 */
static class LinkedEntry<K, V> extends HashMapEntry<K, V> {
    LinkedEntry<K, V> nxt;
    LinkedEntry<K, V> prv;

    /** Create the header entry */
    LinkedEntry() {
        super(null, null, 0, null);
        nxt = prv = this;
    }

    /** Create a normal entry */
    LinkedEntry(K key, V value, int hash, HashMapEntry<K, V> next,
                LinkedEntry<K, V> nxt, LinkedEntry<K, V> prv) {
        super(key, value, hash, next);
        this.nxt = nxt;
        this.prv = prv;
    }
}

/**
 * HashMapEntry
 */
static class HashMapEntry<K, V> implements Entry<K, V> {
       final K key;
       V value;
       final int hash;
       HashMapEntry<K, V> next;

       HashMapEntry(K key, V value, int hash, HashMapEntry<K, V> next) {
           this.key = key;
           this.value = value;
           this.hash = hash;
           this.next = next;
       }
 }

通过对比我们发现LinkedEntry的构造方法中调用了super(key, value, hash, next); 同时还增加了两个新的特有属性 nxt 和 prv。如果来记得我之前关于LinkedList的源码解析的那篇文章的话,就大致可以猜到这两个属性是干什么的,没错就是引用元素前后其他元素的,也就是指针。

这里写图片描述

还记得上一篇中我使用★来包裹的函数吗,这里我也贴出来作比较,来看一看LinkedHashMap和HashMap的区别

/**
 * HashMap
 */
void preModify(HashMapEntry<K, V> e) { }


/**
 * LinkedHashMap
 */
@Override 
void preModify(HashMapEntry<K, V> e) {
    if (accessOrder) {
        makeTail((LinkedEntry<K, V>) e);
    }
}

这个方法是出现在put方法中的,LinedkHashMap并没有自己实现put方法,而是依然使用的父类HashMap的put方法,我们可以发现影响两者实现不同的关键在于accessOrder的值上面,如果是false那么两者的实现可以说是完全一样的,但是如果是true的话LinkedHashMap就会执makeTail函数。而我们知道使用无参构造创建LinkedHashMap的时候accessOrder默认值就是false,所以我们先暂时搁置不去看这个函数

/**
 * HashMap
 */
void postRemove(HashMapEntry<K, V> e) { }

/**
 * LinkedHashMap
 */
@Override 
void postRemove(HashMapEntry<K, V> e) {
    LinkedEntry<K, V> le = (LinkedEntry<K, V>) e;
    le.prv.nxt = le.nxt;
    le.nxt.prv = le.prv;
    le.nxt = le.prv = null; // Help the GC (for performance)
}

这个方法是出现在remove方法中的,LinedkHashMap也没有自己实现remove方法,而是依然使用的父类HashMap的remove方法,这是只是操纵了LinedEntry特有的两个属性nxt和prv的指针引用,学过链表结构的想必都知道这个几行代码就是将元素e的前后元素的指针重新进行了赋值,同时将自身的引用断开置空。基本过程就如下图

这里写图片描述

/**
 * HashMap
 */
void addNewEntry(K key, V value, int hash, int index) {
    table[index] = new HashMapEntry<K, V>(key, value, hash, table[index]);
}

/**
 * LinkedHashMap
 */
@Override 
void addNewEntry(K key, V value, int hash, int index) {
    LinkedEntry<K, V> header = this.header;

    // Remove eldest entry if instructed to do so.
    LinkedEntry<K, V> eldest = header.nxt;
    if (eldest != header && removeEldestEntry(eldest)) {
        remove(eldest.key);
    }

    // Create new entry, link it on to list, and put it into table
    LinkedEntry<K, V> oldTail = header.prv;
    LinkedEntry<K, V> newTail = new LinkedEntry<K,V>(
            key, value, hash, table[index], header, oldTail);
    table[index] = oldTail.nxt = header.prv = newTail;
}

这个方法也是出现在put方法中,如果大家细心的话,可以发现LinedkHashMap的addNewEntry做了和HashMap的addNewEntry相同的事情。同时还做了一些HashMap没有做的事情

/**
 * HashMap
 */
table[index] = new HashMapEntry<K, V>(key, value, hash, table[index]);

/**
 * LinkedHashMap
 */
newTail = new LinkedEntry<K,V>(key, value, hash, table[index], header, oldTail);
table[index] = oldTail.nxt = header.prv = newTail;

总结:刨除header, oldTail就发现其实逻辑是一样的,那么header, oldTail额外干了什么呢,还得记得LinkedEntry的构造吗,去看看你就会想起来了,通过代码可以看出,它维护了一个以header为头节点的双向循环链表,通过上面的几个个比较,到这里想必大家现在应该有点知道了为什么LinkedEntry比HashMapEntry多出的两个属性nxt和pre到底用来干什么的。也就是说LinkedHashMap不但完全跟HashMap一样维护了一个散列链表,同时跟LinkedList一样也维护了一个双向循环链表,所以LinkedHashMap真的是名副其实啊也就是说LinkedHashMap不但像HashMap那样维护了一个Entry[]数组,同时也像LinkedList那样有一个以header为头结点的链表。

Entry[] 数组 table

这里写图片描述

LinekedEntry header为头结点的链表
这里写图片描述

我们知道LinkedHashMap的增加和删除调用的是父类HashMap的方法,那么我们来看一下get方法有什么区别

  • 查找
/**
 * HashMap
 */
public V get(Object key) {
    if (key == null) {
        HashMapEntry<K, V> e = entryForNullKey;
        return e == null ? null : e.value;
    }

    int hash = Collections.secondaryHash(key);
    HashMapEntry<K, V>[] tab = table;
    for (HashMapEntry<K, V> e = tab[hash & (tab.length - 1)];
            e != null; e = e.next) {
        K eKey = e.key;
        if (eKey == key || (e.hash == hash && key.equals(eKey))) {
            return e.value;
        }
    }
    return null;
}

/**
 * LinkedHashMap
 */
@Override 
public V get(Object key) {
    /*
     * This method is overridden to eliminate the need for a polymorphic
     * invocation in superclass at the expense of code duplication.
     */
    if (key == null) {
        HashMapEntry<K, V> e = entryForNullKey;
        if (e == null)
            return null;
        if (accessOrder)
            makeTail((LinkedEntry<K, V>) e);
        return e.value;
    }

    int hash = Collections.secondaryHash(key);
    HashMapEntry<K, V>[] tab = table;
    for (HashMapEntry<K, V> e = tab[hash & (tab.length - 1)];
            e != null; e = e.next) {
        K eKey = e.key;
        if (eKey == key || (e.hash == hash && key.equals(eKey))) {
            if (accessOrder)
                makeTail((LinkedEntry<K, V>) e);
            return e.value;
        }
    }
    return null;
}

对比发现如果accessOrder如果是false是完全没有区别的,而且我们通过之前对比也多次见到了accessOrder这个变量的身影,可以说这个属性的值决定了很多事情,那么如accessOrder为true的话它都干了些什么呢?那么我们来看makeTail函数究竟做了些什么?

/**
 * 是不是看起来不是那么复杂,而且十分眼熟,好像就是链表指针相关的各种操作,你链我啊 我链你的
 */
private void makeTail(LinkedEntry<K, V> e) {
    // Unlink e
    e.prv.nxt = e.nxt;
    e.nxt.prv = e.prv;

    // Relink e as tail
    LinkedEntry<K, V> header = this.header;
    LinkedEntry<K, V> oldTail = header.prv;
    e.nxt = header;
    e.prv = oldTail;
    oldTail.nxt = header.prv = e;
    modCount++;
}

实际上就是当我们get获取到元素的时候重新调整了该元素在链表中的位置。
相信还有一种数据结构大家不陌生吧就是队列,我们知道LinkedList也是实现Queue接口的

public class LinkedList<E> extends AbstractSequentialList<E> implements
        List<E>, Deque<E>, Queue<E>, Cloneable, Serializable {

所以LindedList其实就是队列的一种,而我们知道队列区别于栈结构的,队列是先进先出,队尾进入,队头出,而栈结构是先进后出的,栈顶进入,栈顶出。

看图我们就可以发现header头节点的nxt所指向的元素就是队头,而header头结点pre指向的元素就是队尾。

这里写图片描述

而当accessOrder为false的时候,是不执行makeTail函数的,LindedHashMap中的排序方式就是像队列一样先进先出,而且元素的顺序不会发生变化的(保持上图的LinedEntry1和LinedEntry2顺序),即使重新put了key值相同的元素,通过HashMap的源码可以发现他也只是执行了替换,没有执行addNewEntry,所以也就没有机会重新更改指针指向。而队列我们都知道队列满了的时候是从队头删除元素,腾出空间来使用的,所以这种形式下,最先进入队列或者链表中的就是最早的最老的元素,也就是header的nxt,

这里写图片描述

而当accessOrder为true的时候,是执行makeTail函数的,LindedHashMap中的排序方式就会随着访问和插入操作,元素的顺序就会发生变化的,重新更改指针指向(比如我们访问了LinkedEntry1,那么LinedEntry1就会放到LinkedEntry2的后面,如上图)。每次我们访问一个元素的时候都会改变元素的指针指向,将该元素放回队尾,重新调整header的pre指向,假如我们访问的正好是header.nxt指向的元素,那么header.nxt就会发生变化,那么上面提到的最老的元素就会发生了变化,而header.nxt永远指向的是最近最少使用的

想必看到这里大家对于Android缓存策略Lru到底是怎么实现的应该有了一定的了解了,那就是使用一个了accessOrder为true的LinkedHashMap。

下一篇我将简单带大家看一下LruCache的源码。

Java 集合框架:从基础到精通1 Java 集合框架(Java Collections Framework, JCF)是 Java 中用于存储和操作一组对象的统一架构,位于 包中。 1.2 核心接口详解 Iterable 接口 所有集合都实现 Iterable,因此都支持 for-each 循环。 List 接口 有序集合(序列),允许重复元素,可通过索引访问。 Set 接口 不允许重复元素的集合。 Queue 接口 设计用于在处理前保存元素的集合。 Map 接口 键值对映射,键唯一。 1.3 集合接口的两类操作模式 操作类型 阅读详情

相关推荐

大数据Spark “蘑菇云”行动前传第8课:零基础实战Scala最常用数据结构Map和Tuple及Spark源码解析

大数据Spark “蘑菇云”行动前传第8课:零基础实战Scala最常用数据结构Map和Tuple及Spark源码解析   1 Map 和Tuple 在spark源码中的鉴赏 2 Map 和Tuple 代码操作实战   map - tree - graph   map:无为天地之始 有为万物之母   java:  array list 不能放不同类型的数据 只容纳一种类型 Tup

大模型与Agent智能体 1426

HashMap、LinkedHashMap、ConcurrentHashMap的使用

HashMap、LinkedHashMap、ConcurrentHashMap的使用

会飞的鱼儿的博客 1331

Windows与Linux安装miniconda并启动python项目及指令

官方介绍:Miniconda 是 conda 的免费最小安装程序。它是 Anaconda 的一个小型引导版本,仅​​包含 conda、Python、它们都依赖的包以及少量其他有用的包(例如 pip、zlib 等)。如果您需要更多软件包,请使用该 命令从 Anaconda 公共存储库或其他渠道(例如 conda-forge 或 bioconda)默认提供的数千个软件包中进行安装。minicoda下载地址最好挂个梯子。如果你需要指定版本的conda,可以在这里下载历史版本的miniconda。

一直走的很慢的鸭子 3191

LinkedHashMap如何保证顺序性

一. 前言 先看一个例子,我们想在页面展示一周内的消费变化情况,用echarts面积图进行展示。如下: 我们在后台将数据构造完成 HashMap<String, Integer> map = new HashMap<>(); map.put("星期一", 40); map.put("星期二", 43); map.put("星期三", 35); map.put("星期四",...

weixin_30315435的博客 2287

TPS5430/54302调试血泪史:从‘烫手山芋’到冒烟烧板,我的5V电源到底怎么了?

本文深入剖析了TPS5430/TPS54302 DCDC电源芯片调试中的常见问题,包括异常发热、电压漂移等,并提供了从热设计到PCB布局的全面解决方案。通过实战案例,揭示了数据手册中未明确的‘潜规则’,帮助工程师避免烧板风险,提升电源系统稳定性。

weixin_28744423的博客 502

CSS字体样式全攻略

🧱 让文字有空间感,适合标题或LOGO。🖋️适合插画、创意工作者的个人页面。🔥 适合标题、品牌名,视觉冲击力强。🧘‍♀️适合极简设计、文化类网站。✨适合科技类网站、博客、作品集。🚀适合游戏、AI、科技类项目。🐰 适合儿童类网站或节日氛围。📖适合时尚、生活方式类内容。🌫️ 适合神秘、梦幻主题。🌃 夜店风、科技感十足。具体效果是文字会上下跳动。

dreams_dream的博客 1804

LinkedHashMap 详解

LinkedHashMap 通过特有底层双向链表的支持,使得LinkedHashMap可以保存元素之间的顺序,例如插入顺序或者访问顺序,而HashMap因为没有双向链表的支持,所以就不能保持这种顺序,所以它的访问就是随机的了和HashMap一样,还是通过数组存储元素的这里的顺序指的是遍历的顺序,定义了头结点head,当我们调用迭代器进行遍历时,通过head开始遍历,通过after属性可以不断找到下一个,直到tail尾结点,从而实现顺序性。...

持续学习,持续更新 1万+

学习Ultralytics (下载)

Ultralytics由创立,最初是为了简化目标检测模型的开发和应用,专注于构建高效、易用、性能卓越的深度学习框架。其主要产品之一是 YOLO 系列模型,尤其是最新的YOLOv5和YOLOv8,因其在精度、速度和可扩展性方面的出色表现而广受欢迎。

2301_76846375的博客 2864

LinkedHashMap使用技巧

public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map<K,V> 的两个使用技巧 1.元素先进先出。 public LinkedHashMap(int initialCapacity) 这是linkedHashMap的一个构造方法,从名字上来看,是初始化长度。该构...

做你想做的人,没有时间的限制,只要愿意,什么时候都可以start。 551

XGBoost算法案例 - 红酒品质分类

数据集共包含 11 个特征,共计 3269 条数据. 我们通过训练模型来预测红酒的品质, 品质共有 6 个各类别,分别使用数字: 0、1、2、3、4、5 来表示。

YIAN爱学习的博客 449

工业异常检测评价指标(I-AUROC、PRO等)

模型评价指标:TPR、FPR、Recall、ROC、AUC、AUROC、IoU、PRO、AUPRO等

qq_1532145264的博客 7432

集合四课之四 Map接口下,HashTable、LinkedHashMap、HashMap和TreeMap介绍与区别 附带速记卡

先来看看组织图

null 202

AES加密算法及AES-CMAC原理白话版系统解析

对AES不同加密算法,加密模式,加密原理,填充算法及AES-CMAC算法的详细系统介绍,帮助大家对AES进行系统掌握。

initiallizer的博客 4070

Map相关的基础知识

HashMap 原理图 主要源码解析 基于1.6 public V put(K key, V value) { if (key == null) return putForNullKey(value); int hash = hash(key.hashCode()); int i = indexFor(hash, table.length); for (Entry<K,V> e = table[i]; e != null; e = e.next) { Objec

bluewaveandy的博客 179

AI技术在电商中的实际应用

人工智能、电商、推荐系统、个性化、机器学习、深度学习 1. 背景介绍 电子商务行业近年来发展迅速,用户数量不断增长,商品种类日益丰富。然而,随着市场竞争的加剧,电商平台面临着如何提升用户体验、提高转化率、挖掘潜在商机等一系列挑战。人工智能(AI)技术作为一种新兴技术,凭借其强大的数

AGI×大数据,开启智能时代的认知跃迁;解码AGI,赋能数据驱动的智能革命。 1740

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

JAVA中对集合源码的理解

Collection和Map源码的理解

yd1472939313的博客 163

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

《java核心卷Ⅰ》—— Set集合类、Map集合

各位小伙伴们大家好,欢迎来到这个小扎扎的专栏,在这个系列专栏中我将记录浅学这本书所得收获,鉴于精神,这波简直就是血赚

扎哇太枣糕的笔记博客 586

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

Java Map常用方法和实现类深度详解

本文深入解析Java Map接口及其主要实现类的核心原理。Map采用键值对存储结构,包含HashMap、LinkedHashMap、TreeMap等实现。重点剖析了HashMap的底层数据结构演进(JDK7数组+链表到JDK8数组+链表+红黑树)、关键设计决策(如0.75负载因子、2^n容量等),详细解读了put方法执行流程和扩容机制。文章还对比了不同Map实现的特点,帮助开发者根据场景选择合适实现,掌握Map的高效使用技巧。

百锦再的博客 2415

Java Day15

1,JDK8中,HashMap底层结构是 :数组+单向链表 + 红黑树, 无序、可以存放null值,null键,键不能重复2,HashMap的初始容量是16,负载因子默认是0.75,当容量达到16*0.75=12的时候,会扩容3,初始容量和负载因子都可以自己设置 ,负载因子设置的过大和过小都不太好,过大的话,会减少扩容,增加哈希冲突,过小可以减少冲突,扩容次数变多4,如果需要存入大量元素,那么可以指定一个特定的初始容量,HashMap的容量值都是2的n次方。

qq_51944132的博客 161

遍历map的四种方法及Map.entry详解

Map.entrySet() 这个方法返回的是一个Set<Map.Entry<K,V>>, Map.Entry 是Map中的一个接口,他的用途是表示一个映射项(里面有Key和Value), 而Set<Map.Entry<K,V>>表示一个映射项的Set。 Map.Entry里有相应的getKey和getValue方法,即JavaBean,让我们能够从一个项中取出Key和Value。 下面是遍历Map的四种方法: public static

wenchang-的博客 655

剑指offer.50.第一个只出现一次的字符之练习递归、标记或Map

剑指offer.50.打卡,第一次只出现一次字符。记录该题三种写法,分别体现三种思想,练习数据结构中的数据结构或是编程思想。

qq_43164662的博客 97

JavaSE基础_集合

一.Collection接口 1.Collection接口继承树 2.Map接口继承树

qq_17674357的博客 379

小滴课堂-学习笔记:面试BAT高级工程师/技术经理的java集合框架Map

愿景:"让编程不再难学,让技术与生活更加有趣" 更多架构课程请访问 xdclass.net 目录 第1集 编程语言面试题之新版javase集合框架Map篇<小试牛刀上> 第2集 编程语言面试题之对象底层HashCode和equals掌握了吗 第3集 编程语言面试题之新版javase集合框架Map篇<小试牛刀下> 第4集 编程语言面试题之新版javase集合框架Map篇<进阶> 第5集 编程语言面试题之新版javase集合框架Map高手篇<上&g..

dev666的博客 280

JavaSE:集合

JavaSE:集合概述集合框架Collection的使用Collection中的常见方法迭代器接口 IteratorCollection的子接口之一:List底层源码分析ArrayListLinkedListVectorList接口中的常用方法Collection子接口之二:SetLinkedHashSet的使用TreeSet的使用 概述         为了方便对多个对象的操作,就要对对象进行存储。另一方面,使用数组存储对象方

m0_49825096的博客 445

Map源码解析之LinkedHashMap

Map源码解析之HashMap Map源码解析之HashMap红黑树 HashMap源码解析之补充说明:集合、迭代器、compute、merge、replace 在分析完了HashMap源码之后,我们接着看另一种形式的map :LinkedHashMap。 LinkedHashMap是HashMap的子类,相比HashMap而言,其数据结构在HashMap的基础上多了双向链表将所有节点连接起来,从...

翻身已碰头的博客 472

LinkedHashMap 全面深度解析

LinkedHashMap是HashMap的子类,在哈希表高效存取的基础上,通过双向链表维护元素顺序,支持插入顺序或访问顺序遍历。其核心在于Entry节点扩展了before/after指针,形成独立于哈希桶的双向链表。accessOrder参数控制两种模式:插入顺序保持put顺序,访问顺序则在get/put时移动元素至链表尾部实现LRU策略。通过重写removeEldestEntry方法可轻松实现LRU缓存,在O(1)时间复杂度下平衡了性能与有序性,适用于缓存、日志等场景。

csdn_silent的博客 2014
上一篇: 数据结构Map-----HashMap源码解析
下一篇: Android缓存策略LruCahe源码解析,Lru到底是怎么算的?
omyrobin
博客等级 码龄12年 65粉丝 58原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值