How to regroup the map keys in java7 [duplicate] - java

If I was using a Set similar to this:
Set<node> s=new TreeSet<node>();
class node {
private int x;
private int y;
}
Would this be acceptable, and since it's a TreeSet, would it also sort it?

It's not going to be able to sort it without you implementing Comparable<Node>, and it won't really be an appropriate for set operations until you override equals() and hashCode(). (You don't have to override equals and hashCode for TreeSet to work, but it would make sense to do so.)
Something like this:
final class Node implements Comparable<Node> {
private final int x;
private final int y;
Node(int x, int y) {
this.x = x;
this.y = y;
}
#Override public boolean equals(Object other) {
if (!(other instanceof Node)) {
return false;
}
Node otherNode = (Node) other;
return x == otherNode.x && y == otherNode.y;
}
#Override public int hashCode() {
return x * 31 + y * 17; // For example...
}
#Override public int compareTo(Node other) {
// As of Java 7, this can be replaced with
// return x != other.x ? Integer.compare(x, other.x)
// : Integer.compare(y, other.y);
if (x < other.x || (x == other.x && y < other.y)) {
return -1;
}
return x == other.x && y == other.y ? 0 : 1;
}
}
(Note that by convention the class name would be Node, not node.)

Node needs to implement a Comparable or you need to pass a custom Comparator which can compare two Node objects. Also, any hash based collection relies on the object suitably overriding equals() and hashcode() method.

You have to specify equals, hashCode and implement the Comparable interface

There is nothing wrong with the code as for as acceptance is concerned. But for sorting Node class MUST implement comparable interface.

Related

Hashmap with Tuple for key and mapped value

What i would like is to create a Hashtable that takes a pair of integers as a key and maps it to a pair of (Integer,String).So having 2 specific integers i would like to be able to acquire both the Integer and the String they map to.What i have done so far:
class Tuple {
public Tuple (int x, int y) {
this.x = x;
this.y = y;
}
public int k;
#Override
public int hashCode() {
int hash = 17;
hash = 5 * hash + this.x;
hash = 5 * hash + this.y;
return hash;
}
#Override
public boolean equals(Object o) {
if (o == this) {
return true;
}
if (!(o instanceof Tuple)) {
return false;
}
Tuple c = (Tuple) o;
return Double.compare(x, c.x) == 0
&& Double.compare(y, c.y) == 0;
}
private int x;
private int y;
}
I created a Tuple class for the key and i initialized the Hashtable like this:
HashMap<Tuple, String> seen = new HashMap<Tuple,String>();
where as a String i put String1:"Integer+"#"+String".
So for a specific key (i,j) i can retrieve this String and separate it to Integer and String.For many and very large integers though String1 takes up a lot of memory since i think for every additional character this string need 2 more bytes.So if i want to store 100000 it would need 12 bytes instead of 4(int's bytes).I tried creating a similar class with Tuple with y being String but i can't retrieve both values only by having (i,j) key.Any ideas?

How to compare coordinate points (of a list) in a nested for loop

Having some trouble building an equals method that compares two dimensional coordinate points in a list based on distance from point zero (0,0) -equation included.
public double distanceToOrigin() {
return distance(zero);
}
public double distance(Point that) {
return Math.sqrt(Math.pow((x - that.getX()), 2) + Math.pow((y - that.getY()), 2));
}
boolean equals(List<Point> lst){
boolean eq = true;
for (int i=0; i<lst.size(); i++)//accounts for first element-to-compare.
{
for (int q = 1; q < lst.size(); q++)//accounts for second element-to-compare.
{
if(lst.distanceToOrigin(i) == (lst).distanceToOrigin(q)))
{
eq = false;
}
}
}
return eq;
}
I may be over-interpreting the if statement: is there a more efficient way to compare both elements (in a single line of code)?
For reference:
static Point zero = new Point(0, 0);
public int getX(){
return x;
}
public int getY(){
return y;
}
Assistance heartily appreciated.
Examples of lists:
List<Point> lst = new ArrayList<Point>();
The corrected equals method would appear similar to the following (somewhat clumsy implementation currently):
boolean equals(List<Point> lst){
boolean eq = true;
for (int i=0; i<lst.size(); i++)//accounts for first element-to-compare.
{
for (int q = 1; q < lst.size(); q++)//accounts for second element-to-compare.
{
if(lst.get(i).distanceToOrigin() == lst.get(q).distanceToOrigin()){
eq = false;
}
}
}
return eq;
}
The equals method should return boolean true or false based on whether or not element-to-compare(1) is identical to element-to-compare(2).
If you are looking for equal distances of two points you are likely better off just comparing the sum of the squares of the coordinates. That avoids comparing floats and is more efficient:
class Point {
public boolean isSameDistanceFromOrigin(Point other) {
return x * x + y * y == other.x * other.x + other.y * other.y;
}
}
If I'm interpreting your loop correctly you want to return false if any two points in a list are the same distance from the origin. Here's an algorithm for doing that in one line (sort of) using Java 8:
public boolean areAllDifferentDistancesFromOrigin(List<Point> points) {
return points.stream().noneMatch(point ->
points.stream().filter(p -> p != point)
.anyMatch(p-> point.isSameDistanceFromOrigin(p)));
}

Resizing Arrays for Speed

So, I am writing a Befunge Interpreter in Java. I have almost all of it down, except I can't figure out a good solution to the problem of Funge Space. Currently I'm using the style stated in the Befunge 93 specs, which is a 80x25 array to hold the code.
In Funge, though, I'm supposed to have an "infinite" array of code (or 4,294,967,296 x 4,294,967,296, which is -2,147,483,648 to 2,147,483,648 in both dimensions), but obviously it's never a good idea to have that much space allocated. But as well as this, it doesn't seem like a good idea to create a new array and copy every character into it every time the program steps out of bounds. Is there a solution to this problem that I'm missing?
So basically, my problem is that I need to somehow expand the array every time I reach out of bounds, or use some sort of other data structure. Any suggestions?
Funge 98 specs
Also, by the way, I still have never figure out how to pronounce Befunge or Funge, I always just say it like "Bee-funj" and "funj"
Without having read the specs (no - I mean, just NO!): A 4,294,967,296 x 4,294,967,296 array is obviously a highly theoretical construct, and only a tiny fraction of these "array entries" can and will ever be used.
Apart from that: Regardless of whether you use an array or any other collection, you'll have a problem with indexing: Array indices can only be int values, but 4,294,967,296 is twice as large as Integer.MAX_VALUE (there are no unsigned ints in Java).
However, one way of representing such an "infinitely large" sparse 2D array would be a map that maps pairs of long values (the x and y coordinates) to the array entries. Roughly like this:
import java.util.HashMap;
import java.util.Map;
interface Space<T>
{
void set(long x, long y, T value);
T get(long x, long y);
}
class DefaultSpace<T> implements Space<T>
{
private final Map<LongPair, T> map = new HashMap<LongPair, T>();
#Override
public void set(long x, long y, T value)
{
LongPair key = new LongPair(x,y);
if (value == null)
{
map.remove(key);
}
else
{
map.put(key, value);
}
}
#Override
public T get(long x, long y)
{
return map.get(new LongPair(x,y));
}
}
class LongPair
{
private final long x;
private final long y;
LongPair(long x, long y)
{
this.x = x;
this.y = y;
}
#Override
public String toString()
{
return "("+x+","+y+")";
}
#Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + (int) (x ^ (x >>> 32));
result = prime * result + (int) (y ^ (y >>> 32));
return result;
}
#Override
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
LongPair other = (LongPair) obj;
if (x != other.x)
return false;
if (y != other.y)
return false;
return true;
}
}

Java hashCode for a Point class

I have a simple custom Point class as follows and I would like to know if my hashCode implemention could be improved or if this is the best it's going to get.
public class Point
{
private final int x, y;
public Point(int x, int y)
{
this.x = x;
this.y = y;
}
public int getX()
{
return x;
}
public int getY()
{
return y;
}
#Override
public boolean equals(Object other)
{
if (this == other)
return true;
if (!(other instanceof Point))
return false;
Point otherPoint = (Point) other;
return otherPoint.x == x && otherPoint.y == y;
}
#Override
public int hashCode()
{
return (Integer.toString(x) + "," + Integer.toString(y)).hashCode();
}
}
Please do not use Strings. There's a lot of theory behind this and several implementations (division method, multiplication one, etc...). If you have about a hour you can watch this MIT-Class
This being said, here is what Netbeans 7.1 suggests:
#Override
public int hashCode() {
int hash = 7;
hash = 71 * hash + this.x;
hash = 71 * hash + this.y;
return hash;
}
October 2015 Edit
I started using IntelliJ a while back, I live happier now. This is what its automatic hashCode generation produces. It's a little less verbose. Note the use of prime numbers as well.
#Override
public int hashCode() {
int result = x;
result = 31 * result + y;
return result;
}
The manual multiplication of values of all significant member fields as suggested by Gevorg is probably the most efficient and has a good value distribution. However, if you favour readability, there are nice alternatives available either in Java 7...
import java.util.Objects;
...
#Override
public int hashCode() {
return Objects.hash(x, y);
}
... or in the Guava library:
import com.google.common.base.Objects;
....
#Override
public int hashCode() {
return Objects.hashCode(x, y);
}
Both of these varags methods simply delegate to Arrays.hashCode(Object[] a), so there is a slight impact on performance because of the autoboxing of ints and creating an array of object references, but it should be far less significant than using reflection.
And the readability is just great, since you simply see, which fields are used for the hashcode computation and all the multiply and add syntax is just hidden under the hood of Arrays.hashCode(Object[] a):
public static int hashCode(Object a[]) {
if (a == null)
return 0;
int result = 1;
for (Object element : a)
result = 31 * result + (element == null ? 0 : element.hashCode());
return result;
}
I would recommend using a simpler and more performant method without strings, perhaps Josh Bloch's method from this answer, in your case just:
return 37 * x + y;
EDIT: nybbler is correct. What is actually recommended is:
int result = 373; // Constant can vary, but should be prime
result = 37 * result + x;
result = 37 * result + y;
A really nice way to hash a 2D point into a single integer is to use a number spiral!
http://ulamspiral.com/images/IntegerSpiral.gif
#Override
public int hashCode() {
int ax = Math.abs(x);
int ay = Math.abs(y);
if (ax>ay && x>0) return 4*x*x-3*x+y+1;
if (ax>ay && x<=0) return 4*x*x-x-y+1;
if (ax<=ay && y>0) return 4*y*y-y-x+1;
return 4*y*y-3*y+x+1;
}
While this method requires a few more calculations, there will be no unpredictable collisions. It also has the nice property that points closer to the origin in general will have smaller hash value. (Still can overflow with x or y > sqrt(MAX_VALUE) however)
From the JDK's Point class (inherited from Point2d):
public int hashCode() {
long bits = java.lang.Double.doubleToLongBits(getX());
bits ^= java.lang.Double.doubleToLongBits(getY()) * 31;
return (((int) bits) ^ ((int) (bits >> 32)));
}
That looks slightly better than your implementation.
You can have a look into existing Point type classes implementations:
/**
343 * Returns the hashcode for this <code>Point2D</code>.
344 * #return a hash code for this <code>Point2D</code>.
345 */
346 public int hashCode() {
347 long bits = java.lang.Double.doubleToLongBits(getX());
348 bits ^= java.lang.Double.doubleToLongBits(getY()) * 31;
349 return (((int) bits) ^ ((int) (bits >> 32)));
350 }
from: http://kickjava.com/src/java/awt/geom/Point2D.java.htm#ixzz1lMCZCCZw
Simple guide for hashCode implementation can be found here
I used to write my own hash and equals functions then I found this : )
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.EqualsBuilder;
#Override
public boolean equals(Object obj) {
return EqualsBuilder.reflectionEquals(this, obj);
}
#Override
public int hashCode() {
return HashCodeBuilder.reflectionHashCode(this);
}
of course keep in mind the following:
Because reflection involves types that are dynamically resolved,
certain Java virtual machine optimizations can not be performed.
Consequently, reflective operations have slower performance than their
non-reflective counterparts, and should be avoided in sections of code
which are called frequently in performance-sensitive applications. SRC
By default, Eclipse will use a hashCode() function for your Point class similar to:
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + getOuterType().hashCode();
result = prime * result + x;
result = prime * result + y;
return result;
}
At the very least, incorporating a prime number into your hashCode algorithm will help with it's "uniqueness".

remove method for arrayList doesn't work

Hi
I have written this code that with output you can get that .remove() method doesn't work. a, b, c, and d are some Points Objects that have x and y members.
Here are a and b and c and d values, which in the if statement must be deleted for upper but it doesn't.
X :59 Y: 143
X :165 Y: 140
X :59 Y: 143
X :165 Y: 140
System.out.println(upper.toString());
for(int i =0;i<upper.size();i++)
if(upper.get(i)==a||upper.get(i)==b||upper.get(i)==c||upper.get(i)==d){
upper.remove(i);
}
for(int i =0;i<lower.size();i++)
if(lower.get(i)==a||lower.get(i)==b||lower.get(i)==c||lower.get(i)==d){
upper.remove(i);
}
System.out.println(upper.toString());
System.out.println(lower.toString());
first println : [X :108 Y: 89, X :165 Y: 140]
second println: [X :108 Y: 89, X :165 Y: 140]
third println : [X :105 Y: 191]
If I'm reading your question right, you're assuming that == will compare the properties of two objects. It doesn't, that's what equals does. == tells you whether two references are to the same object instance, not to equivalent ones.
So for example:
public class Foo {
public Foo(int x, int y) {
this.x = x;
this.y = y;
}
#override
public boolean equals(Object other) {
Foo otherFoo;
if (other == null || !(other instanceof Foo)) { // or you might be more restrictive
return false;
}
otherFoo = (Foo)other);
return otherFoo.x == this.x && otherFoo.y == this.y;
}
#override
public int hashCode() {
// ...appropriate implementation of hashCode...
}
}
Foo a = new Foo(0, 0);
Foo b = new Foo(0, 0);
System.out.println(a == b); // "false"
System.out.println(a.equals(b)); // "true"
Separately: Consider what happens when you have two consequtive matching objects in the ArrayList that you have to remove. Say they're at indexes 8 and 9 in the list. So when i == 8, you remove the item at index 8, and the one that used to be at 9 is now at 8. But then you increment i in the for loop and continue with the new item at index 9, leaving the second one untouched. If you want to modify the list while you're looping through it, consider looping backward to avoid that, or using an Iterator.
Two problems here. Firstly, you're removing objects from a list while you iterate it. That's not a good idea.
Secondly, I think you're misunderstanding the == operator in Java, as mentioned by #T.J. Crowder.
This is a better way of doing what you're trying to do (after you've fixed the equals issue):
List<Point> mypoints = new ArrayList();
mypoints.add(a);
mypoints.add(b);
mypoints.add(c);
mypoints.add(d);
List<Point> otherPoints = new ArrayList();
for(Point p: upper)
for(Point myPoint: mypoints)
{
if(p.equals(myPoint))
break;
otherPoints.add(p);
}
upper = otherPoints;
Another implementation (which only works if upper is a Set, as it will not catch duplicates):
List<Point> mypoints = new ArrayList();
mypoints.add(a);
mypoints.add(b);
mypoints.add(c);
mypoints.add(d);
for(Point myPoint: mypoints)
{
upper.remove(myPoint);
}
As Eric implies, the length of the list changes as items are removed from it, and so do the indices of all of the values after the element that has just been removed.
I'm not sure what the significance of "lower" is. I did notice that the loop that iterates through "lower" attempts to remove elements from "upper". Is this intentional?
This is my solution based on a "remove" list of points that should be removed from "upper". It is also possible to use the style of your original test except that each == check has to to be replaced by an equals() check.
If the equals(...) implementation is removed from the Point class, nothing will be removed from "upper" because the test case deliberately uses clones of the original a,b,c and d values.
import java.util.ArrayList;
import java.util.List;
import junit.framework.Assert;
import org.junit.Test;
public class TestArrayList
{
#Test
public void testRemove()
{
// Test fixture:
Point a = new Point(115, 70);
Point b = new Point(139, 66);
Point c = new Point(195, 111);
Point d = new Point(144, 165);
List<Point> upper = new ArrayList<Point>();
upper.add(a.clone());
upper.add(b.clone());
upper.add(c.clone());
upper.add(d.clone());
List<Point> remove = new ArrayList<Point>();
remove.add(a.clone());
remove.add(b.clone());
remove.add(c.clone());
remove.add(d.clone());
// Assertions:
Assert.assertTrue(upper.size() == 4);
Assert.assertTrue(remove.size() == 4);
// Modified code:
System.out.println(upper.toString());
System.out.println(remove.toString());
for (Point p : remove)
{
upper.remove(p);
}
System.out.println(upper.toString());
System.out.println(remove.toString());
// Assertions:
Assert.assertTrue(upper.isEmpty());
Assert.assertTrue(remove.size() == 4);
}
}
class Point implements Cloneable
{
public int x;
public int y;
public Point(int x, int y)
{
this.x = x;
this.y = y;
}
#Override
public Point clone()
{
return new Point(x, y);
}
#Override
public boolean equals(Object o)
{
if (this == o)
{
return true;
}
else if (o instanceof Point)
{
Point p = (Point) o;
return x == p.x && y == p.y;
}
else
{
return false;
}
}
#Override public String toString()
{
return "X: " + x + " Y: " + y;
}
}

Categories

Resources