Consider the sample code:
class EmployeeClass {
int id;
public EmployeeClass(int eid) {
this.id=eid;
}
#Override
public int hashCode(){
return this.id;
}
#Override
public boolean equals(Object o){
return true;
}
}
public class HashcodeAndEquals {
public static void main(String[] args) {
Map map=new HashMap();
EmployeeClass e1=new EmployeeClass(1);
map.put(e1, "Employee 1"); // line 1
EmployeeClass e2=new EmployeeClass(2);
map.put(e2, "Employee 2");
EmployeeClass e3=new EmployeeClass(3);
EmployeeClass e4=new EmployeeClass(1); // line 2
EmployeeClass e5=new EmployeeClass(1);
map.put(e5, "Employee 5"); // line 3
System.out.println("e1 -> "+map.get(e1));
System.out.println("e2 -> "+map.get(e2));
System.out.println("e3 -> "+map.get(e3));
System.out.println("e4 -> "+map.get(e4)); // line 4
System.out.println("e5 -> "+map.get(e5));
}
}
Output:
e1 -> Employee 5
e2 -> Employee 2
e3 -> null
e4 -> Employee 5
e5 -> Employee 5
After line 1 runs, then line 3 override the value of e1 but my equals method return true only. Also at line 4 we get the value of e4 even though equals method only return true. Since equals method has no comparison only returns true, how put and get is working here. What is happening behind the scenes?
I'm guessing you're surprised that not all of them are Employee 5? Equals always returns true so e5 should have overwritten all of them, right?
A HashMap uses "buckets" behind the scenes. Let's say that there's only 2, to make it simple. A real HashMap has a lot more.
When you put an object into a HashMap, it looks at the hashCode first. (That's why it's called a HashMap.) Based on the hashCode, it chooses a bucket to store it in. For e1, the hashCode is 1, so it would choose bucket 1. For e2, it's 2, so that goes into bucket 2. The hashCode for e3 is 3, but there's only 2 buckets, so it will go into bucket 3 modulo 2, which is 1. e4 goes into bucket 2 for the same reason, and e5 is back in 1.
Note that I'm simplifying here extremely; in reality the process is a little more complex, but this should be enough to explain things.
So we have the following buckets:
bucket 1 | bucket 2
e5 | e4
e3 | e2
e1 |
So now it's time to retrieve values. When I retrieve e1, the hashCode is still 1, so it looks in bucket 1. There, it picks the first object which equals e1, which is e5: the last object you put in, is the first that gets out, apparently. e2 directs to bucket 2, so in this example case, you would get e4 as a result.
In your case, you did never actually put e3 and e4 into the HashMap. But because e3's hashCode directs to bucket 1, and it's equal to e5, when you look up e3 you still get e5 even though it's not actually there.
As I said, this is an extreme simplification of things. In a real HashMap, there's a lot more than 2 buckets. So in your case, e3 has a hashcode that directs to an empty bucket, and the hashCodes for e1, e4 and e5 apparently all direct to the same bucket.
This is why it's important, when you write hashCode, to give it a good "distribution". If you always return 42, all objects would always go into the same bucket, which would turn your HashMap into essentially a very awkward ArrayList. You'd lose al the performance benefits that HashMap gives you.
Related
The problem statement is:
Given a Binary Tree, convert this binary tree to a Doubly Linked List.
A Binary Tree (BT) is a data structure in which each node has at most two children.
A Doubly Linked List contains a previous pointer, along with the next pointer and data.
The order of nodes in Doubly Linked List must be the same as Inorder of the given Binary Tree.
The doubly linked list should be returned by taking the next pointer as right and the previous pointer as left.
You need to return the head of the Doubly Linked List.
For example:
4
/ \
2 5
/ \
1 3
The doubly linked list would be: 1 2 3 4 5
My code is:
class BinaryTreeNode
{
public :
T data;
BinaryTreeNode<T> *left;
BinaryTreeNode<T> *right;
BinaryTreeNode(T data) {
this -> data = data;
left = NULL;
right = NULL;
}
};
void inorder(BinaryTreeNode<int>* root,BinaryTreeNode<int>* &prev,BinaryTreeNode<int>* &nroot){
if(!root) return;
inorder(root->left,prev,nroot);
if(prev == NULL) nroot=root;
else{
root->left = prev;
prev->right=root;
}
prev=root;
inorder(root->right,prev,nroot);
}
BinaryTreeNode<int>* BTtoDLL(BinaryTreeNode<int>* root) {
BinaryTreeNode<int>* prev=NULL;
BinaryTreeNode<int>* nroot=NULL;
inorder(root,prev,nroot);
return nroot;
}
I have doubt regarding root.
The root pointer works with passing by value and does not works when it is passed by reference.
When root is passed by reference, it does not work.
void inorder(BinaryTreeNode<int>*& root,BinaryTreeNode<int>*& prev,BinaryTreeNode<int>* &nroot){
if(!root) return;
inorder(root->left,prev,nroot);
if(prev == NULL) nroot=root;
else{
root->left = prev;
prev->right=root;
}
prev=root;
inorder(root->right,prev,nroot);
}
How can I know which variable should be passed by reference and which variable should by passed by value with regard to pointers?
At first glance, one problem is the API of inorder itself. You are assigning nroot = root; to see why this is a problem, consider this simpler example:
void set_x(int *x, int *y)
{
x = y;
}
Remember that pointers are really just memory addresses. So, the assignment of x = y says, "replace the memory address that x contains, and set it to whatever y contains". At no stage do you actually change the value at the memory address.
Now, considering nroot = root again, here you are just giving the local variable you have a new memory address, but not updating anything. So at your call side BTtoDLL, you provide it nullptr for the address, to which it never uses it, and never sets it. So, BTtoDLL will never see any change to nroot.
I just updated Flutter and successfully downloaded my original project from git. Now I'm getting a weird Future error. I see mention of it online at github, but with no definitive answer on how to fix. The project doesn't even load. It reads Future statements from my main.dart file and returns this...
[VERBOSE-2:dart_error.cc(16)] Unhandled exception: type
'Future dynamic' is not a subtype of type 'Future String' where
Future is from dart:async
Future is from dart:async
String is
from dart:core
*** Not sure where error is. My dart analysis says "Await Only Futures". Here is my futures code which I run before my widgets begin to build...
Future<Null> getData() async{
FirebaseUser user = await FirebaseAuth.instance.currentUser;
user = FirebaseAuth.instance.currentUser;
var userid = user.uid;
fb.child('users/${userid}').onValue.listen((Event event) {
if (event.snapshot.value != null) {
name = event.snapshot.value['displayName'];
image = event.snapshot.value['image'];
} else {
name = "User";
}
});
}
Ok. I think I got it.
Dart 1.0, was a soft-typed language, so something like
main() async {
print(await getData());
}
Future<Null> getDatare() async{return "a";}
would print "a"
The thing is that Dart 2.0 is a typed language, so the Future actually has a meaning. And what happens here (in short) is that Future becomes a FutureNull, and you can't get a String from a FutureNull (since it only contains a Null).
Actually, this kind of bit me once[1], but if you think about it, it makes sense. Look at the following code:
List<dynamic> l = ["a", "b", "c", "d"];
List<String> d = l;
or even more so
List<int> l = [1,2,3,4];
List<double> d = l;
Will crash in Flutter. Why? Because think about what happens here:
What is "l"?
----------------------
| int | int | int | int |
----------------------
What is "d"?
---------------------------------------------
| double | double | double | double |
---------------------------------------------
So how do you convert between "l" and "d"?
You'd have to create a new List of doubles, and then copy the value in l, cast it into a double, and then store it in "d".
But this doesn't just apply to lists. It applies to all generics.
When you have something like A<B>, it's a totally different type than A<C>, and you can't cast simply cast from one to the other, and for the same reason:
Take the following code:
class Box<T> {
T a;
Box(T v) {
a=v;
}
T getVal() {
return a;
}
}
Now convert Box to Box. Doesn't make sense, right? Can I do the following?
Box<int> i = new Box(5);
Box<String> s= new Box("a");
i + (s as Box<int>)
So what really happens here is that Box becomes BoxInt, and Box becomes BoxString (with the compiler find/replacing the identifier "T" with "int" or "T" with "String").
So you have the same thing here: You have to unbox the value from the future, and then work with that. In your case (actually, your case has an additional problem - you're not returning anything) you probably want a Future and then await that Future and get a String.
[1]. How did it bite me? Coming from Kotlin (or any other JVM language), I got used to be able to do something like:
List<A> a = ...;
List<B> b = a;
without a problem. Why? Because JVM doesn't have real generics. What it does is called "type erasure", where what really happens:
List<Object> a = ...;
List<Object> b = a;
Well, that obviously works, since all Lists hold a pointer to an Object, determined at run time.
That was because Java 1.0 (unlike Dart) never had generics and they were bolted on, so for the sake of backwards compatibility they made generics less type-safe than they could have.
So Dart (or C++ or Rust or Go arrays) treats generics as monomorphic, while Java treats them as polymorphic code (treat "T" as pointer).
Let's say I have two array lists, I want to emit an item from the first list then 4 items from the second list and combine them into a third observable which emits the result of this operator. If the second list has less than 4 items, then emit all items remaining from this list.
O1: A, B, C, D
O2: 1,2,3,4,5,6,7,8,9,10,11,12,13,14
So the result will be : A1234 B5678 C9101112 D1314
Haven't checked by a compiler, it's just something I can think of:
Observable<T> o1 = ...
Observable<T> o2 = ...
Observable<T> o3 = o1.zip(o2.buffer(4), (a, b) -> {
List<T> contents = new ArrayList<>();
contents.add(a);
contents.addAll(b);
return contents;
}).flatMap(list -> Observable.from(list));
buffer the second Observable (the one that you want to take chunks of 4 of)
zip it with the first Observable, and create a single List<T> from the 2
flatMap the Observable<List<T>> into Observable<T>
Also mind that I assume that both of your Observables are of the same type.
Given the following Go code example:
package main
import "fmt"
type greeter interface {
hello()
goodbye()
}
type tourGuide struct {
name string
}
func (t tourGuide) hello() {
fmt.Println("Hello", t.name)
}
func (t *tourGuide) goodbye() {
fmt.Println("Goodbye", t.name)
}
func main() {
var t1 tourGuide = tourGuide{"James"}
t1.hello() // Hello James
t1.goodbye() // Goodbye James (same as (&t1).goodbye())
var t2 *tourGuide = &tourGuide{"Smith"}
t2.hello() // Hello Smith
t2.goodbye() // Goodbye Smith (same as (*t2).hello())
// illegal: t1 is not assignable to g1 (why?)
// var g1 greeter = t1
var g2 greeter = t2
g2.hello() // Hello Smith
g2.goodbye() // Goodbye Smith
}
I'm able to call the two methods of the struct tourGuide using either a variable of type tourGuide t1 or a pointer to tourGuide t2. In other words, I can call a method with T receiver using a variable of type T or *T. Similarly, I can call a method with *T receiver using a variable of type T (if T is addressable) or *T. I understand that the compiler handles the differences here (see my comments in the code).
However, things change when we are implementing interfaces. In the above code, a variable of type greeter interface is assignable from a pointer to tourGuide but not from a tourGuide.
Can anyone tell me why this is the case? Why am I able to call t1.hello() and t1.goodbye() but somehow t1 is not enough for the interface greeter?
If a method has a pointer receiver, only a pointer value can be used as the receiver value. So to call this method on some value, the value itself must be a pointer, or it must be possible to acquire its address (to be used as the receiver).
If you have a variable for example, it is addressable and thus it's possible to get its address and use that as the receiver. And the spec allows you to do this, this happens automatically.
Values wrapped in interfaces are not addressable. When an interface value is created, the value that is wrapped in the interface is copied. It is therefore not possible to take its address. Theoretically you could allow to take the address of the copy, but that would be the source of (even) more confusion than what benefit it would provide, as the address would point to a copy, and methods with pointer receiver could only modify the copy and not the original.
See this answer which details / proves that values are copied when the interface value is created: How can a slice contain itself?
if you have a pointer to a struct then go will allow you to access the properties on the struct and its functions which have value type receivers (as apposed to pointer receivers) without having to dereference your pointer, but this only works for one level of pointer, see your code below where I turn t2 into a pointer to a pointer to a tourguide, at this point I need to explicitly dereference it to make it back into a pointer to a tourguide. think of the first level of a pointer to a struct as being a special case that go allows you to use syntatic sugar to access the value types properties and functions to save you having to constantly manually dereference you variables.
package main
import "fmt"
type greeter interface {
hello()
goodbye()
}
type tourGuide struct {
name string
}
func (t tourGuide) hello() {
fmt.Println("Hello", t.name)
}
func (t *tourGuide) goodbye() {
fmt.Println("Goodbye", t.name)
}
func main() {
var t1 tourGuide = tourGuide{"James"}
t1.hello() // Hello James
t1.goodbye() // Goodbye James (same as (&t1).goodbye())
var tmpT2 *tourGuide = &tourGuide{"Smith"}
var t2 **tourGuide = &tmpT2
(*t2).hello() // Hello Smith
(*t2).goodbye() // Goodbye Smith (same as (*t2).hello())
//illegal: t1 is not assignable to g1 (why?)
//var g1 greeter = t1
//now this is illegal too
//var g2 greeter = t2
var g3 greeter = (*t2)
g3.hello() // Hello Smith
g3.goodbye() // Goodbye Smith
}
My answer here explains why Go prevents you from taking the address of a value stored in an interface.
tl;dr its because a pointer to A which points to a value of type A in an interface would be invalidated when a value of different type B is subsequently stored in the interface.
Is there any possibility to create an enum A which inherits properties of enum B and additionally provides possibility to extend elements?
Example:
Enum A
- one
- two
- three
Enum B:A
- four
No, it is not possible.
Base Enums do not support inheritance.
You can't, but if you manually create two base enums, the second with same labels and values of the first one, you can virtually "down cast" them on runtime like if they were inherited, this way (real code):
NoYes e1; // 0 No, 1 Yes
NoYesError e2; // 0 No, 1 Yes, 2 Error
e1 = NoYes::No;
e2 = e1+0; // Add zero to avoid compile error
info(strFmt("%1 %2", e1, e2));
e2 = NoYesError::Error;
e1 = e2+0; // Don't do that
info(strFmt("%1 %2", e1, e2));
Hope this helps.