java map byte[],java中byte数组不能作为map的key使用
今天在使用java寫(xiě)代碼的時(shí)候,用byte數(shù)組作為map的key來(lái)使用,發(fā)現(xiàn)在遍歷的時(shí)候get到之前傳進(jìn)去的值總是為空,很是困惑,后來(lái)查了下資料發(fā)現(xiàn)java中的字節(jié)數(shù)組不能直接作為map的key來(lái)使用.
/**
* 找到當(dāng)前區(qū)塊鏈中所有UTXO
*/
public List findAllUtxos(String sendAddress) {
//遍歷所有的區(qū)塊,找出交易發(fā)起人能夠解鎖的所有沒(méi)有花費(fèi)的交易輸出
List utxoInfos = new ArrayList<>();
Iterator blockIterator = new Iterator(tailHash);
//byte[]不能直接作為map的key使用,所以需要將txid轉(zhuǎn)換成string才能使用
Map> spentOutputs = new HashMap<>();
for (; ; ) {
Block block = blockIterator.getBlock();
for (Transaction tx : block.transactions) {
System.out.println("tag2:outputs length is " + tx.outputs.length + " tx id is " + new BigInteger(tx.id).toString(16));
ScanTransaction:
//遍歷所有的交易輸出
for (int i = 0; i < tx.outputs.length; i++) {
//如果發(fā)現(xiàn)該交易已經(jīng)有被引用的交易輸出,就開(kāi)始判斷
List idList = spentOutputs.get(new String(tx.id));
if (idList != null) {
System.out.println(idList.toString());
for (Integer index : idList) {
if (i == index) {
System.out.println("find spent output,continue scan next input");
continue ScanTransaction;
}
}
}
//如果交易發(fā)起人能使用,將其添加進(jìn)去
TxOutput output = tx.outputs[i];
if (output.canUnlockUTXOWith(sendAddress)) {
UtxoInfo utxoInfo = new UtxoInfo();
utxoInfo.id = tx.id;
utxoInfo.index = i;
utxoInfo.output = output;
utxoInfos.add(utxoInfo);
}
}
//遍歷所有的交易輸入,找到已經(jīng)花費(fèi)掉的,每次循環(huán)都創(chuàng)建一個(gè)List對(duì)象
List spentTxIds = new ArrayList<>();
if (!tx.isCoinBase()) {
for (int i = 0; i < tx.inputs.length; i++) {
TxInput input = tx.inputs[i];
if (input.canUnlockWith(sendAddress)) {
spentTxIds.add(i);
//一定要注意這里的txid是輸入中引用的交易id,不是本次循環(huán)的txid
System.out.println("find used utxo,tx id is " + new BigInteger(input.txId).toString(16) + "index is " + i);
spentOutputs.put(new String(input.txId), spentTxIds);
}
}
}
}
if (block.prevHash == null || block.prevHash.length == 0) {
break;
}
}
return utxoInfos;
}
原因是這樣的,當(dāng)使用byte[]作為key的時(shí)候,map會(huì)對(duì)這個(gè)字節(jié)數(shù)組的地址進(jìn)行hashcode得到一個(gè)值作為key,而不是以?xún)?nèi)容作為它的key,所以?xún)纱蝏yte數(shù)組地址不一樣的話(huà),得到的結(jié)果就會(huì)完全不同.
有三種解決方案:
Wrapping in a String, but then you have to be careful about encoding issues (you need to make certain that the byte -> String -> byte gives you the same bytes).
Use List(can be expensive in memory).
Do your own wrapping class, writing hashCode and equals to use the contents of the byte array.
分別是將byte轉(zhuǎn)成字符串String,我在代碼里也是這么改的;第二是使用List代替;第三是實(shí)現(xiàn)你自己的包裝類(lèi),重寫(xiě)hashcode和equals方法來(lái)達(dá)到以?xún)?nèi)容作為key的目的.
再來(lái)類(lèi)比一下go語(yǔ)言中的map,map的key需要能夠進(jìn)行比較的數(shù)據(jù)類(lèi)型.那些內(nèi)置復(fù)雜類(lèi)型如slice,function和map以及包含這些類(lèi)型字段的結(jié)構(gòu)體也是不能用來(lái)做map的key的.
參考資料:
--EOF--
發(fā)表于 2018-12-01 15:25:00
,并被添加「java、go」標(biāo)簽。
本站使用「署名 4.0 國(guó)際」創(chuàng)作共享協(xié)議,轉(zhuǎn)載請(qǐng)注明作者及原網(wǎng)址。更多說(shuō)明 ?
提醒:本文最后更新于 830 天前,文中所描述的信息可能已發(fā)生改變,請(qǐng)謹(jǐn)慎使用。
專(zhuān)題「java相關(guān)」的其它文章 ?
總結(jié)
以上是生活随笔為你收集整理的java map byte[],java中byte数组不能作为map的key使用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 官宣!荣耀Magic5系列国内新品发布会
- 下一篇: 苹果动画电影《男孩、鼹鼠、狐狸和马》获得