java map byte[],java中byte数组不能作为map的key使用

今天在使用java写代码的时候,用byte数组作为map的key来使用,发现在遍历的时候get到之前传进去的值总是为空,很是困惑,后来查了下资料发现java中的字节数组不能直接作为map的key来使用.

/**

* 找到当前区块链中所有UTXO

*/

public List findAllUtxos(String sendAddress) {

//遍历所有的区块,找出交易发起人能够解锁的所有没有花费的交易输出

List utxoInfos = new ArrayList<>();

Iterator blockIterator = new Iterator(tailHash);

//byte[]不能直接作为map的key使用,所以需要将txid转换成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++) {

//如果发现该交易已经有被引用的交易输出,就开始判断

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;

}

}

}

//如果交易发起人能使用,将其添加进去

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);

}

}

//遍历所有的交易输入,找到已经花费掉的,每次循环都创建一个List对象

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,不是本次循环的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;

}

原因是这样的,当使用byte[]作为key的时候,map会对这个字节数组的地址进行hashcode得到一个值作为key,而不是以内容作为它的key,所以两次byte数组地址不一样的话,得到的结果就会完全不同.

有三种解决方案:

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转成字符串String,我在代码里也是这么改的;第二是使用List代替;第三是实现你自己的包装类,重写hashcode和equals方法来达到以内容作为key的目的.

再来类比一下go语言中的map,map的key需要能够进行比较的数据类型.那些内置复杂类型如slice,function和map以及包含这些类型字段的结构体也是不能用来做map的key的.

参考资料:

--EOF--

发表于 2018-12-01 15:25:00

,并被添加「java、go」标签。

本站使用「署名 4.0 国际」创作共享协议,转载请注明作者及原网址。更多说明 »

提醒:本文最后更新于 830 天前,文中所描述的信息可能已发生改变,请谨慎使用。

专题「java相关」的其它文章 »

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值