Win a copy of Programmer's Guide to Java SE 8 Oracle Certified Associate (OCA) this week in the OCAJP forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

HashSet problem

 
Vinay Naga
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

I am trying write a program that has three sets with points defined by
Set A = {{x1, y1}, {x2, y2},{x3, y3} ...}
Set B = {{x1, y1}, {x2, y2}}
Set C = {{x2,y2},{x3,y3},{x4,y4},....}

I need to get the elements of the set such that ((A-B)intersection(C))

I have written the following program

public class sample {
HashSet<int[][]> shapeA = new HashSet<int[][]>();
HashSet<int[][]> shapeB = new HashSet<int[][]>();
HashSet<int[][]> shapeC = new HashSet<int[][]>();
int arrayA[][] = {{0,0},{100,50},{300,500}, {50, 100}, {0,0}};
int arrayB[][] = {{0,0},{100,50}};
int arrayC[][] = {{40,40},{50,100},{300,500}, {50, 100}, {40,40}};
int resultant[][] ;
Iterator<int[][]> resultantarray ;

public static void main(String args[]){
sample sam = new sample();
sam.logic();
}

public void logic(){

shapeA.add(arrayA);
shapeB.add(arrayB);
shapeC.add(arrayC);

shapeA.removeAll(shapeB);

shapeC.retainAll(shapeA);

resultantarray = shapeC.iterator();

while (resultantarray.hasNext())
{
resultant = resultantarray.next();
}

for (int i = 0 ; i < resultant.length; i ++)
{
System.out.println(resultant[i][0]);
}
}
}


But when I inspect (am using Eclipse) the variables in this line :

shapeA.removeAll(shapeB);

The HashSet shapeA does not seem to remove the points in HashSet shapeB. I see all the variables in shapeA as it is. Please let me know what I am doing wrong here.

Thanks for your help,
Vinay
 
Jeanne Boyarsky
author & internet detective
Marshal
Posts: 34835
369
Eclipse IDE Java VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Vinay,
HashSet uses the equals() method to determine whether two objects are the same and should be removed. And int[] has equals() implemented to check if two objects are pointing to the same int[]. It does not check that the values in the int[] are the same.

Since shapeA and shapeB have references to different physical int[]'s, they are not considered the same and are therefore not removed.

You can write your own comparator with the desired implementation and pass it to the HashSet to get the desired functionality.
 
Rob Spoor
Sheriff
Pie
Posts: 20605
60
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Jeanne Boyarsky:
You can write your own comparator with the desired implementation and pass it to the HashSet to get the desired functionality.

Aren't you confusing HashSet with TreeSet? HashSet can only use the object's hashCode() and equals() methods.

What of course is also possible is create a wrapper class:
 
Vilmantas Baranauskas
Ranch Hand
Posts: 89
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Another problem is that you add only one object to your set.

You would need to define your sets and add elements as following:

Set<int[]> shapeA = new HashSet<int[]>();
Set<int[]> shapeB = new HashSet<int[]>();
Set<int[]> shapeC = new HashSet<int[]>();

...

shapeA.addAll(Arrays.asList(arrayA));
shapeB.addAll(Arrays.asList(arrayB));
shapeC.addAll(Arrays.asList(arrayC));



However this will not solve your problem because of the reason Jeanne explains.
 
Rob Spoor
Sheriff
Pie
Posts: 20605
60
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You do know that Arrays.asList will return a List<int[]> containing only one element this way, right? You can't autobox from int[] to Integer[].
 
Vilmantas Baranauskas
Ranch Hand
Posts: 89
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The original code puts a single array into each of sets.

My code puts a list of arrays (int[] arrays) into each of sets. There is no need to autobox from int[] to Integer[] in my code.

The best solution would probably be to define a Point class containing x and y fields as well as equals() method.

BTW, is the order of points important? If so, simple Set will not suffice. You may then create Point class with x, y and n, where n would point to Point's position in a SortedSet. Then you need to write custom Comparator to sort points by n.
 
Rob Spoor
Sheriff
Pie
Posts: 20605
60
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I just don't see the difference between the two following:

The first adds one int[] to the HashSet<int[]>.

The second takes that same int[], puts it in a List<int[]> of size 1, then adds each element of that List<int[]> to the HashSet<int[]>. In other words, it still adds the one int[] to the HashSet<int[]>, but it takes some steps to do it.

If you would use add instead of addAll, then you would be adding a List<int[]> to the HashSet<int[]>. Which of course fails to compile due to incompatible types.


I do like your idea of using a Point class though. However, instead of creating a new class, use java.awt.Point instead. Sure, it's not Comparable, but you can use a Comparator<Point> if needed.
 
Vinay Naga
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Jeanne, Rob and Vilmantas.
Yes, I need to create something like a point class. And the order of the elements in each of the points is also important. Let me post the actual problem and the solution I came up with. But it is not complete because It still fails with respect to the order. i.e. The points {10,50} and {50,10} are treated same in my code, which is wrong.

Problem :
===================
Shape A defined by a set of (x,y) points in the cartesian xy - plane.
Shape B defined by a set of (x,y) points in the cartesian xy -plane which creates a hollow hole inside of shape A.
Shape C defined by a set of (x,y) points in the cartesian xy-plane.
Write a JAVA console or windows program to find Shape E. E is the intersection of shape C with shape A where A has a hole shape B.
E is a set of (x,y) points in the cartesian xy - plane.

Input of program:
Input for A e.g. (Ax1,Ay1), (Ax2,Ay2), (Ax3,Ay3)�
Input for B e.g. (Bx1,By1), (Bx2,By2), (Bx3,By3)�
Input for C e.g. (Cx1,Cy1), (Cx2,Cy2), (Cx3,Cy3)�
Ouput of program :
Output for E e.g. (Ex1,Ey1), (Ex2,Ey2), (Ex3,Ey3)�

Please provide all code.
===================================

Solution code , which I am still working on. Also bear with me for the mistakes. Please feel free to correct it.
=====================================
import java.util.ArrayList;


public class programone
{
String Shape;
ArrayList<Integer> shapeA = new ArrayList<Integer>();
ArrayList<Integer> shapeB = new ArrayList<Integer>();
ArrayList<Integer> shapeC = new ArrayList<Integer>();
int arrayA[][] = {{100,50},{300,500}, {25, 45},{0,0}};
int arrayB[][] = {{100,50}};
int arrayC[][] = {{40,40},{100,50},{300,500}, {50, 100}, {0,0}};
int k=0;
int l=0;
int m=0;



public static void main(String args[]){
programone p1 = new programone();
p1.logic();
}

public void logic(){

for (int i = 0 ; i < arrayA.length ;i ++ )
{
for (int j =0 ; j <2 ; j ++,k++)
{
shapeA.add(k,arrayA[i][j]);
}
}
for (int i = 0 ; i < arrayB.length ;i ++ )
{
for (int j =0 ; j <2 ; j ++,l++)
{

shapeB.add(l,arrayB[i][j]);
}
}
for (int i = 0 ; i < arrayC.length ;i ++ )
{
for (int j =0 ; j <2 ; j ++,m++)
{
shapeC.add(m,arrayC[i][j]);
}
}

shapeA.removeAll(shapeB);
shapeC.retainAll(shapeA);

System.out.println("ShapeC has a resultant set : " + "{");
for (int y=0; y < shapeC.size(); y ++ )
{
if (y % 2 ==0)
{
System.out.println("{" + shapeC.get(y)
+","+ shapeC.get(y +1)+"}," );
}
}
System.out.println("}");
}
}
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic