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)
);
}
Related
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));
}
}
I have a CSV conversion class. It's job is to muck with values and produce few outputs. The CSV row has around 30 columns. I've modelled via immutable objects:
In(i1, i2, ..., iM)
OutA(a1, a2, ..., aN)
OutB(b1, b2, ..., bO)
...
OutK(k1, k2, ..., kP)
OutX(x1, x2, ..., xQ)
There are inter-dependencies: b1 is the same as a1, b2 is calculated based on a2, they combine to the final result (OutX). Some calculations are expensive.
The end result is a huge method that looks similar to this simplified monster:
OutX method(In in) {
I1 i1 = in.getI1();
I1 i2 = in.getI2();
...
I1 iM = in.getIM();
A1 a1 = fa1(i1, i2);
A2 a2 = fa2(i2, i5, iM);
...
AN aN = ...;
OutA outA = new OutA(
a1,
a2,
...,
aN);
A1 b1 = a1;
B2 b2 = fb2(a2, i5, i13);
...
BO bO = ...;
OutB outB = new OutB(
b1,
b2,
...,
bO);
...
return new OutX(
outA,
outB,
...,
outK);
}
'Tis wonderful being immutable and type-checked and stuff. 'Tis also 300 lines and this is for each "flavor" of CSV. Ugh. Breaking up just creates methods that are mostly parameters + constructor calls.
Are there patterns or libraries to un-Frankenstein this?
The Adapter pattern might be helpful. Each layer/shell delegates as much as possible to build up to the final result. Here's an example:
public class App {
public static void main(String[] args) {
App app = new App();
app.process();
}
private void process() {
In in = new In(1, 2, 3);
OutA a = new OutA(in);
OutB b = new OutB(a);
System.out.println(b);
}
public class In {
private final int i1;
private final int i2;
private final int i3;
public In(int i1, int i2, int i3) {
this.i1 = i1;
this.i2 = i2;
this.i3 = i3;
}
public int getI1() {
return i1;
}
public int getI2() {
return i2;
}
public int getI3() {
return i3;
}
}
public class OutA {
private final In in;
private Integer a3;
public OutA(In in) {
this.in = in;
}
public int getA1() {
return in.getI1();
}
public int getA2() {
return in.getI2() * 2;
}
public int getA3() {
if (a3 == null) {
// a3 = some expensive calculation
a3 = 1; // hold the value to avoid expensive calculation next time method is called
}
return a3;
}
}
public class OutB {
private final OutA a;
public OutB(OutA a) {
this.a = a;
}
public int getB1() {
return a.getA1();
}
public int getB2() {
// a.getA3() is expensive, but only the first time it's called
return a.getA3() + 4;
}
public int getB3() {
// a.getA3() is expensive, but only the first time it's called
return a.getA3() + 9;
}
public String toString() {
return "b1: " + getB1() + " b2: " + getB2() + " b3: " + getB3();
}
}
}
Output: b1: 1 b2: 5 b3: 10
UPDATE: here's a more interesting example using a factory to have different calculations, but still using the same interface.
public class App {
public static void main(String[] args) {
App app = new App();
app.process();
}
private void process() {
In in = new In(1, 2, 3);
OutXFactory factory = new OutXFactory();
OutX resultType1 = factory.create(in, CSVType.TYPE_1);
System.out.println(resultType1);
OutX resultType2 = factory.create(in, CSVType.TYPE_2);
System.out.println(resultType2);
}
public class In {
private final int i1;
private final int i2;
private final int i3;
public In(int i1, int i2, int i3) {
this.i1 = i1;
this.i2 = i2;
this.i3 = i3;
}
public int getI1() {
return i1;
}
public int getI2() {
return i2;
}
public int getI3() {
return i3;
}
}
public enum CSVType {
TYPE_1, TYPE_2;
}
public class OutA {
private final In in;
private Integer a3;
public OutA(In in) {
this.in = in;
}
public int getA1() {
return in.getI1();
}
public int getA2() {
return in.getI2() * 2;
}
public int getA3() {
if (a3 == null) {
// a3 = some expensive calculation
a3 = 1; // hold the value to avoid expensive calculation next time method is called
}
return a3;
}
}
public class OutB {
private final OutA a;
public OutB(OutA a) {
this.a = a;
}
public int getB1() {
return a.getA1();
}
public int getB2() {
// a.getA3() is expensive, but only the first time it's called
return a.getA3() + 4;
}
public int getB3() {
// a.getA3() is expensive, but only the first time it's called
return a.getA3() + 9;
}
}
public interface OutX {
public int getX1();
public int getX2();
public int getX3();
}
public abstract class AbstractOutX implements OutX {
#Override
public String toString() {
return "x1: " + getX1() + " x2: " + getX2() + " x3: " + getX3();
}
}
public class OutXA extends AbstractOutX {
private final OutA a;
public OutXA(OutA a) {
this.a = a;
}
#Override
public int getX1() {
return a.getA1() + 1;
}
#Override
public int getX2() {
return a.getA2() + a.getA3() + 2;
}
#Override
public int getX3() {
return a.getA1() + a.getA2() + 3;
}
}
public class OutXAB extends AbstractOutX {
private final OutA a;
private final OutB b;
public OutXAB(OutA a, OutB b) {
this.a = a;
this.b = b;
}
#Override
public int getX1() {
return a.getA1() + b.getB1();
}
#Override
public int getX2() {
return a.getA2() * b.getB2();
}
#Override
public int getX3() {
return (int) Math.pow(a.getA3(), b.getB3());
}
}
public class OutXFactory {
public OutX create(In in, CSVType type) {
if (type == CSVType.TYPE_1) {
OutA a = new OutA(in);
return new OutXA(a);
} else {
OutA a = new OutA(in);
OutB b = new OutB(a);
return new OutXAB(a, b);
}
}
}
}
I'm having a hard time to understand the ClassCastException and it is crashing the line that it is commented. Please explain why its doing in that? Thanks
public class tester {
private static B<Data> build(char[] ss, double[] f) {
B<Data> res = new B<Data>();
PriorityQueue<String> q = new PriorityQueue<String>();
...
double c_x = 20.1;
Data h = res.getElement(); //throws ClassCastException
if(h.getFreq()==c_x){
...
}
}//end of method
}//end of class tester
public class Data{
private char symbol;
private double freq;
public Data(char c, double f){
symbol = c;
freq = f;
}
public char getSymbol(){
return symbol;
}
public double getFreq(){
return freq;
}
public String toString(){
return freq + ":" + symbol;
}
public int compareTo(Data o) {
return (int) (this.freq-o.freq);
}
}//end of class Data
public class B<T> {
// the fields
private T element;
private B<T> left;
private B<T> right;
// create an empty node
public B() {
this(null, null, null);
}
public B(T theElement, B<T> lt, B<T> rt) {
element = theElement;
left = lt;
right = rt;
}
// return the element
public T getElement() {
return element;
}
public void setElement(T x) {
element = x;
}
}//end of class B
Exception:
Exception in thread "main" java.lang.ClassCastException: java.lang.Double cannot be cast to Data
at tester.build(tester.java:40)
at tester.main(tester.java:83)
Do you happen to have some method that takes a raw type B? Because if you do, you can assign any value to element in that method.
Example
static void rawSet(B b) {
b.setElement(1.0); // you can put anything here
}
public static void main(String [] args) {
B<Integer> b = new B<>();
rawSet(b);
Integer x = b.getElement(); // ClassCastException
}
Since you didn't post complete code I could run, I have to make my own.
Data.java:
package test;
public class Data {
private char symbol;
private double freq;
public Data(char c, double f){
symbol = c;
freq = f;
}
public char getSymbol(){
return symbol;
}
public double getFreq(){
return freq;
}
public String toString(){
return freq + ":" + symbol;
}
public int compareTo(Data o) {
return (int) (this.freq-o.freq);
}
}
GenericType.java (replacing B):
package test;
public class GenericType<T> {
private T element;
public GenericType() {
element = null;
}
public T getElement() {
return element;
}
public void setElement(T x) {
element = x;
}
}
Test.java (main program):
package test;
public class Test {
public static void main(String[] args) {
GenericType<Data> obj = new GenericType<Data>();
Data d = obj.getElement();
System.out.println("Data retrieved");
}
}
When executed:
> java test.Test
Data retrieved
So there's a problem somewhere, and you omitted it.
How to create a Minimal, Complete, and Verifiable example
https://stackoverflow.com/help/mcve
Generics is only a compile-time concept. At runtime they are just Objects. Your problem most likely lies in how you instantiate B.
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);
Im working with a stand-alone class, and a main driver, here's the stand-alone class:
public class Bugs{
private String bugType;
private int legs;
private int arms;
private String nativeTo;
public Bugs(String bt, int l, int a, String nt){
bt=bugType;
l=legs;
a=arms;
nt=nativeTo;
}
public Bugs(String bt, int l, int a){
bt=bugType;
l=legs;
a=arms;
nativeTo="Not known";
}
public String getbt(){
return bugType;
}
public void setbugType(String bugType){
this.bugType=bugType;
}
public int getlegs(){
return legs;
}
public void setlegs(int legs){
this.legs=legs;
}
public int getarms(){
return arms;
}
public void setarms(int arms){
this.arms=arms;
}
public String getnativeTo(){
return nativeTo;
}
public void setnativeTo(String nativeTo){
this.nativeTo=nativeTo;
}
public String toString(){
return bugType + " has " + legs + arms + nativeTo;
}
}
And here's the main driver:
public class myBugs{
public static void main (String args[]){
Bugs asiaBeetle = new Bugs("Asian Beetle", 2, 2, "Japan");
Bugs spider = new Bugs("Spider", 1000, 0);
Bugs americanBeetle = new Bugs("American Beetle", 2, 2, "USA");
System.out.println(asiaBeetle);
}
}
JGRASP keeps returning "null has 00null", every time I run the main driver. What am I doing wrong?
Swap your assignments in your constructors :
public Bugs(String bt, int l, int a, String nt){
bugType = bt;
legs = l;
arms = a;
nativeTo = nt;
}
You have to do the same for the other :
public Bugs(String bt, int l, int a){
bugType = bt;
legs = l;
arms = a;
nativeTo="Not known";
}
Change your constructor to this offcourse do the same for the other as well
public Bugs(String bt, int l, int a, String nt){
bugType=bt;
legs=l;
arms=a;
nativeTo= nt;
}