NullPointerException when trying to run PostFixCalculator in Java - java

I have gotten my code to work to the extent that it can compile and run but now I get exceptions at two different places as follows:
Exception in thread "main" java.lang.NullPointerException
at PostFixCalculator.storeOperand(PostFixCalculator.java:97)
at CalcTest.main(CalcTest.java:17)
...I am not sure at all what is wrong. The first error is in the code that follows at
myStack.push(operand);
But I am so lost as to where to go from here...
import java.util.*;
public class PostFixCalculator {
private DoubleStack<Double> myStack;
private ArrayList<Double> evalList;
//private Map<String, Operator> operatorMap;
Map<String, Operator> operatorMap = new HashMap<String, Operator>();
public PostFixCalculator () {
Map<String, Operator> operatorMap = new HashMap<String, Operator>();
operatorMap.put("+", new AddOp());
operatorMap.put("add", new AddOp());
operatorMap.put("-", new SubOp());
operatorMap.put("sub", new SubOp());
operatorMap.put("/", new DivOp());
operatorMap.put("div", new DivOp());
operatorMap.put("*", new MultOp());
operatorMap.put("mult", new MultOp());
operatorMap.put("=", new PrintOp());
operatorMap.put("print", new PrintOp());
}
public class AddOp implements Operator {
public AddOp () {
}
public int numArgs () {
return 2;
}
public double eval (List<Double> args) {
double a = args.get(0);
double b = args.get(1);
double sum = a + b;
return sum;
}
}
public class SubOp implements Operator {
public SubOp () {
}
public int numArgs () {
return 2;
}
public double eval (List<Double> args) {
double a = args.get(0);
double b = args.get(1);
double difference = a - b;
return difference;
}
}
public class DivOp implements Operator {
public DivOp () {
}
public int numArgs () {
return 2;
}
public double eval (List<Double> args) {
double a = args.get(0);
double b = args.get(1);
double quotient = a / b;
return quotient;
}
}
public class MultOp implements Operator {
public MultOp () {
}
public int numArgs () {
return 2;
}
public double eval (List<Double> args) {
double a = args.get(0);
double b = args.get(1);
double product = a * b;
return product;
}
}
public class PrintOp implements Operator {
public PrintOp () {
}
public int numArgs () {
return 1;
}
public double eval (List<Double> args) {
System.out.println(myStack.pop());
return 1;
}
}
public void storeOperand (double operand) {
myStack.push(operand);
}
public void evalOperator (String operator) {
Operator o = operatorMap.get(operator);
ArrayList<Double> evalList = new ArrayList<Double>();
if (o.numArgs() == 2) {
double a = myStack.pop();
double b = myStack.pop();
evalList.add(a);
evalList.add(b);
}
else {
double a = myStack.pop();
evalList.add(a);
}
double answer = o.eval(evalList);
myStack.push(answer);
}
}

Make sure you're importing everything you are using. At the top of your file, add:
import java.util.ArrayList;
If you're using Eclipse you can press Ctrl-Shift-O to fix your imports.

You are still missing the following imports:
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Then check the remaining errors related to your custom types.

Related

How do I compare 2 objects with 1 parameter?

I made a java program that compares the distance between 2 objects
I managed to figure out how to solve it when I make a class with 2 parameters and compare these with the formula seen below;
public class RasterServices {
public static double distance (SimpleRasterElement a, SimpleRasterElement b) {
double d;
d = Math.sqrt(((b.x-a.x)*(b.x-a.x)) + ((b.y-a.y)*(b.y-a.y)));
return d;
}
public class SimpleRasterElement {
public int id;
public double x;
public double y;
public double height;
}
public class SimpleRasterElementTest {
public static void main (String[] args)
{
SimpleRasterElement a, b ; // Deklarera variabeln
a = new SimpleRasterElement (); // Skapa en instans (med ’new’),
b = new SimpleRasterElement ();
// Tilldela variablerna i ’a’ värden:
a.id = 1;
a.x = 6.0;
a.y = 8.0;
a.height = 10.5;
// Tilldela variablerna i ’b’ värden:
b.id = 1;
b.x = 9.0;
b.y = 12.0;
b.height = 15.5;
System.out.println (RasterServices.distance(a,b));
}
}
I can then test this via using my test program RasterServices.distance(a,b)
But now I want to make my variables private, use getters and create the distance() method within the RasterElement-class, and now I'm hardstuck.
public class RasterElementTest {
public static void main(String[] args) {
RasterElement re_a = new RasterElement(1, 6.0, 8.0, 10.5);
RasterElement re_b = new RasterElement(1, 9.0, 12.0, 15.5);
double d = re_a.distance(re_b);
System.out.println(d);
}
}
asd
public class RasterElement {
private final int id;
private final double x;
private final double y;
private final double height;
public RasterElement (int id_nr, double x_val, double y_val, double height_val) {
id = id_nr;
x = x_val;
y = y_val;
height = height_val;
}
public int getId () {
return id;
}
public double getX () {
return x;
}
public double getY () {
return y;
}
public double getHeight () {
return height;
}
public double distance (RasterElement a) {
double d;
d = Math.sqrt(((b.getX()-a.getX())*(b.getX()-a.getX())) + ((b.getY()-a.getY())*b.getY()-a.getY()));
return d;
}
}
But here in distance() i'm only allowed ONE parameter, can someone please explain to me how I can compare two elements/objects when I'm only allowed one parameter in the function?
(By using re_a.distance(re_b); in my test-code)
Thanks, sorry for the long post B-)
(how do I get the b-value into the equation in the method distance in the class RasterElement..?)
Change b to this. Also, you can eliminate d and return directly. Like,
public double distance (RasterElement a) {
return Math.sqrt(((this.getX()-a.getX())*(this.getX()-a.getX()))
+ ((this.getY()-a.getY())*this.getY()-a.getY()));
}

Can't seem to get .doubleValue() to work (I have the latest version of Java)

So I am having problem with a method I created, called averageCost(). The error I get is:
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
The method doubleValue() is undefined for the type Double
at queue.averageCost(queue.java:38)
at queue.main(queue.java:47)
And previously I tried just adding a double value to a Double object which obviously didn't work. So I found the .doubleValue method but I can't get it to work. I added all my code (everything else works just fine) in case that clears anything up. I have been stuck on this for a couple days now while working on other stuff please help ):
import java.util.LinkedList;
public class queue<Double> {
private LinkedList<Double> linklist;
private String symbol;
private String name;
private int shares;
private Double price;
public queue(String symbol2, String name2, int shares2, Double price2) { //so far, I have a linkedlist that works
linklist = new LinkedList<Double>();
shares = shares2;
price = price2;
symbol = symbol2;
name = name2;
bigAdd(shares, price);
}
public void add(Double e) {
linklist.add(e);
}
public Double take() {
return linklist.poll();
}
public void bigAdd (int shares2, Double price2) {
while(shares2>0) {
linklist.add(price2);
shares2--;
}
}
public double averageCost(int shares2) {
double average = 0;
int sizer = 0;
while(sizer < shares2) {
average = average + linklist.poll().doubleValue(); //this is where the problem lies
sizer++;
}
average = average/shares2;
return average;
}
}
Your mistake comes from the class declaration.
Formal parameter of generic may be T:
public class queue<T> {
Now you see that T has no method named doubleValue because you haven't constrained it.
The following do what you want:
import java.util.LinkedList;
public class queue<T extends Number> {
private final LinkedList<T> linklist;
private final int shares;
private final T price;
public queue( int shares2, T price2 ) {
linklist = new LinkedList<>();
shares = shares2;
price = price2;
bigAdd( shares, price );
}
public void add( T e ) {
linklist.add(e);
}
public T take() {
return linklist.poll();
}
public void bigAdd( int shares2, T price2 ) {
while(shares2>0) {
linklist.add(price2);
shares2--;
}
}
public double averageCost( int shares2 ) {
double average = 0;
int sizer = 0;
while( sizer < shares2 ) {
final T v = linklist.poll();
average = average + v.doubleValue();
sizer++;
}
average = average/shares2;
return average;
}
}
You can just use linklist.poll(). The Double will get unboxed to a double.

SumAggregation using generics types

I want to do a sum for all over a Collection of numbers. But I want to indicate the return number type. For example I want to do the sum of a double collection, but I want to get back an Integer.
I want to have something like this SumAggregator. Here is the code I develop, but I have a Cast problem.
public class SumAggregator<N1 extends Number, N2 extends Number> {
public SumAggregator() {
}
public N2 sum(Collection<? extends N1> list){
Double sum = 0;
for(Number n : list){
sum += n.doubleValue();
}
return (N2) sum;
}
}
If I want to do SumAggregator<Double, Double> I don't have any problem. But if I want to do SumAggregator<Double, Integer>, once I run I get the following exception:
java.lang.ClassCastException: java.lang.Double cannot be cast to java.lang.Integer
Any idea of how to solve this?
Not exactly what you wanted but you could do something like:
interface DoubleConverter<N extends Number) {
N2 convert(double d);
}
And add a constructor to your SumAggregator:
private final DoubleConverter<N2> converter;
public SumAggregator(DoubleConverter<N2> converter) {
this.converter = converter;
}
And your method would look like:
public N2 sum(Collection<? extends N1> list){
double sum = 0;
for(Number n : list){
sum += n.doubleValue();
}
return converter.convert(sum);
}
finally, you would create one with:
SumAggregator<Double, Integer> a = new SumAggregator<> (new DoubleConverter<Integer>() {
public Integer convert(double d) { return (int) d; }
});
Finally, you could add some helper methods in the DoubleConverter interface:
DoubleConverter<Integer> INTEGER = new DoubleConverter<Integer>() {
public Integer convert(double d) { return (int) d; }
}
so the calling code can use:
SumAggregator<Double, Integer> a = new SumAggregator<> (DoubleConverter.INTEGER);
This is the solution I choose:
public class SumAggregator<N1 extends Number, N2 extends Number> {
private final NumberConverter<N2> converter;
public SumAggregator(NumberConverter<N2> converter) {
this.converter = converter;
}
public N2 sum(Collection<? extends N1> list){
double sum = 0;
for(Number n : list){
sum += n.doubleValue();
}
return converter.convert(sum);
}
}
And then:
public interface NumberConverter<N2> {
N2 convert(Number d);
NumberConverter<Short> SHORT = new NumberConverter<Short>() {
public Short convert(Number d) {
return d.shortValue();
}
};
NumberConverter<Integer> INTEGER = new NumberConverter<Integer>() {
public Integer convert(Number d) {
return d.intValue();
}
};
NumberConverter<Double> DOUBLE = new NumberConverter<Double>() {
public Double convert(Number d) {
return d.doubleValue();
}
};
NumberConverter<Float> FLOAT = new NumberConverter<Float>() {
public Float convert(Number d) {
return d.floatValue();
}
};
NumberConverter<Long> LONG = new NumberConverter<Long>() {
public Long convert(Number d) {
return d.longValue();
}
};
}

JSpinner : how to display both numbers and text?

I would like to create a JSpinner which can take every possible Double value between a specified minimum and a specified maximum.
Also, the JSpinner should be able to display a text instead of a specific value. Let's say our JSpinner can take values from -1 to 10. I would like to display a text, e.g. "Auto", instead of -1 .
How to replace by
Here is the Model I wrote, but it seems not to be enough, because it says in JSpinner there is an error because the text is not a Double.
public class SpinnerSpecialModel
extends AbstractSpinnerModel implements SpinnerMinMaxModel {
public static final double DEFAULT_MINIMUM = 0.0;
public static final double DEFAULT_MAXIMUM = Double.POSITIVE_INFINITY;
public static final double DEFAULT_STEP = 1.0;
public static final double DEFAULT_VALUE = 1.0;
public static final double DEFAULT_SPECIAL_NUMBER = -1.0;
public static final String DEFAULT_SPECIAL_TEXT = "Auto";
private double maximum;
private double minimum;
private double stepSize;
private double currentNumber;
private double specialNumber;
private String specialText;
private Object m_Value;
public SpinnerSpecialModel(double max, double min, double step, double num,
double specialNum, String specialTxt) {
maximum = max;
minimum = min;
stepSize = step;
currentNumber = num;
specialNumber = specialNum;
specialText = specialTxt;
setAccurateValue(num);
}
public SpinnerSpecialModel(double specialNum, String specialTxt) {
this(DEFAULT_MAXIMUM, DEFAULT_MINIMUM,
DEFAULT_STEP, DEFAULT_VALUE, specialNum, specialTxt);
}
public SpinnerSpecialModel() {
this(DEFAULT_SPECIAL_NUMBER, DEFAULT_SPECIAL_TEXT);
}
#Override
public Object getValue() {
if (currentNumber == specialNumber) {
m_Value = specialText;
}
else {
m_Value = currentNumber;
}
return m_Value;
}
#Override
public void setValue(Object value) {
setAccurateValue(value);
}
private void setAccurateValue(Object value) {
if (value instanceof Double) {
double doubleValue = (Double) value;
if (doubleValue != currentNumber) {
if (doubleValue == specialNumber) {
currentNumber = specialNumber;
m_Value = specialText;
}
else if (doubleValue > maximum) {
currentNumber = maximum;
m_Value = maximum;
}
else if (doubleValue < minimum) {
currentNumber = maximum;
m_Value = minimum;
}
else {
currentNumber = doubleValue;
m_Value = doubleValue;
}
fireStateChanged();
}
}
if (value instanceof String) {
String stringValue = (String) value;
if (stringValue.equals(specialText)) {
this.currentNumber = specialNumber;
this.m_Value = specialText;
fireStateChanged();
}
}
}
#Override
public Object getNextValue() {
return getNewValue(+1);
}
#Override
public Object getPreviousValue() {
return getNewValue(-1);
}
/**
*
* #param direction
* #return
*/
private Object getNewValue(int direction) {
double newValue = currentNumber + direction * stepSize;
setAccurateValue(newValue);
return m_Value;
}
#Override
public double getMaximum() {
return maximum;
}
#Override
public double getMinimum() {
return minimum;
}
#Override
public double getStepSize() {
return stepSize;
}
#Override
public void setMaximum(double max) {
maximum = max;
}
#Override
public void setMinimum(double min) {
minimum = min;
}
#Override
public void setStepSize(double step) {
stepSize = step;
}
}
The best and proper way to do this is not as simple as just writing a model, but it is not very complicated. You actually need to write an Editor and a Formatter to have a true MVC spinner:
A class that extends JSpinner : SpecialValuesSpinner.
A class that implements SpinnerModel : SpecialValuesSpinnerModel
A class that extends DefaultEditor and implements DocumentListener : SpecialValuesSpinnerEditor
A class that extends NumberFormatter : SpecialValuesSpinnerFormatter
I am not going to show you the code for all classes, but here is basically what you have to do in each :
SpecialValuesSpinner :
public class SpecialValuesSpinner() extends SpinnerNumberModel {
// in your constructor do this
setModel(new SpecialValuesSpinnerModel(YOUR_SPECIAL_VALUES);
setEditor(new SpecialValuesSpinnerEditor());
}
SpecialValuesSpinnerModel :
public class SpinnerSpecialValuesModel() extends JSpinner {
// in this class you handle the fact that now, you have an
// interval of values and a list of special values that are allowed.
// here is what I did :
#Override
public Object getNextValue() {
return incrValue(+1);
}
#Override
public Object getPreviousValue() {
return incrValue(-1);
}
private Object incrValue(int dir) {
// NB : BigDecimal here because this is what I used,
// but use what you want in your model
BigDecimal result = null;
BigDecimal numberBD = new BigDecimal(getNumber().toString());
BigDecimal stepSizeBD = new BigDecimal(getStepSize().toString());
BigDecimal dirBD = new BigDecimal(dir);
BigDecimal nextValue = numberBD.add(stepSizeBD.multiply(dirBD));
TreeSet<BigDecimal> currentAllowedValues = new TreeSet<BigDecimal>();
currentAllowedValues.addAll(m_SpecialValues);
if (getMaximum() != null) {
currentAllowedValues.add((BigDecimal) getMaximum());
}
if (getMinimum() != null) {
currentAllowedValues.add((BigDecimal) getMinimum());
}
if (isIncludedInBounds(nextValue)) {
currentAllowedValues.add(nextValue);
}
if (dir > 0) {
try {
result = currentAllowedValues.higher(numberBD);
}
catch (NoSuchElementException e) {}
}
else if (dir < 0) {
try {
result = currentAllowedValues.lower(numberBD);
}
catch (NoSuchElementException e) {}
}
return result;
}
}
In SpecialValuesSpinnerEditor, we use Document Listener to have autocompletion (easy to do, just search on SO).
public class SpecialValuesSpinnerEditor extends DefaultEditor implements DocumentListener {
// You have to do in your contructor
SpecialValuesSpinnerFormatter formatter =
new SpecialValuesSpinnerFormatter (spinner.getSpecialValues(), format);
getTextField().setFormatterFactory(new DefaultFormatterFactory(formatter));
}
And now, the most important, the Formatter which does conversion between user input (string) and numbers, and handle the model's display :
public class SpecialValuesSpinnerFormatter extends NumberFormatter {
// Just override the methos StringToValue and ValueToString.
// You can check here if the value is special
// i.e you must display its special text instead. e.g. : "Auto" instead of -1
}
I think you can achieve that by implementing your own SpinnerModel and supplying that as argument to the JSpinner constructor.

de.congrace.exp4j fails on multiple arguments for a CustomFunction

i am trying to add a custom function that sums number to a ExpressionBuilder
This is the java code:
package com.sapiens.bdms.drools.exe.helper.FuncServiceTrial;
import com.sapiens.bdms.drools.exe.helper.Functions;
import de.congrace.exp4j.*;
import java.util.ArrayList;
import java.util.Collection;
public class FormulaInterpreter {
public double interpret(String formula) throws UnparsableExpressionException, UnknownFunctionException, InvalidCustomFunctionException {
Collection<CustomFunction> customFunctions = new ArrayList<CustomFunction>();
customFunctions.add(new CustomFunction("SUM") {
#Override
public double applyFunction(double[] doubles) {
Double res = 0.0;
for (double aDouble : doubles) {
res += aDouble;
}
return res;
}
});
Calculable calc = (Calculable) new ExpressionBuilder(formula).withCustomFunctions(customFunctions).build();
return calc.calculate();
}
public static void main(String[] args) throws UnknownFunctionException, UnparsableExpressionException, InvalidCustomFunctionException {
FormulaInterpreter formulaInterpreter = new FormulaInterpreter();
double res = formulaInterpreter.interpret("SUM(2,4,4)");
System.out.println(res);
}
}
but it prints out "2" instad of 10
Can you try this constructor telling exp4j how many arguments your function should have:
new CustomFunction("SUM",3)
as described in the API Docs: http://www.objecthunter.net/exp4j/apidocs/de/congrace/exp4j/CustomFunction.html
Here is a working JUnit test case:
#Test
public void testCustomFunction21() throws Exception {
CustomFunction sumFunc = new CustomFunction("SUM",3) {
#Override
public double applyFunction(double[] doubles) {
Double res = 0.0;
for (double aDouble : doubles) {
res += aDouble;
}
return res;
}
};
Calculable calc = (Calculable) new ExpressionBuilder("SUM(2,4,4)").withCustomFunction(sumFunc).build();
assertTrue(10d == calc.calculate());
}
Hope this helps,
Frank

Categories

Resources