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相关」的其它文章 »
java map byte[],java中byte数组不能作为map的key使用相关推荐
- java sbyte_JAVA与c#中byte取值范围的差异
C#中分有符号类型的sbyte和无符号类型的byte Console.WriteLine("byte.min:{0},byte.max:{1},{2}byte", byte.Min ...
- java stream 转 file_java 中 byte[]、File、InputStream 互相转换
1.将File.FileInputStream 转换为byte数组: File file = new File("test.txt"); InputStream input = n ...
- java 数组排序论文_Java中运用数组的四种排序方法
标签: <1>利用Arrays带有的排序方法快速排序 import java.util.Arrays; 2 public class Test2{ public static void m ...
- easypoi list中的map导出_Java中的集合类(List,Set.Map)
1.List 1.1 Arraylist 与 LinkedList 区别 是否保证线程安全: ArrayList 和 LinkedList 都是不同步的,也就是不保证线程安全: 底层数据结构: Arr ...
- Java中Array、List、Map相互转换
引言: 在实际项目开发中或者一些算法面试题目中经常需要用到Java中这三种类型的相互转换,比如对于一个整型数组中寻找一个整数与所给的一个整数值相同,正常情况下第一反应会想到用for循环直接遍历这个数组 ...
- 关于java中的数组
前言:最近刚刚看完了<Java编程思想>中关于数组的一章,所有关于Java数组的知识,应该算是了解的差不多了.在此再梳理一遍,以便以后遇到模糊的知识,方便查阅. Java中持有对象的方式, ...
- Java解析json字符串和json数组
Java解析json字符串和json数组 public static Map<String, String> getUploadTransactions(String json){Map& ...
- 【Java基础】Java IO编程:输入输出流、内存流、打印流、缓冲流BufferedReader、扫描流Scanner、序列化与反序列化
文章目录 第11章.Java IO编程 11.1 文件操作类:File 11.2 字节流与字符流 字节输出流:OutputStream OutputStream类 FileOutputStream类 ...
- Java中 byte[]数组序列化和fastjson序列化区别
Java中 byte[]数组序列化和fastjson序列化区别 Java中,对于对象可以通过序列化成byte数组或者序列化成json形式,这里做下两者的对比. 首先看下实现方式: 1 byte数组序列 ...
最新文章
- Python装饰器实现一个代码计时器?
- python命令提示符窗口在哪里_详解python命令提示符窗口下如何运行python脚本
- 微软开源AI诊断工具Error Analysis
- react(85)--error:Error creating bean with name ‘onlineStudyController‘:
- MFC中树形控件的应用——电话簿
- Python操作MySQL的封装类
- ISO14229-1道路车辆-统一诊断服务(UDS)-1
- 程序员都在用的电脑小技巧,一遍就学会,每天早下班一小时
- 图的深度优先遍历及广度优先遍历
- 数据分析之描述性统计分析
- Java异常处理之异常类继承层次
- 【RDMA】qp数量和RDMA性能(节选)|连接数
- 在linux上使用spi-lcd屏 ST7735
- 乘云而上,易捷行云入选“2020中国企服行业独角兽TOP50”
- 模拟城市服务器连接中断 正试着,【模拟城市5】确认DRM在线 中断不会被踢
- 备赛脱脂经验分享_敲黑板,备赛这几招如果你还不知道,赶快学起来吧!
- 运算放大器的差分放大电路
- 到底应不应该【跨专业】考研计算机?希望大么?
- Windows10 会不会成为微软的新起点?
- 如果哥白尼也玩“虚拟化”和“超融合”
热门文章
- c语言可以编写图形界面吗,「分享」C语言如何编写图形界面
- linux添加文件后无法启动,linux安装后grub无法启动
- php 相册分类,这款不需要网络就可以智能识别分类照片,让你的相册不再混乱...
- Java刷漆问题代码_Java实现蓝桥杯历届试题格子刷油漆
- linux控制台编辑模式下换行,linux控制台命令的换行识别问题
- mysql 阿里云 优化_MySQL性能优化速记
- Linux/unix 查看端口占用
- C和C++的关键字区别
- 【Debug】— C++ 表达式必须包含类类型
- android studio你可能忽视的细节——启动白屏?drawable和mipmap出现的意义?这里都有!!!...