How to use a compareTo function in java - java

public class Pair<F,S> implements Comparable<Pair<F,S>> {
public F first;
public S second;
public F first() {
return first;
}
public void setFirst(F first) {
this.first=first;
}
public S second() {
return second;
}
public void setSecond(S second) {
this.second=second;
}
public Pair(F first, S second) {
super();
this.first=first;
this.second=second;
}
public int hashCode() {
return(first.hashCode()^second.hashCode());
}
#Override
public boolean equals(Object obj) {
return obj instanceof Pair && ((Pair)obj).first.equals(first) && (Pair)obj).second.equals(second);
}
public String toString() {
return first + " / " + second;
}
#SuppressWarnings("unchecked")
public int compareTo(Pair<F, S> o) throws ClassCastException{
int firstCompared = ((Comparable<F>) first).compareTo(o.first());
if(firstCompared!=0) return(firstCompared);
return(((Comparable<S>)second).compareTo(o.second()));
}
}
and and I have the following class:
public class Point{
public int x;
public int y;
Point(int x, int y){
this.x = x;
this.y = y;
}
public String toString(){
return "(" + x + "," + y + ")";
}
}
My Question:
Suppose i have four points p1, p2, p3, p3. How can i use the Pair class to compare the pair (p1, p2) with (p2,p3)? How can i use the compareTo function? Thank you

You can't use this since your Point class does not implement Comparable<Point>. You must fix this first. And in fact, you should constrain your F and S to only classes that implement Comparable.
To constrain F and S, change class declaration to:
public class Pair<F extends Comparable<F>, S extends Comparable<S>> implements Comparable<Pair<F,S>> {
With that, you no longer have to cast in compareTo:
#Override
public int compareTo(Pair<F, S> that) {
int cmp = this.first.compareTo(that.first);
if (cmp == 0)
cmp = this.second.compareTo(that.second);
return cmp;
}
When writing code below, the compiler will tell you that Point must implement Comparable<Point>.
Once you do that, you can:
Pair<Point, Point> pair1 = new Pair<>(p1, p2);
Pair<Point, Point> pair2 = new Pair<>(p3, p4);
int cmp = pair1.compareTo(pair2);

Related

How to find a maximum value of an index in a list of lists

I have a list of lists of objects, with each single innerlist having 3 Object elements, theoretically a String and two doubles,say a and b, in that order.
ArrayList<ArrayList<Object>> timings = new ArrayList<ArrayList<String>>()
for (int runnerno = 0; runnerno < runners; runnerno++) {
ArrayList<Object> thisrunner = new ArrayList<Object>();
thisrunner.add(sc.next()); //string
thisrunner.add(sc.nextDouble()); //double a
thisrunner.add(sc.nextDouble()); //double b
timings.add(thisrunner);
sc.nextLine();
}
How do I find out the maximum a value in my list of lists? ie. I want to find an indexed maximum.
1) Lets make a better encapsulation of your data object, call it FooBar
public class FooBar {
private String text;
private Double x;
private Double y;
public FooBar() {
}
public FooBar(String text,Double x,Double y) {
this.text = text;
this.x = x;
this.y = y;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public Double getX() {
return x;
}
public void setX(Double x) {
this.x = x;
}
public Double getY() {
return y;
}
public void setY(Double y) {
this.y = y;
}
}
2) Populate a list of FooBars
List<FooBar> points = new ArrayList<FooBar>();
for( int i = 0; i < 1000; i++ ) {
FooBar f = new FooBar("Text" + i,
ThreadLocalRandom.current().nextDouble(0, 100),
ThreadLocalRandom.current().nextDouble(0, 100));
points.add(f);
}
3) Use streams.max (with Comparator)
Optional<FooBar> maxFooBar = points.stream().max(new Comparator<FooBar>() {
#Override
public int compare(FooBar o1, FooBar o2) {
return o1.getX().compareTo(o2.getX());
}
});
System.out.println("Max Point: " + maxFooBar.get().getX());
4) Or use Collections.max
FooBar maxFooBar = Collections.max(points, new Comparator<FooBar>() {
#Override
public int compare(FooBar o1, FooBar o2) {
return o1.getX().compareTo(o2.getX());
}
});
System.out.println("Max Point: " + maxFooBar.getX());
5) Or just sort the list yourself and get the first item (if sorted Descending; get last if Ascending)
points.sort(new Comparator<FooBar>() {
#Override
public int compare(FooBar o1, FooBar o2) {
return -1 * o1.getX().compareTo(o2.getX());
}
});
System.out.println("Max Point: " + points.get(0).getX());
The maximum double value of all values that are of type Double in the list of lists, like so
public static double findMax(List<List> lists) {
double max = Double.MIN_VALUE;
for (List list : lists)
for (Object o : list)
if (o instanceof Double)
if ((Double) o).doubleValue() > max)
max = ((Double) o).doubleValue();
return max;
}
what if you use Comparator interface for sorting your each individual Runner object in ascending order and the last Runner object inside timings treeSet would be always the index of maximum value
we cannot use the ArrayList since it does not have any constructor which support Comparator as an argument
public class Runner {
private String s;
public double a;
public double b;
public Runner() {}
public Runner(String s, double a, double b) {
this.s = s;
this.a = a;
this.b = b;
}
#Override
public String toString() {
return s + " " + a + " " + b;
}
}
calling class
import java.util.Comparator;
import java.util.Scanner;
import java.util.TreeSet;
public class Calling {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int runners = 3;
TreeSet<Runner> timings = new TreeSet<>(new MyComparator());
for (int runnerno = 0; runnerno < runners; runnerno++) {
timings.add(new Runner(sc.nextLine(), Double.parseDouble(sc.nextLine()), Double.parseDouble(sc.nextLine())));
}
System.out.println(timings);
System.out.println("max value " + timings.last());
}
}
class MyComparator implements Comparator<Runner> {
#Override
public int compare(Runner o1, Runner o2) {
return Double.valueOf(o1.a).compareTo(Double.valueOf(o2.a));
}
}

Pass enum class as parameter to method in java

I have two different Enums:
public enum A {
mass(10); // many other values omitted for clarity
private final int m;
private A(int m) { this.m = m; }
public int value() { return this.m; }
}
public enum B {
mass(100); // many other values omitted for clarity
private final int m;
private B(int m) { this.m = m; }
public int value() { return this.m; }
}
and want to pass enum class as parameter to my function. From other answers that I found on SO, it is suggested that I can pass Class, but I am not sure how to correctly detect and use A or B enum in the function body:
public int mass(Class<?> clazz) {
// Is it the best way? How to avoid a bunch of ifs?
if (clazz == A.class) return A.mass.value();
if (clazz == B.class) return B.mass.value();
}
Not sure what you're trying to accomplish buddy but you seem to be in need of polymorphism. Try using an interface with Enums like this:
public enum A implements MassProvider {
MASS(10);
private int mass;
A(int mass) {
this.mass = mass;
}
#Override
public int getMass() {
return mass;
}
}
public enum B implements MassProvider {
MASS(100);
private int mass;
B(int mass) {
this.mass = mass;
}
#Override
public int getMass() {
return mass;
}
}
public interface MassProvider {
int getMass();
}
public static int mass(MassProvider p) {
return p.getMass();
}
Basically instead of passing a class to the mass method you pass a MassProvider that is implemented by both enums.

Is it possible to get public static field from template class argument?

Given
class A {
public static A newInstance(int x) { ... }
}
And several classes containing static fields of type A
class B1 {
public static A MIN = A.newInstance(10);
}
class B2 {
public static A MIN = A.newInstance(15);
}
I would like to parameterize a class with B1 or B2 to get MIN field of type A from class B in the class C:
class C <T, P> {
private T t = ???;
}
When C<A, B1> c = new C(); what should be placed instead ??? to get B1.MIN?
Is it possible?
EDIT:
Thank you for the answers, I have upvoted both.
I have arrived simply at
class C <T, P> {
private T t;
public C(T min) {
this.t = min;
}
}
This will be just C<A, B1> c = new C<A, B1>(B1.MIN); because as you can see it is hard to avoid a constructor for C taking an instance of B1 or smth like that. But in this case B1 at least not instantiated.
You can use an interface to achieve this behavior:
class A {
public static A newInstance() { return new A(); }
}
interface HasMin {
public static A MIN = null;
}
class B1 implements HasMin {
public static A MIN = A.newInstance();
}
class B2 implements HasMin {
public static A MIN = A.newInstance();
}
class C<T extends HasMin> {
private A t = T.MIN;
}
Then you can create: C<B1> and C<B2> and use both.
As Tom suggested in the comments below, this approach is limited to use static fields. An even better approach would be:
public class Play {
public static void main(String[] args) {
B1 b1 = new B1();
C<B1> c = new C<>(b1);
System.out.println(c.getA()); // prints: A{ x=10 }
B2 b2 = new B2();
C<B2> c2 = new C<>(b2);
System.out.println(c2.getA()); // prints: A{ x=20 }
}
}
class A {
private int x;
public A(int x) {
this.x = x;
}
#Override
public String toString() {
return "A{ x=" + x + " }";
}
public static A newInstance(int x) {
return new A(x);
}
}
interface GetMin {
public A getMin();
}
class B1 implements GetMin {
public A MIN = A.newInstance(10);
#Override
public A getMin() {
return MIN;
}
}
class B2 implements GetMin {
public A MIN = A.newInstance(20);
#Override
public A getMin() {
return MIN;
}
}
class C<T extends GetMin> {
private A a = null;
public C(T t) {
a = t.getMin();
}
public A getA() {
return a;
}
}
I would forget static and have a concrete instance of an interface:
public interface Bounds<T> {
T min();
}
The concrete instance could be singleton, so next best thing to a static:
public enum B implements Bounds<A> {
INSTANCE;
private final A min = A.newInstance(10);
#Override
public A min() {
return min;
}
}
C then defined like so:
public class C<T, P extends Bounds<T>> {
private T min;
public C(P bounds) {
min = bounds.min();
}
public T getMin() {
return min;
}
}
Usage:
C<A, B> c = new C(B.INSTANCE);
Self describing
Maybe you don't want this meta data type (B), maybe you want types to describe themselves. So C could be defined for types that can describe their own bounds:
public class C<T extends Bounds<T>> {
private T min;
public C(T anyT) {
min = anyT.min();
}
public T getMin() {
return min;
}
}
Usage:
C<A> c = new C(A.zero); //any A will do
Where A is:
public class A implements Bounds<A>{
public final static A zero = A.newInstance(0);
private final static A min = A.newInstance(10);
public static A newInstance(int x) {
return new A(x);
}
private int x;
public A(int x) {
this.x = x;
}
#Override
public A min() {
return min;
}
}

Java Generic treeMap with comparator declaration without warning

There is any way i can do next with out getting the yellow warning / #SuppressWarnings("unchecked")
Generics objects :
P=product to compare,C = custoumer
public static myComparator<Product<P>> comparator= new myComparator<Product<P>>();
comparator declaration is outside "insertIntoMap" method,
i cant use the Product object inside "insertIntoMap" method .
public static <P,C> TreeMap<P, C> insertIntoMap(LinkedHashSet<P> set,C[] ac){
#SuppressWarnings("unchecked")
TreeMap<P,C> treeMap = new TreeMap<P,C>((Comparator<? super P>) comparator);
int itrIndex=0;
Iterator<P> itr = set.iterator();
while(itr.hasNext()){
treeMap.put(itr.next(), ac[itrIndex]);
itrIndex++;
}
return (TreeMap<P, C>) treeMap;
}
public static class myComparator<E> implements Comparator<Product<? super E>>{
#Override
public int compare(Product<? super E> o1, Product<? super E> o2) {
if(o1.getName().length()>o2.getName().length())
return 1;
else return -1;
}
}
Product Class :
public static class Product<E> implements Comparable<E>{
private E serialNum;
private String name;
Product(E serialNum,String name){
setSerialNum(serialNum);
setName(name);
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result;
result = prime * result + ((serialNum == null) ? 0 : serialNum.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
Product<?> other = (Product<?>) obj;
if (serialNum.equals(other.serialNum))return true;
else return false;
}
public E getSerialNum() {
return serialNum;
}
public void setSerialNum(E serialNum) {
this.serialNum = serialNum;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String toString() {
return serialNum.toString()+": "+name;
}
#Override
public int compareTo(E o) {
if(this.hashCode()>o.hashCode())return 1;
else if(this.hashCode()<o.hashCode()) return -1;
else return -1;
}
}
Thanks !
From the code you posted it seems:
myComparator should not be generic:
public class myComperator implements Comparator<Product<?>> {
#Override
public int compare(Product<?> o1, Product<?> o2) {
if (o1.getName().length() > o2.getName().length())
return 1;
else if (o1.getName().length() < o2.getName().length())
return -1;
else
return -1;
}
}
insertIntoMap should only work for P extending Product. Otherwise you cannot use myComperator (which compares Products):
public static <P extends Product<?>, C> TreeMap<P, C> insertIntoMap(
LinkedHashSet<P> set, C[] ac) {
TreeMap<P, C> treeMap = new TreeMap<P, C>(new myComperator());
int itrIndex = 0;
Iterator<P> itr = set.iterator();
while (itr.hasNext()) {
treeMap.put(itr.next(), ac[itrIndex]);
itrIndex++;
}
return treeMap;
}

static methods or setter or getters?

public class Operations {
private int add;
private int sub;
private int mul;
private int div;
private double sqrt;
public void setadd(int a, int b) {
add = a + b;
}
public void setsub(int a, int b) {
sub = a - b;
}
public void setmul(int a, int b) {
mul = a * b;
}
public void setdiv(int a, int b) {
div = a / b;
}
public void setsqrt(double sqt) {
sqrt = Math.sqrt(sqt);
}
public int getadd() {
return add;
}
public int getsub() {
return sub;
}
public int getmul() {
return mul;
}
public int getdiv() {
return div;
}
public double getsqrt() {
return sqrt;
}
}
Do I have to do a prototype of this or in Java that's not necessary, also how do I use static methods here instead of setter and getter.. I'm trying to do a calculator.. Are my methods ok?
Make all the operations (addition, multiplication, division, etc ) static methods of a Calculator class:
class Calculator{
public static int add(int a, int b){
return a+b;
}
...
I don't really understand the point of setting and getting, why not have your calculator like this:
public class Calculator {
public int add(int a, int b){
return a + b;
}
public int sub(int a , int b){
return a - b;
}
public int mul(int a, int b){
return a * b;
}
public int div(int a, int b){
return a/b;
}
public double sqrt(double sqt){
return Math.sqrt(sqt);
}
Your methods are all wrong, because you modeled your operation incorrectly. It is not supposed to contain its result, and it should do only one operation, not all of them. Operation object should be immutable, and it should produce an answer to a specific operation given two operands. You should separate binary operations from unary as well.
interface BinaryOp {
double calculate(double left, double right);
}
interface UnaryOp {
double calculate(double operand);
}
private static final BinaryOp ADD = new BinaryOp() {
double calculate(double left, double right) {
return left + right;
}
};
private static final BinaryOp SUB = new BinaryOp() {
double calculate(double left, double right) {
return left - right;
}
};
private static final BinaryOp MUL = new BinaryOp() {
double calculate(double left, double right) {
return left * right;
}
};
private static final BinaryOp DIV = new BinaryOp() {
double calculate(double left, double right) {
return left / right;
}
};
private static final UnaryOp SQRT = new UnaryOp() {
double calculate(double operand) {
return Math.sqrt(operand);
}
};
Now you can organize your operators by name:
private static final Map<String,BinaryOp> opByName = new HashMap<String,BinaryOp>();
static {
opByName.put("+", ADD);
opByName.put("-", SUB);
opByName.put("*", MUL);
opByName.put("/", DIV);
}
With this map, you can use your operations to perform calculations for you:
String op = "+";
double left = 123;
double right = 456;
double res = opByName.get(op).calculate(left, right);
Just to answer the part of the question not answered yet:
You do not need prototypes in java.
This looks like a good use for an enum or two:
enum BinOp {
ADD {
#Override
public int eval(int leftArg, int rightArg) {
return leftArg + rightArg;
}
#Override
public String symbol() {
return "+";
}
},
SUBTRACT {
#Override
public int eval(int leftArg, int rightArg) {
return leftArg - rightArg;
}
#Override
public String symbol() {
return "-";
}
}
// etc.
;
public abstract int eval(int leftArg, int rightArg);
public abstract String symbol();
}
And a similar enum for unary operators (only SQRT, at the moment).
You could use these as follows:
int left = 3;
int right = 2;
for (BinOp op : BinOp.values()) {
System.out.println("The value of "
+ left + " " + op.symbol() + " " + right " is "
+ op.eval(left, right)
);
}

Categories