精华内容
下载资源
问答
  • 在新建一个HashMap时,会初始化一个数组,在JDK1.8之前初始化的数组初始容量为16,但在JDK1.8及之后,它实现了一个懒加载功能,就是在第一次put数据时才会初始化容量,初始容量仍然是16,在添加数据时,添加数据的...

    HashMap

    底层是数组+链表+红黑树,集数组和链表的优点与一身,线程不安全。

    数组:

    在新建一个HashMap时,会初始化一个数组,在JDK1.8之前初始化的数组初始容量为16,但在JDK1.8及之后,它实现了一个懒加载功能,就是在第一次put数据时才会初始化容量,初始容量仍然是16,在添加数据时,添加数据的下标是由key经过hash算法生成的,获取的hash值与数组长度进行一个取余算法获取下标,取余不是用‘%’,而是用‘&’,因为‘&’的运算比‘%’快,而且用数组的长度肯定是2的次幂,所以不用担心‘%’和‘&’这俩个算出的值不相等的问题(只有长度为2的次幂时,‘%’和‘&’的结果才肯定相等)。在容量达到当前容量的0.75倍时,数组会进行扩容,规则是扩容为原来的2倍,比如当前容量为16,当添加第13个数据时,数组就会进行扩容,扩容后所有key重新进行hash算法重新获取自己的‘房子’

    链表

    在添加数据时,当hash算法算出新key的值与数组中某个key一致时,会触发链表结构,相当于在老key旁边放一个小板凳让新key坐,如图所示
    在这里插入图片描述

    红黑树

    当链表的长度大于等于8时会链表会转成红黑树,当它长度再次小于6之后会再转为链表,否则仍以红黑树存储数据,在这里有个重点,就是当数组的长度小于64时,链表是不会转为红黑树的,因为当数组长度小于64,使用数组加链表比使用红黑树查询速度要更快、效率要更高。

    展开全文
  • private Map testMap = new HashMap(); public MapBean() { testMap.put("key1", "value1"); testMap.put("key2", "value2"); testMap.put("key3"...
    public class MapBean {
    
    	private Map testMap = new HashMap();
    
    	public MapBean() {
    		testMap.put("key1", "value1");
    		testMap.put("key2", "value2");
    		testMap.put("key3", "value3");
    		testMap.put("key4", "value4");
    		testMap.put("key5", "value5");
    	}
    
    	public Map getTestMap() {
    		return testMap;
    	}
    
    	public void setTestMap(Map testMap) {
    		this.testMap = testMap;
    	}
    }

     xtml的内容:

    <?xml version="1.0" encoding="UTF-8"?>
    <ui:composition xmlns="http://www.w3.org/1999/xhtml"
    	xmlns:ui="http://java.sun.com/jsf/facelets"
    	xmlns:h="http://java.sun.com/jsf/html"
    	xmlns:f="http://java.sun.com/jsf/core"
    	xmlns:a4j="http://richfaces.org/a4j"
    	xmlns:rich="http://richfaces.org/rich"
    	xmlns:c="http://java.sun.com/jstl/core"
    	xmlns:fn="http://java.sun.com/jsp/jstl/functions">
    	<!-- 显示列表页面 -->
    	<h:form>
    		<h:panelGrid columns="2">
    			<c:forEach items="${mapBean.testMap}" var="entry">
    				<h:outputText value="${entry.key}" style="font:12px;width:20px;" />
    				<h:inputText value="${entry.value}" style="font:12px;width:150px;" />
    			</c:forEach>
    		</h:panelGrid>
    	</h:form>
    </ui:composition>

     

    已知key获取value的方法:

    <fc:render debugMode="true"
    										chartId="#{inforReportBean.chartMap[row.cells[index-1].cellContent].chartID}"
    										filename="FusionCharts/#{inforReportBean.chartMap[row.cells[index-1].cellContent].chartStyle.chartFile}"
    										width="#{inforReportBean.chartMap[row.cells[index-1].cellContent].widthPx}"
    										height="#{inforReportBean.chartMap[row.cells[index-1].cellContent].heightPx}"
    										xml="#{inforReportBean.chartMap[row.cells[index-1].cellContent].dataxml}" />
     获取数组的长度
    1. ${fn:length(listComment)}     
    2. ${fn:length(listComment)}  
    展开全文
  • * 3、给定一个数组,值可以为正、负和0,请返回累加和小于等于k最长子数组长度。 时间复杂度:O(n) * * 这里需要分为两步,第一步是获取,以每个位置开头最小和长度。第二步,从0到N逐一判断刚才最小长度...
    import java.util.HashMap;
    
    /**
     * 
     * 3、给定一个数组,值可以为正、负和0,请返回累加和小于等于k的最长子数组长度。 时间复杂度:O(n)
     *  
     *  这里需要分为两步,第一步是获取,以每个位置开头最小和的长度。第二步,从0到N逐一判断刚才最小长度是否可以合并在一起达到小于等于k的效果。
     *     
     *   第一步:   获取以每个位置开头的最小和的长度。
     *         可以从后向前计算,把问题变成以某个位置结尾和的最小子串的长度。
     *         例如:   index = 7 , value  = -2 ;   min_sum = -2 ; min_index = 7;
     *              index = 6 , value  = -1 ;   min_sum = -3 ; min_index = 6;
     *              index = 5 , value  = -3 ;   min_sum = -6 ; min_index = 5;
     *              index = 4 , value  =  7 ;   min_sum =  1 ; min_index = 4;
     *              从后向前计算的时候,当发现i+1的min_sum值为正数的时候。则把当前位置i设置为min_index = i ,min_sum = value.
     *                因为这样就是计算以每个位置开头的最小和的长度。-----------------这很重要,也是一种思想。
     *              index = 3 , value  =  6 ;   min_sum =  6 ; min_index = 3;
     *              index = 2 , value  = -2 ;   min_sum = -2 ; min_index = 2;
     *               
     *   index  :       0	     1	      2		  3		  4		  5		   6     7       
     *   value  :       4		 3       -2       6       7      -3       -1     -2  
     *   
     *   
     *   min_index: 	0		 2		  2	      3		  7		  7		   7	  7
     *   min_sum :      4        1       -2       6       1      -6       -3     -2  
     *   			
     *  
     *  
     *  第二步:从0到N逐一判断刚才最小长度是否可以合并在一起达到小于等于k的效果。
     *  	  注意:1,从0-N开始位置index,一个一个遍历。
     *           2,每当遇到一个开始位置index = i时, end = min_index[i],
     *             判断当前sum+=min_sum的大小是否<=K,如果<=K则尝试着往右继续扩展加上  end = min_index[i] + 1,获得其sum += min_sum[i+1]
     *             如果最终的结果继续<=k;则继续向右扩展。如果,>=k则跳转到第3步,
     *           3,如果 sum>=k;则右边不动,左边缩一位,也就是index = i+1;sum-=value[i];再次判断其sum是否<=k;
     *             如果继续<=k,则到第二步。如果不是则继续第三步。
     * 
     * @author xiaodong
     *
     */
    public class Problem_02_LongestSubarrayLessSumAwesomeSolution
    {
    
    	public static int maxLengthAwesome(int[] arr, int k)
    	{
    		if (arr == null || arr.length == 0)
    		{
    			return 0;
    		}
    		int[] sums = new int[arr.length];
    		HashMap<Integer, Integer> ends = new HashMap<Integer, Integer>();
    		sums[arr.length - 1] = arr[arr.length - 1];// 以某个位置开头,得到的最小和。
    		ends.put(arr.length - 1, arr.length - 1);// 当前位置下,最长子序列的最小和
    		for (int i = arr.length - 2; i >= 0; i--)
    		{
    			if (sums[i + 1] < 0)
    			{
    				sums[i] = arr[i] + sums[i + 1];
    				ends.put(i, ends.get(i + 1));
    			} else
    			{
    				sums[i] = arr[i];
    				ends.put(i, i);
    			}
    		}
    		int end = 0;
    		int sum = 0;
    		int res = 0;
    		for (int i = 0; i < arr.length; i++)
    		{
    			while (end < arr.length && sum + sums[end] <= k)
    			{
    				sum += sums[end];
    				end = ends.get(end) + 1;
    			}
    			sum -= end > i ? arr[i] : 0;//这里是为了防止刚开始的时候end==i,就不满足,这样sum没有被加过,所以一直为0,所以不需要减去任何值
    
    			res = Math.max(res, end - i);
    			end = Math.max(end, i + 1);//这里是为了防止刚开始的时候end==i,需要把end值往后移动一个位置,向右扩展。i是自增的
    		}
    		return res;
    	}
    
    	// 这是第二种方法
    	public static int maxLength(int[] arr, int k)
    	{
    		int[] h = new int[arr.length + 1];
    		int sum = 0;
    		h[0] = sum;
    		for (int i = 0; i != arr.length; i++)
    		{
    			sum += arr[i];
    			h[i + 1] = Math.max(sum, h[i]);
    		}
    		sum = 0;
    		int res = 0;
    		int pre = 0;
    		int len = 0;
    		for (int i = 0; i != arr.length; i++)
    		{
    			sum += arr[i];
    			pre = getLessIndex(h, sum - k);
    			len = pre == -1 ? 0 : i - pre + 1;
    			res = Math.max(res, len);
    		}
    		return res;
    	}
    
    	public static int getLessIndex(int[] arr, int num)
    	{
    		int low = 0;
    		int high = arr.length - 1;
    		int mid = 0;
    		int res = -1;
    		while (low <= high)
    		{
    			mid = (low + high) / 2;
    			if (arr[mid] >= num)
    			{
    				res = mid;
    				high = mid - 1;
    			} else
    			{
    				low = mid + 1;
    			}
    		}
    		return res;
    	}
    
    	// for test
    	public static int[] generateRandomArray(int len, int maxValue)
    	{
    		int[] res = new int[len];
    		for (int i = 0; i != res.length; i++)
    		{
    			res[i] = (int) (Math.random() * maxValue) - (maxValue / 3);
    		}
    		return res;
    	}
    
    	public static void main(String[] args)
    	{
    		for (int i = 0; i < 1000000; i++)
    		{
    			int[] arr = generateRandomArray(10, 20);
    			int k = (int) (Math.random() * 20) - 5;
    			if (maxLengthAwesome(arr, k) != maxLength(arr, k))
    			{
    				System.out.println("oops!we made a mistake");
    			} else
    			{
    				// System.out.println(maxLengthAwesome(arr, k) );
    			}
    		}
    
    	}
    
    }
    

    展开全文
  • 数组、链表、hashmap

    2020-08-24 23:45:15
    数组 数组存储数据方式是在内存中开辟一块连续...而且因为真实物理地址连续性,数组一旦初始化完成,其长度就是固定,所以当数组中元素存储密度较小时,即数组比较空时,数组对空间利用率较低。且数组

    数组

    数组存储数据的方式是在内存中开辟一块连续的空间,按照数组中元素索引的顺序依次存储元素。所以数组元素在逻辑上是连续的,在真实的物理空间中也是连续的。因为这一特性,数组的查询十分便捷,可以直接访问任一数组元素获取该元素的值,其时间复杂度为O(1)。但是数组的删除与插入操作效率较低,因为插入或删除某元素,很可能要同时移动大量的其他元素,其时间复杂度为O(n)。而且因为真实物理地址的连续性,数组一旦初始化完成,其长度就是固定的,所以当数组中元素的存储密度较小时,即数组比较空时,数组对空间的利用率较低。且数组对空间要求比较严苛,因为它总是要求一块完整的空间。

    链表

    链表存储数据的方式是,在每一个节点中既存放有元素本身,还存放了指向特定元素的指针。比如在单链表中,每个节点就存有元素本身及指向下一个元素的指针,这样所有的链表元素就像一条链子被串了起来。因此链表元素在物理空间中的存储一般是不连续的,因此链表没有索引。不支持随机访问,链表元素的查询需要依次遍历链表中的元素,效率较低,时间复杂度为O(n)。但链表的插入删除操作只需要修改指针就可以完成,不需要移动大量元素,所以效率很高。因为以上特性,链表的空间分配比较灵活,可以利用零散分布的物理空间。但当存储密度较高时,链表的空间利用率低于数组,因为链表需要额外的空间来存储指针。

    HashMap

    hashmap以键值对的形式存储元素,其结构结合了数组与链表,且在jdk1.8版本之后引入了红黑树。

    hashmap在初始状态下,即没放入任何元素时,就是一个默认长度为16的数组,当有新元素要放入时,通过计算新元素键的hashcode获得其在数组中存放的位置即索引。
    然后判断,当此位置为空时,直接存入该元素。当有元素存在时,即发生了哈希冲突,此时根据equals方法判断已存放元素的键与新元素的键是否内容相同,如果相同则用新元素的value直接覆盖旧元素。如果键内容不同,则将新元素链接在旧元素之后,即生成了一个链表。

    当数组中存放的元素达到阈值(数组长度*负载因子)时,若新存放元素时发生哈希冲突,则数组扩容为原来两倍。原数组内容复制到新数组,且重新计算hashcode获取位置。

    当hashmap中任一个链表长度大于8且此时数组长度大于64时,将此链表转化为红黑树。

    以下为hashmap的原理图:
    hashmap原理图

    展开全文
  •  从源码中我们可以看到获取 key 所对应 Node 数组下标方法是 (length - 1) & hash,它与我们要求 hash % length ... hash,n对应数组长度 else if ((e = tab[index = (n - 1) & hash]) != null) HashM.
  • HashMap的实现原理

    2021-01-10 17:42:51
    (JDK 1.7)HashMap是由数组+链表形式实现,集成了数组的获取元素方便以及链表插入元素方便优点,初试数组长度设置是16位。其中HashCode代表了在hash表中位置。并且在HashMap中有一个Hash算法 (使用异或...
  • HashMap的底层实现

    2018-08-09 16:35:33
    (1)HashMap的构成 HashMap是由数组+链表实现的。它的主干是一个Entry...如果将键值对存储到Map中,首先会调用hashCode()方法获取hashCode,并对数组长度取余找到数组上的存储位置,然后判断该位置是否由元素,...
  • java中的HashMap和Set

    2021-06-07 16:30:42
    java中的HashMap和SetHashMap属性常用方法添加元素--put(key,value)删除元素-remove(key)获取元素-get(key)修改元素--replace(key, value)一些其他方法Set集合HashSet HashMap HashMap是Map接口实现类 HashMap...
  • HashMap的那点事儿

    2020-06-09 18:42:54
    1、HashMap的数据结构 哈希表结构(链表散列:数组+链表)实现,结合数组和链表的优点。当链表长度超过 8 时,链表转换为红黑树 ...①、调用 hash(K) 方法计算 K 的 hash 值,然后结合数组长度,计算得数组下
  • 简单实现HashMap 原理

    2020-04-15 23:12:59
    添加元素下标使用 hashCode % 数组长度 获取 里面存储自定义节点对象,下标值相同存储到next中,依次向下存储 public class MyHashMap<K, V> { //节点数组 private Entry<K, V>[] table; //...
  • HashMap中数组下标值计算过程,大致分为如下几步:1、获取key.hashCode(),2、将hashCode高16位和低16位异或(^)操作,3、与当前数组长度length-1结果进行与(&)操作,最终结果就是数组下标值! static...
  • Java——HashMap

    2019-02-26 22:34:00
    获取数组长度 数组.length 获取下标 HashMap HashMap 构造函数 1 // 默认构造函数。 2 HashMap() 3 4 // 指定“容量大小”构造函数 5 HashMap(int capacity) 6 7 // 指定“容量...
  • 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。 你可以假设数组是非空的,并且给定的数组总是存在多数元素。 示例 1: 输入: [1, 2, 3, 2, 2, 2, 5, 4, 2] 输出: 2 自己的算法及代码 看到这个...
  • Hashmap是由一个Entry数组及链表实现,当使用put(key, value)将键值对存储到Map中时,首先会调用hashCode()方法获取hashCode,并对数组长度取余找到在数组上存储位置,然后判断该位置上上是否有元素,没有话...
  • HashMap 工作原理

    2020-10-16 16:03:00
    HashMap 底层是 hash 数组和单向链表实现,数组每个元素都是链表,由 Node 内部类(实现 Map.Entry接口)实现,HashMap 通过 put & get 方法存储和获取。 存储对象时,将 K/V 键值传给 put() 方法: ①、
  • 有关HashMap的问题

    2020-08-11 14:17:50
    HashMap 底层是 hash 数组和单向链表实现,数组每个元素都是链表,由 Node 内部类(实现 Map.Entry接口)实现,HashMap 通过 put & get 方法存储和获取。 存储对象时,将 K/V 键值传给 put() 方法: ①、
  • hashMap

    2021-04-22 08:54:49
    HashMap 底层是 hash 数组和单向链表实现,数组每个元素都是链表,由 Node 内部类(实现 Map.Entry<K,V>接口)实现,HashMap 通过 put & get 方法存储和获取。 存储对象时,将 K/V 键值传给 p
  • HashMap

    2020-08-05 15:38:11
    HashMap 底层是 hash 数组和单向链表实现,数组每个元素都是链表,由 Node 内部类(实现 Map.Entry接口)实现,HashMap 通过 put & get 方法存储和获取。 存储对象时,将 K/V 键值传给 put() 方法: ①、
  • HashMap 原理

    2021-04-06 22:02:57
    HashMap数组和链表组成:数组为主体,链表是为了解决hash冲突而存在。JDK1.8中若链表长度超过了8(含8),则链表转化为红黑树。jdk1.7链表从头部插入,jdk1.8链表从尾部插入。jdk1.8中entry替换为node。 HashMap继承...
  • HashMap学习笔记

    2021-03-27 12:38:05
    使用key做hash运算得到hash值,hash与数组长度取模得到数组下标index,从数组index位置对应对象类型(链表/红黑树)获取元素。无论数组对应位置是链表或红黑树,都需要key相等时才认为是同一个元素 关键概念 ...
  • HashMap的灵魂21问

    2020-07-21 16:25:12
    哈希表结构(链表散列:数组+链表)实现,结合数组和链表优点,当链表长度超过8时,链表转换为红黑树 2.HashMap 工作原理 HashMap 底层是 hash 数组和单向链表实现,数组每个元素都是链表,由 Node 内部...
  • 关于Java的HashMap

    2020-08-10 22:26:32
    存储:调用hash(K)计算Khash,结合数组长度,计算数组下标;扩容时增加一倍;hash值已存在时会发生碰撞——比对两者equals,true则更新键值对,false则插入链表尾部或红黑树中(注:jdk1.7使用头插;jdk1.8使用...
  • 并且如果HashMap中元素的个数大于等于阈值并且根据key的哈希值和数组长度减一做按位与运算获取的数组下标位置元素非空,则需要扩容,扩容后容量是原来的2倍,也仍然是一个2的幂,那么HashMap为什么这样来做呢?...
  • HashMap简析

    2019-12-14 17:40:37
    HashMap的底层是一个数组,要知道元素存储在数组的哪一个位置,就需要将元素的hash值跟数组长度进行取模,这样就能得到元素在数组中的下标了,但是在HashMap中并不是使用的这种简单的取模方式,而是使用了下面这种...
  • HashMap 实现原理

    2021-04-06 10:44:34
    HashMap HashMap基于hashing原理,我们通过put()和get()方法存储和获取对象。当我们将键值对传递给put()方法时,它调用键对象hashCode()方法来计算hashcode,然后找到bucket位置来...[] table 数组的初始长度 加载因
  • HashMap是由Hash表来实现,数组+链表(1.8加入红黑树)方式实现,通过keyhash值与数组长度取余来获取应插入数组下标,如果产生Hash冲突,在原下标位置转为链表,当链表长度到达8并且数组长度大于等于64则...
  • 1.Hashmap原理及内部数据结构:  底部采用hash表数据加链表形式,1.8以后引入了红黑树数据结构。... 初始化数组长度为16.   最大长度限制   获取在数组中位置: 当数组长度到0.75时扩容: ...
  • 1、1.7 添加元素时,首先通过hash方法获取哈希值,通过indexFor方法获取索引,在1.8版本中,indexFor取消了,直接使用数组长度-1取模hash值得方式获取 2、1.7 hashMap的数据结构为数组+链表,在1.8版本中,数据结构...

空空如也

空空如也

1 2 3 4 5 ... 10
收藏数 189
精华内容 75
关键字:

获取hashmap的数组长度