TreeMap/Comparator a mapping problem

J

Jeff Higgins

Hi,
When I run the following code
several output lines are not what I expect.

I expect:
1:1:7 [red, red]
1:32:18 [yellow]
7:11:20 [orange]

but get:
1:1:7 Why is dataByCoordinate.get(k)==null here?
1:32:18 Why is dataByCoordinate.get(k)==null here?
7:11:20 Why is dataByCoordinate.get(k)==null here?

Is there something wrong with my CoordinateComparator?
Do I not understand how TreeMap works?
Something else?
Is there an easier/better way of mapping my input to output?

Can I safely ignore the warning: Type safety: The expression
of type TestMapping.CoordinateComparator needs unchecked
conversion to conform to Comparator<? super String>

Thanks
Jeff Higgins


import java.util.ArrayList;
import java.util.Comparator;
import java.util.TreeMap;

public class TestMapping {

public static void main(String[] args)
{
ArrayList<String> metCriteria = new ArrayList<String>();
metCriteria.add("black 1:1:1 1:1:1 1:1:2 1:1:2 1:1:3 13:13:1");
metCriteria.add("brown 13:13:1 14:20:21 16:5:7");
metCriteria.add("red 1:1:1 1:1:2 1:1:2 1:1:3 1:1:3 1:1:3 1:1:4" +
" 1:1:5 1:1:5 1:1:6 1:1:7 1:1:7 13:13:1 24:49:7");
metCriteria.add("orange 5:32:37 7:11:20 7:20:36 12:18:5 19:13:5");
metCriteria.add("yellow 1:7:14 1:32:18");
metCriteria.add("green 24:49:7 41:16:14");
metCriteria.add("blue 2:38:18 19:13:5");
metCriteria.add("violet 19:13:5 24:49:7 42:24:31 72:3:19");
metCriteria.add("gray 1:2:6 44:13:11 61:2:17 70:2:4");
metCriteria.add("white 1:2:6 9:9:9");

TreeMap<String,ArrayList<String>> dataByCoordinate =
new TreeMap<String,ArrayList<String>>(
new CoordinateComparator());

for(String line : metCriteria)
{
String[] a = line.split(" ",2);
String[] b = a[1].split(" ");
for(int i = 0; i < b.length; i++)
if(dataByCoordinate.containsKey(b))
{
dataByCoordinate.get(b).add(a[0]);
}
else
{
dataByCoordinate.put(b, new ArrayList<String>());
dataByCoordinate.get(b).add(a[0]);
}
}
for(String k : dataByCoordinate.keySet())
{
if(dataByCoordinate.get(k) != null)
{
System.out.println(k + " " +
dataByCoordinate.get(k).toString());
}
else
{
System.out.println(k +
" Why is dataByCoordinate.get(k)==null here?");
}
}

}

static class CoordinateComparator implements Comparator
{
public final int compare ( Object o1, Object o2 )
{
String s1 = ((String) o1);
String s2 = ((String) o2);

String[] sa = s1.split(":");
long[] a = new long[3];
a[0] = Long.valueOf(sa[0]);
a[1] = Long.valueOf(sa[1]);
a[2] = Long.valueOf(sa[2]);

String[] sb = s2.split(":");
long[] b = new long[3];
b[0] = Long.valueOf(sb[0]);
b[1] = Long.valueOf(sb[1]);
b[2] = Long.valueOf(sb[2]);

long[] c = new long[3];
c[0] = signum(a[0] - b[0]);
c[1] = signum(a[1] - b[1]);
c[2] = signum(a[2] - b[2]);

if(c[0] < 0)
{
return -1;
}
else if(c[0]==0 && c[1]==0 && c[2]<0)
{
return -1;
}
else if(c[0]==0 && c[1]==0 && c[2]==0)
{
return 0;
}
else if(c[0]==0 && c[1]==0 && c[2]>0)
{
return 1;
}
else
{
return 1;
}
}

static final int signum ( long diff )
{
if ( diff > 0 ) return 1;
if ( diff < 0 ) return -1;
else return 0;
}
}
}
 
L

Lew

Jeff said:
Can I safely ignore the warning: Type safety: The expression
of type TestMapping.CoordinateComparator needs unchecked
conversion to conform to Comparator<? super String>

No.

Define your CoordinateComparator using generics.

You should never ignore warnings. You can disregard the "unchecked" warning
in specific situations; in fact Java pretty much guarantees that you have to.
For this use @SuppressWarnings( "unchecked" ). Note that this does not
/ignore/ the warning, it most explicitly and in a self-documenting way
suppresses it.
 
E

Eric Sosman

Jeff said:
Hi,
When I run the following code
several output lines are not what I expect.

I expect:
1:1:7 [red, red]
1:32:18 [yellow]
7:11:20 [orange]

but get:
1:1:7 Why is dataByCoordinate.get(k)==null here?
1:32:18 Why is dataByCoordinate.get(k)==null here?
7:11:20 Why is dataByCoordinate.get(k)==null here?

Is there something wrong with my CoordinateComparator?

I think so. In the case c[0]==0, c[1]!=0 it always
returns 1. Hence 1:2:3 compares greater than 1:3:4, but
at the same time 1:3:4 compares greater than 1:2:3.
Do I not understand how TreeMap works?
Something else?
Is there an easier/better way of mapping my input to output?

Can I safely ignore the warning: Type safety: The expression
of type TestMapping.CoordinateComparator needs unchecked
conversion to conform to Comparator<? super String>

Try using Comparator<String> instead of raw Comparator,
and change the types of the compare() arguments from Object
to String.
Thanks
Jeff Higgins


import java.util.ArrayList;
import java.util.Comparator;
import java.util.TreeMap;

public class TestMapping {

public static void main(String[] args)
{
ArrayList<String> metCriteria = new ArrayList<String>();
metCriteria.add("black 1:1:1 1:1:1 1:1:2 1:1:2 1:1:3 13:13:1");
metCriteria.add("brown 13:13:1 14:20:21 16:5:7");
metCriteria.add("red 1:1:1 1:1:2 1:1:2 1:1:3 1:1:3 1:1:3 1:1:4" +
" 1:1:5 1:1:5 1:1:6 1:1:7 1:1:7 13:13:1 24:49:7");
metCriteria.add("orange 5:32:37 7:11:20 7:20:36 12:18:5 19:13:5");
metCriteria.add("yellow 1:7:14 1:32:18");
metCriteria.add("green 24:49:7 41:16:14");
metCriteria.add("blue 2:38:18 19:13:5");
metCriteria.add("violet 19:13:5 24:49:7 42:24:31 72:3:19");
metCriteria.add("gray 1:2:6 44:13:11 61:2:17 70:2:4");
metCriteria.add("white 1:2:6 9:9:9");

TreeMap<String,ArrayList<String>> dataByCoordinate =
new TreeMap<String,ArrayList<String>>(
new CoordinateComparator());

for(String line : metCriteria)
{
String[] a = line.split(" ",2);
String[] b = a[1].split(" ");
for(int i = 0; i < b.length; i++)
if(dataByCoordinate.containsKey(b))
{
dataByCoordinate.get(b).add(a[0]);
}
else
{
dataByCoordinate.put(b, new ArrayList<String>());
dataByCoordinate.get(b).add(a[0]);
}
}
for(String k : dataByCoordinate.keySet())
{
if(dataByCoordinate.get(k) != null)
{
System.out.println(k + " " +
dataByCoordinate.get(k).toString());
}
else
{
System.out.println(k +
" Why is dataByCoordinate.get(k)==null here?");
}
}

}

static class CoordinateComparator implements Comparator
{
public final int compare ( Object o1, Object o2 )
{
String s1 = ((String) o1);
String s2 = ((String) o2);

String[] sa = s1.split(":");
long[] a = new long[3];
a[0] = Long.valueOf(sa[0]);
a[1] = Long.valueOf(sa[1]);
a[2] = Long.valueOf(sa[2]);

String[] sb = s2.split(":");
long[] b = new long[3];
b[0] = Long.valueOf(sb[0]);
b[1] = Long.valueOf(sb[1]);
b[2] = Long.valueOf(sb[2]);

long[] c = new long[3];
c[0] = signum(a[0] - b[0]);
c[1] = signum(a[1] - b[1]);
c[2] = signum(a[2] - b[2]);

if(c[0] < 0)
{
return -1;
}
else if(c[0]==0 && c[1]==0 && c[2]<0)
{
return -1;
}
else if(c[0]==0 && c[1]==0 && c[2]==0)
{
return 0;
}
else if(c[0]==0 && c[1]==0 && c[2]>0)
{
return 1;
}
else
{
return 1;
}
}


An easier way to write this might be

if (c[0] != 0)
return c[0];
if (c[1] != 0)
return c[1];
return c[2];

.... with the added benefit that it's easy to see the
Comparator contract is fulfilled.
 
J

Jeff Higgins

Eric said:
Jeff Higgins wrote:
Is there something wrong with my CoordinateComparator?

I think so. In the case c[0]==0, c[1]!=0 it always
returns 1. Hence 1:2:3 compares greater than 1:3:4, but
at the same time 1:3:4 compares greater than 1:2:3.

An easier way to write this might be

if (c[0] != 0)
return c[0];
if (c[1] != 0)
return c[1];
return c[2];

how nice :)
... with the added benefit that it's easy to see the
Comparator contract is fulfilled.


Try using Comparator<String> instead of raw Comparator,
and change the types of the compare() arguments from Object
to String.

Great!
Straightforward help greatly appreciated.
Thanks so much.
Jeff Higgins

static class CoordinateComparator
implements Comparator<String>
{
public final int compare(String s1, String s2)
{// thanks rg es
String[] sa = s1.split(":");
long[] a = new long[3];
a[0] = Long.valueOf(sa[0]);
a[1] = Long.valueOf(sa[1]);
a[2] = Long.valueOf(sa[2]);

String[] sb = s2.split(":");
long[] b = new long[3];
b[0] = Long.valueOf(sb[0]);
b[1] = Long.valueOf(sb[1]);
b[2] = Long.valueOf(sb[2]);

long[] c = new long[3];
c[0] = signum(a[0] - b[0]);
c[1] = signum(a[1] - b[1]);
c[2] = signum(a[2] - b[2]);

if (c[0] != 0)
return (int)c[0];
if (c[1] != 0)
return (int)c[1];
return (int)c[2];
}
}
import java.util.ArrayList;
import java.util.Comparator;
import java.util.TreeMap;

public class TestMapping {

public static void main(String[] args)
{
ArrayList<String> metCriteria = new ArrayList<String>();
metCriteria.add("black 1:1:1 1:1:1 1:1:2 1:1:2 1:1:3 13:13:1");
metCriteria.add("brown 13:13:1 14:20:21 16:5:7");
metCriteria.add("red 1:1:1 1:1:2 1:1:2 1:1:3 1:1:3 1:1:3 1:1:4" +
" 1:1:5 1:1:5 1:1:6 1:1:7 1:1:7 13:13:1 24:49:7");
metCriteria.add("orange 5:32:37 7:11:20 7:20:36 12:18:5 19:13:5");
metCriteria.add("yellow 1:7:14 1:32:18");
metCriteria.add("green 24:49:7 41:16:14");
metCriteria.add("blue 2:38:18 19:13:5");
metCriteria.add("violet 19:13:5 24:49:7 42:24:31 72:3:19");
metCriteria.add("gray 1:2:6 44:13:11 61:2:17 70:2:4");
metCriteria.add("white 1:2:6 9:9:9");

TreeMap<String,ArrayList<String>> dataByCoordinate =
new TreeMap<String,ArrayList<String>>(
new CoordinateComparator());

for(String line : metCriteria)
{
String[] a = line.split(" ",2);
String[] b = a[1].split(" ");
for(int i = 0; i < b.length; i++)
if(dataByCoordinate.containsKey(b))
{
dataByCoordinate.get(b).add(a[0]);
}
else
{
dataByCoordinate.put(b, new ArrayList<String>());
dataByCoordinate.get(b).add(a[0]);
}
}
for(String k : dataByCoordinate.keySet())
{
if(dataByCoordinate.get(k) != null)
{
System.out.println(k + " " +
dataByCoordinate.get(k).toString());
}
else
{
System.out.println(k +
" Why is dataByCoordinate.get(k)==null here?");
}
}

}

static class CoordinateComparator implements Comparator
{
public final int compare ( Object o1, Object o2 )
{
String s1 = ((String) o1);
String s2 = ((String) o2);

String[] sa = s1.split(":");
long[] a = new long[3];
a[0] = Long.valueOf(sa[0]);
a[1] = Long.valueOf(sa[1]);
a[2] = Long.valueOf(sa[2]);

String[] sb = s2.split(":");
long[] b = new long[3];
b[0] = Long.valueOf(sb[0]);
b[1] = Long.valueOf(sb[1]);
b[2] = Long.valueOf(sb[2]);

long[] c = new long[3];
c[0] = signum(a[0] - b[0]);
c[1] = signum(a[1] - b[1]);
c[2] = signum(a[2] - b[2]);

if(c[0] < 0)
{
return -1;
}
else if(c[0]==0 && c[1]==0 && c[2]<0)
{
return -1;
}
else if(c[0]==0 && c[1]==0 && c[2]==0)
{
return 0;
}
else if(c[0]==0 && c[1]==0 && c[2]>0)
{
return 1;
}
else
{
return 1;
}
}> static final int signum ( long diff )
{
if ( diff > 0 ) return 1;
if ( diff < 0 ) return -1;
else return 0;
}
}
}

 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top