I have no idea about java whatsoever but I found this blockchain guide in java and I have been trying to understand and convert the code in C++ (my thing). I was doing good so far but I am stuck here. I cant understand this for loop and Map.Entry<> thing. Any kind of help is appreciated.
And also I am new to blockchain.
The link to this guide is:
https://medium.com/programmers-blockchain/creating-your-first-blockchain-with-java-part-2-transactions-2cdac335e0ce
If that helps.
Here is the code:
public class Wallet {
public PrivateKey privateKey;
public PublicKey publicKey;
public HashMap<String,TransactionOutput> UTXOs = new HashMap<String,TransactionOutput>();
public float getBalance() {
float total = 0;
for (Map.Entry<String, TransactionOutput> item: NoobChain.UTXOs.entrySet()){
TransactionOutput UTXO = item.getValue();
if(UTXO.isMine(publicKey)) { //if output belongs to me ( if coins belong to me )
UTXOs.put(UTXO.id,UTXO); //add it to our list of unspent transactions.
total += UTXO.value ;
}
}
return total;
}
What is this for loop doing is beyond me. If anyone could provide a simpler C++ version of this loop.
Instead of just providing a C++ code snipped let me try to explain this:
In java there are data structures called Maps which contain key-value pairs (you probably could guess this part). The Map itself is not iterable, so in order to loop through a map you can loop through all its keys (also called a key set), all the values or all the key-value pairs (also know as the Entry set). The latter happens in your example.
So in your example you have a map of String (the keys) and TransactionOutput objects (values). The for, loops through these pairs and each pair is stored in the variable item. Then the value part is extracted from the key-value pair (item) which is a TransactionOutput object.
Then this object is verified with the method isMine() and if that is true, it is added to another Map (calles UTXOs) that maps Strings (the key) to TransactionOutput object. In this case it seems the string (the key in the map) is the id of the TransactionObject.
The variable total is increased by the value of the added TrasactionOutput.
Side note: This for-loop could as well just loop through all the values in the map since the key is never used in this particular loop.
Now, to explain this in other words, it is going through the map of TransactionOutputs, the ones that belong to "me" are put aside in a separate map and the total amount of the TrasactionOutput values that belong to "me" is returned.
Hope this clears things up!
Good luck,
Teo
Related
I have a stack of Pair<String key, String value>, and I would like to see if my stack contains a specific value, for example,
private Stack<Pair<String key, String value>> store = new Stack<>();
store.push("cookie", "milk");
store.push("cookie", "white");
store.push("cookie", "triple");
store.push("pie", "apple");
I want to check, given my stack, if it contains "white", without popping everything off. If it contains white, then my methods are different to if it doesn't; there is a precedence in values. Like, if it contains white do x else do y.
I know that there is a method in the Stack class search(Object O), which returns the position in the stack if it does contain it, or a -1 if it doesn't, however, I am not sure how I would do this with a Pair. Would I have to do store.search("cookie", "white"), or can it be just the "white" value?
Hi man i tried your example out and found out that there is no default implementation of Pairs in java so i searched and found this class which seems to do the job: https://stackoverflow.com/a/8446411/10721542
i then tested your example with the following code:
private static Stack<Pair<String, String>> store = new Stack<>();
public static void main(String[] args){
store.push(Pair.createPair("cookie", "milk"));
store.push(Pair.createPair("cookie", "white"));
store.push(Pair.createPair("cookie", "triple"));
store.push(Pair.createPair("pie", "apple"));
store.search(Pair.createPair("cookie", "white"));
}
The only important thing that i found out is that your Pair implementation needs to have an equals implementation or else the search function will not work.
It seems you're creating an pair object, then inserting it into a hash. I would try
store.search("white");
However, to search the stack, which contains objects, you might needs to construct a pair object containing "cookie" and "white" to search for object containing the values and not the actual values themselves.
I must ask, is there a reason you're using a stack to store key-pair values instead of a map or table?
I´m writing a programm in Java. This programm should handle with a lot of diffrent values. I decided to use a HashMap, as you can see here :
public static Map<String, Map<Integer, String>> users = new HashMap<>();
So, as you see I´ve got a map with 2 keys. The first key decides about my "second HashMap". I hope you understood that, because now here is my problem.
public class test {
public static Map<Plot, Map<Integer, Player>> users = new HashMap<>();
public void test(String first, String second) {
if(users.get(first).isEmpty() {
users.computeIfAbsent(first, (a)->new HashMap<>()).put(0, null);
}
if(!users.get(first).containsValue(second)) {
users.computeIfAbsent(first, (a)->new HashMap<>()).put(/*my problem*/, second);
}
}
}
So, in the last if-statement is a comment. I don´t know what i should write in there ? This method is called by another class, but that doesnt matter. My goal is, that to every String (first Key) will be saved a certain Integer (second key) with a certain value(second String in my method).
Of course I want every String to start with 0 and have its own chronologically order. But remember, you can´t use at the start of the class a normal Integer-var, because if you should use it for every key it wouldn´t solve my problem.
If I understand you correctly, the 'inner map' (the one with type Map<Integer, String>) will at all times adhere to the following rule:
The map's keys will always cover a closed range from 0 to its size. For example, an inner map of size 8 will have as keys: `[0, 1, 2, 3, 4, 5, 6, 7].
Assuming I parsed your question correctly, you.... made a list. A list IS semantically speaking exactly that: A thing that 'maps' a closed range of integers starting from 0 to values. To read from this 'map' the value associated with 'key' 5, you just call list.get(5). To 'add' an item at the end, you just call list.add(x) instead of map.put(???, x).
Thus, the answer is as trivial as: Replace Map<Integer, String> with List<String>, replace the (a)->new HashMap<>() with a->new ArrayList<>(), and replace .put(/*my problem*/, with .add(.
If you must do this with maps, you cannot do it with hashmaps, unless you try to use map.size() as a fragile standin, which I strongly advise you don't do (as that would imply your map only works in cases where list would be better, thus proving that the map solution is inferior) – hashmaps do not have an order and thus no idea of 'what is the last / highest key'. You can use a TreeMap instead, which DOES have such concepts. You can ask it about the highest key, and then use 1 higher than that.
But I'm pretty sure you just want a list here.
I want to have map in reverse direction which is mean I have lots of keys and only one value. I need this structure so when I search for one of the key I got the value.
I can use a simple Hash Map but it waste space because of storing value many times. I am looking for optimize and efficient implementation in java. I appreciate your suggestion.
HashMap should be used. when you put "cloth" into HashMap as a value, it is not duplicated in memory. just reference is written into HashMap.
String hat = "hat";
String dress = "dress";
String paths = "paths";
String scarf = "scarf";
String cloth = "cloth";
HashMap h = new HashMap();
h.put(hat,cloth);
h.put(paths,cloth);
h.put(dress,cloth);
h.put(scarf,cloth);
for this sample, memory keeps only cloth object for once.
You don't waste space because each entry shares a reference to the same object. Please post some code if you want a more elaborated answer.
I am doing some algorithm problems in Java, and from time to time the problem needs memoization to optimize speed. And often times, the key is an array. What I usually uses is
HashMap<ArrayList<Integer>, Integer> mem;
The main reason here to use ArrayList<Integer> instead of int[] is that the hashCode() of an primitive array is calculated based on the reference, but for ArrayList<Integer> the value of the actual array is compared, which is desired behavior.
However, it is not very efficient and code can be pretty lengthy as well. So I am wondering if there is any best practice for this kind of memoization in Java? Thanks.
UPDATE: As many have pointed this out in the comments: it is a very bad idea to use mutable objects as the key of a HashMap, which I totally agree.
And I am going to clarify the question a little bit more: when I use this type of memoization, I will NOT change the ArrayList<Integer> once it is inserted to the map. Normally the array represents some status, and I need to cache the corresponding value for that status in case it is visited again.
So please do not focus on how bad it is to use a mutable object as the key to a HashMap. Do suggest some better way to do this kind of memoization please.
UPDATE2: So at last I choose the Arrays.toString() approach since I am doing algorithm problems on TopCoder/Codeforces, and it is just dirty and fast to code.
However, I do think HashMap is the more reasonable and readable way to do this.
You can create a new class - Key, put an array with some numbers as a field and implement your own hascode() based on the contents of the array.
It will improve the readability as well:
HashMap<Key, Integer> mem;
If your ArrayList contains usually 3-4 elements,
I would not worry much about performance. Your approach is OK.
But as others pointed out, your key is thus mutable which is
a bad idea.
Another approach is to append all elements of the ArrayList
together using some separator (say #) and thus have this kind
of string for key: 123#555#66678 instead of an ArrayList of
these 3 integers. You can just call Arrays.toString(int[])
and get a decent string key out of an array of integers.
I would choose the second approach.
If the input array is large, the main problem seems to be the efficiency of lookup. On the other hand, your computation is probably much more expensive than that, so you've got same CPU cycles to spare.
Lookup time will depend both on the hashcode calculation and on the brute-force equals needed to pinpoint the key in a hash bucket. This is why the array as a key is out of the question.
The suggestion already given by user:XpressOneUp, creating a class which wraps the array and provides its custom hash code, seems like your best bet and you can optimize hashcode calculation to involve only some array elements. You'll know best which elements are the most salient.
If the values in the array are small integer than here is way to do it efficiently :-
HashMap<String,Integer> Map
public String encode(ArrayList arr) {
String key = "";
for(int i=0;i<arr.size();i++) {
key = key + arr.get(i) + ",";
}
return(key);
}
Use the encode method to convert your array to unique string use to add and lookup the values in HashMap
So, here is the actual question (it's for a homework):
A hashtable is data structure that allows access and manipulation of the date at constant time (O(1)). The hashtable array must be initialized to null during the creation of the hashtable in order to identify the empty cells. In most cases, the time penalty is enormous especially considering that most cells will never be read. We ask of you that you implement a hashtable that bypasses this problem at the price of a heavier insertion, but still at constant time. For the purpose of this homework and to simplify your work, we suppose that you can't delete elements in this hashtable.
In the archive of this homework you will find the interface of an hashtable that you need to fill. You can use the function hashcode() from java as a hash function. You will have to use the Vector data structure from Java in order to bypass the initialization and you have to find by yourself how to do so. You can only insert elements at the end of the vector so that the complexity is still O(1).
Here are some facts to consider:
In a hashtable containing integers, the table contains numeric values (but they don't make any sense).
In a stack, you cannot access elements over the highest element, but you know for sure that all the values are valid. Furthermore, you know the index of the highest element.
Use those facts to bypass the initialization of the hashtable. The table must use linear probing to resolve collisions.
Also, here is the interface that I need to implement for this homework:
public interface NoInitHashTable<E>
{
public void insert(E e);
public boolean contains(E e);
public void rehash();
public int nextPrime(int n);
public boolean isPrime(int n);
}
I have already implemented nextPrime and isPrime (I don't think they are different from a normal hashtable). The three other I need to figure out.
I thought a lot about it and discussed it with my teammate but I really can't find anything. I only need to know the basic principle of how to implement it, I can handle the coding.
tl;dr I need to implement an array hashtable that works without initializing the array to null at the start. The insertion must be done in constant time. I only need to know the basic principle of how to do that.
I think I have seen this in a book as exercise with answer at the back, but I can't remember which book or where. It is generally relevant to the question of why we usually concentrate on the time a program takes rather than the space - a program that runs efficiently in time shouldn't need huge amounts of space.
Here is some pseudo-code that checks if a cell in the hash table is valid. I will leave the job of altering the data structures it defines to make another cell in the hash table valid as a remaining exercise for the reader.
// each cell here is for a cell at the same offset in the
// hash table
int numValidWhenFirstSetValid[SIZE];
int numValidSoFar = 0; // initialise only this
// Only cells 0..numValidSoFar-1 here are valid.
int validOffsetsInOrderSeen[SIZE];
boolean isValid(int offsetInArray)
{
int supposedWhenFirstValid =
numValidWhenFirstSetValid[offsetInArray]
if supposedWhenFirstValid >= numValidSoFar)
{
return false;
}
if supposedWhenFirstValid < 0)
{
return false;
}
if (validOffsetsInOrderSeen[supposedWhenFirstValid] !=
offsetInArray)
{
return false;
}
return true;
}
Edit - this is exercise 24 in section 2.2.6 of Knuth Vol 1. The provided answer references exercise 2.12 of "The Design And Analysis of Computer Programs" by Aho, Hopcraft, and Ullman. You can avoid any accusation of plaigarism in your answer by referencing the source of the question you were asked :-)
Mark each element in hashtable with some color (1, 2, ...)
F.e.
Current color:
int curColor = 0;
When you put element to hash table, associate with it current color (curColor)
If you need to search, filter elements that haven't the same color (element.color == curColor)
If you need to clear hashTable, just increment current color (curColor++)