c#中的哈希表hashtable.Add(index,index) key与value相同是什么意思啊,望大神解答。

c#中的哈希表hashtable.Add(index,index) key与value相同是什么意思啊,望大神解答。,第1张

这个的你该了解哈希表原理。

比如说有个引用类(class),它重写了 Equals() 和 GetHashCode() 函数。

然后 a 和 b 虽然是引用不等,然后值相等。

如果 a 已经在 hashtable 里,若 b 的值在 hashtable 里,则把值相等的引用对象 a 取出来。

本人也是新手 不过

Map是不能直接调用工具类进行排序的 而且Map类里的泛型不能用int ,

int是基本数据类型 需要用它的包装类Integer

List可以用Collectionssort( ); 排序

之前写了一次不太对 这次完全按照你的要求输出了

package day01;

import javautilArrayList;

import javautilCollections;

import javautilComparator;

import javautilHashMap;

import javautilIterator;

import javautilList;

import javautilMap;

import javautilMapEntry;

import javautilScanner;

import javautilSet;

public class Test02 {

private static final ArrayList Entry = null;

public static void main(String[] args) {

Scanner sc=new Scanner(Systemin);

Systemoutprintln("要输入几个数字");

int num=scnextInt();

Map<Integer,Integer> map=new HashMap<Integer, Integer>();

for(int i=1;i<=num;i++){

Systemoutprintln("第"+i+"个数字:");

int value=scnextInt();

mapput(i,value );

}

//将map转换成list

Set<Entry<Integer,Integer>> set=mapentrySet();

List<Entry<Integer,Integer>> list=new ArrayList<Entry<Integer,Integer>>(set);

//排序

Collectionssort(list,

new Comparator<Entry<Integer,Integer>>(){

public int compare(

Entry<Integer, Integer> o1,

Entry<Integer, Integer> o2) {

return o1getValue()-o2getValue();

}});

int j=1;

for(Iterator<Entry<Integer,Integer>> i=listiterator();ihasNext();){

Entry<Integer,Integer> entry=inext();

int key=entrygetKey();

int value=entrygetValue();

Systemoutprintln("第"+ j++ +"个数字:"+value+"(原来的第"+key+"个数字)");

}

}

}

1、用Object remove(Object key)方法从HashMap或者HashTable中移去待修改的key值对,该方法同时会返回该Key所对应的Object

2、用put(Object key, Object value) 将新的Key-Value重新放入HashMap(HashTable)

static void Main(string[] args)

      {

          Hashtable ht=new Hashtable(); //创建一个Hashtable实例

         

          htAdd("E","e");  //添加keyvalue键值对

          htAdd("A","a");

         

          for(int i=0;i<9;i++)

          {

             htAdd(i,(i+100)ToString());

          }

         string s1=(string)ht["A"];   //取key为A的值

         ConsoleWriteLine(s1);

       

         if(htContains("E"))         //file判断哈希表是否包含key为E的键值

           ConsoleWriteLine( "键值 E 存在,对应:"+ ht["E"]);

         htRemove("E");              //移除一个keyvalue键值对

         ConsoleWriteLine(ht["E"]);  //此处将不会有任何输出

         for(int i=0;i<3;i++)

         ConsoleWriteLine(ht[i]);

         ConsoleWriteLine("----------输出所有元素--------------------");

         foreach (DictionaryEntry de in ht)

         {

             ConsoleWrite(deKey);

             ConsoleWrite("---");

             ConsoleWriteLine(deValue);

         }

         ConsoleReadKey();

         

      }

-------------------------------------------------------------------------------------------------------------------------------

第一个区别就先来说说继承关系吧

如果你baidu一下,会发现网上的大致说法与“由于Java发展的历史原因。Hashtable是基于陈旧的Dictionary类的,HashMap是Java 12引进的Map接口的一个实现。”相同。

这种说法没有错,但是不够准确,特别是对于我们这种大众菜鸟来说,如果不去深究的话,可能就会造成一些理解上的差异。简单的认为Hashtable没有继承Map接口。

我们可以参考一下最新的JDK16的源码,看看这两个类的定义:

public class Hashtable<K,V>extends Dictionary<K,V> implements Map<K,V>, Cloneable, javaioSerializable {…}public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable {…}

可以看到hashtable也是继承了Map接口。

它们的不同Hashtable(since JDK10)就继承了Dictionary这个抽象类,

HashMap(since JDK12)继承的则是AbstractMap这个抽象类。

第二个区别我们从同步和并发性上来说说它们两个的不同。

可以通过这两个类得源码来分析,Hashtable中的主要方法都做了同步处理,而HashMap则没有。

可以说Hashtable在默认情况支持同步,而HashMap在默认情况下是不支持的。

我们在多线程并发的环境下,可以直接使用Hashtable,但是要使用HashMap的话就要自己增加同步处理了。

对HashMap的同步处理可以使用Collections类提供的synchronizedMap静态方法;

或者直接使用JDK50之后提供的javautilconcurrent包里的ConcurrentHashMap类。

第三个区别就是它们对于null值的处理方式了。

我们依然能够从源代码中得知,Hashtable中,key和value都不允许出现null值。

public synchronized V put(K key, V value) {

// Make sure the value is not null

if (value == null) {

throw new NullPointerException();

}

// Makes sure the key is not already in the hashtable

Entry tab[] = table;

int hash =

keyhashCode();

int index = (hash & 0x7FFFFFFF) % tablength;

//…

}

在我们使用上面的方法时,

如参数value为null,可以从代码中直接看出程序会抛出NullPointerException;

而在key为null时,则会在“int hash =

keyhashCode();“这段计算Hash值的过程中抛出NullPointerException。

而在在HashMap中,允许null作为key存在,并且和其他key的特性一样,这样的null值key只能有一个;

另外HashMap允许多个value为null。

这样大家就要注意了, HashMap中就不能用get(key)方法来判断HashMap中是否存在某个key,因为value为null和不存在该key的Entry都会返回null值,而应该用containsKey()方法来判断了。

import

javautilHashMap;

import javautilMap;

import

javautilMapEntry;

public class TestCase

{

 

public static void main(String[] args) {

Map<Integer,String>

hashMap = new HashMap<Integer,String>();

hashMapput(0, null);

hashMapput(1,

"one");

hashMapput(2,

"two");

hashMapput(null,

"null");

for(Entry<Integer,

String> e : hashMapentrySet()) {

Systemoutprintln("Key:

" + egetKey() + " -- Value: " + egetValue());

}

Systemoutprintln(hashMapget(0));

Systemoutprintln(hashMapget(4));

Systemoutprintln("Contains

key 0  :" + hashMapcontainsKey(0));

Systemoutprintln("Contains

key 4  :" + hashMapcontainsKey(4));

Systemoutprintln("Contains

value null  :" + hashMapcontainsValue(null));

}

}

结果:

Key: null -- Value:

null

Key: 0 -- Value: null

Key: 1 -- Value: one

Key: 2 -- Value: two

null

null

Contains key 0  :true

Contains key 4 

:false

Contains value null 

:true

第四个不同就是它们两个Hash值的获取方式了。

还是通过源代码源代码,Hashtable是直接使用key对象的hash值。

public synchronized V put(K key, V value) {

// Make sure the value is not null 

if (value == null) {

throw new NullPointerException();

}

// Makes sure the key is not already in the hashtable

Entry tab[] = table;

int hash = keyhashCode();//hashcode

int index = (hash & 0x7FFFFFFF) % tablength;

//…

}

而HashMap则是利用key对象的hash值重新计算一个新的hash值。 

 

public V put(K key, V value) {

if (key == null)

return putForNullKey(value);

 

int hash= hash(keyhashCode());//hashcode

int i = indexFor(hash, tablelength);

//…

}

 

static int hash(int h)

{

h ^=(h >>> 20) ^ (h >>> 12);

returnh ^ (h >>> 7) ^ (h >>> 4);

}

第五个不同就是Hashtable和HashMap它们两个内部实现方式的数组的初始大小和扩容的方式。

HashMap中内部数组的初始容量是16, 加载因子为075,而且数组容量增容后也要是2指数次幂:

/

 The default

initial capacity - MUST be a power of two

/

static final int

DEFAULT_INITIAL_CAPACITY = 16;

 

/

 The load factor

used when none specified in constructor

/

static final float

DEFAULT_LOAD_FACTOR = 075f;

HashTable中的内部数组的初始容量是11,加载因子也是075数组的增容方式为(oldCapacity 2 + 1):

public Hashtable() {

this(11,

075f);

}

 

protected void

rehash() {

int

oldCapacity = tablelength;

Entry[]

oldMap = table;

int

newCapacity = oldCapacity  2 + 1;

//…

}

第六个不同我们从它们两个遍历方式的内部实现上来说。

Hashtable HashMap都使用了 Iterator。而由于历史原因,Hashtable还使用了Enumeration的方式 。

第七个不同时它们的拷贝构造函数的不同。

依然是通过查看源码,可以发现它们两个对于拷贝函数初始容量的不同值。

HashMap的实现是:

public

HashMap(Map< extends K,  extends V> m) {

this(Mathmax((int)

(msize() / DEFAULT_LOAD_FACTOR) + 1,DEFAULT_INITIAL_CAPACITY), DEFAULT_LOAD_FACTOR);

putAllForCreate(m);

}

而Hashtable的实现是:

public

Hashtable(Map< extends K,  extends V> t) {

this(Mathmax(2tsize(),

11), 075f);

putAll(t);

}

以上就是关于c#中的哈希表hashtable.Add(index,index) key与value相同是什么意思啊,望大神解答。全部的内容,包括:c#中的哈希表hashtable.Add(index,index) key与value相同是什么意思啊,望大神解答。、一个java问题,随机输入一组数字,从小到大排列,然后表示它是第几次输入的数字(问题在这),真心求助。、HashMap和Hashtable中怎么修改key的value值等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/9494232.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-28
下一篇2023-04-28

发表评论

登录后才能评论

评论列表(0条)

    保存