Class.getMethod not working - java

So I had the following code below and called Operators Op = new Operators() elsewhere. However, I got an error in the getMethod call. I admit I'm not completely sure how to use it and got this result by reading other people's code, so any help would be great. Thanks.
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
public class Operators {
static Map<String, Method> METHODS = new HashMap<String, Method>();
String ADD = "+"; String MULTIPLY = "*"; String SUBTRACT = "-"; String DIVIDE = "/";
private static Class[] inputTypes = {Float.class, Float.class};
Operators() throws NoSuchMethodException, SecurityException {
METHODS.put(ADD, getMethod("add"));
METHODS.put(MULTIPLY, getMethod("multiply"));
METHODS.put(SUBTRACT, getMethod("subtract"));
METHODS.put(DIVIDE, getMethod("divide"));
}
static Method getMethod(String s) throws NoSuchMethodException {
return Operators.class.getMethod(s, inputTypes);
}
public static float add(float x, float y) {
return x+y;
}
public static float multiply(float x, float y) {
return x*y;
}
public static float subtract(float x, float y) {
return x-y;
}
public static float divide(float x, float y) {
return x/y;
}
}
Edit. The line referenced was return Operators.class.getMethod(s, inputTypes); inside the getMethod method.

It might give me a better idea of how to help you once I understand what on earth you are trying to do, but on first glance, this might be it:
the inputTypes-array houses two Float.class-es, but your methods use the primitive types. Float with a capital letter is different from float lowercase, hence I would expect a NoSuchMethodException.

you can also avoid to declare the input parameters type by changing the class as following and you can do it outside the constructor:
public class Operators {
static final String ADD = "+";
static final String MULTIPLY = "*";
static final String SUBTRACT = "-";
static final String DIVIDE = "/";
private static Method[] methods;
static Map<String, Method> methodsMap = new HashMap<String, Method>();
static {
methods = Operators.class.getMethods();
try {
methodsMap.put(ADD, getMethod("add"));
methodsMap.put(MULTIPLY, getMethod("multiply"));
methodsMap.put(SUBTRACT, getMethod("subtract"));
methodsMap.put(DIVIDE, getMethod("divide"));
} catch (NoSuchMethodException e) {
// handle error
e.printStackTrace();
}
}
static Method getMethod(String s) throws NoSuchMethodException {
for (Method method : methods) {
if (method.getName().equalsIgnoreCase(s))
return method;
}
throw new NoSuchMethodException(s);
}
public static float add(float x, float y) {
return x + y;
}
public static float multiply(float x, float y) {
return x * y;
}
public static float subtract(float x, float y) {
return x - y;
}
public static float divide(float x, float y) {
return x / y;
}
}
and you can use the methods map:
System.out.println(Operators.methodsMap.get("+").invoke(null, 1.0, 1.0));

Related

Map with custom key in Groovy vs Java

I want to use a map in Groovy where the keys will be instances of an unmutable class.
This is something I do often in Java and it works fine, like in this example class:
public class TestMap {
static final class Point {
final int x; final int y;
public Point(int x, int y) {this.x = x;this.y = y;}
}
public static void main(String[] args) {
Map<Point, String> map = new HashMap<>();
final Point origin = new Point(0, 0);
map.put(origin, "hello world !" );
if(!map.containsKey(origin))
throw new RuntimeException("can't find key origin in the map");
if(!map.containsKey(new Point(0,0))) {
throw new RuntimeException("can't find new key(0,0) in the map");
}
}
}
But when I try to achieve the same thing with Groovy, it doesn't work.
Why ?
Here is a sample non working example in Groovy:
class Point {
final int x; final int y
Point(int x, int y) { this.x = x; this.y = y }
public String toString() { return "{x=$x, y=$y}" }
}
def origin = new Point(0, 0)
def map = [(origin): "hello"]
map[(new Point(1,1))] = "world"
map.put(new Point(2,2), "!")
assert map.containsKey(origin) // this works: when it's the same ref
assert map.containsKey(new Point(0,0))
assert map.containsKey(new Point(1,1))
assert map.containsKey(new Point(2,2))
assert !map.containsKey(new Point(3,3))
You need to have an equals and hashCode method on your Point class so that the instances can be found as keys in the HashMap
You can do this quickly by adding an annotation in Groovy:
import groovy.transform.*
#EqualsAndHashCode
class Point {
final int x; final int y
Point(int x, int y) { this.x = x; this.y = y }
public String toString() { return "{x=$x, y=$y}" }
}

Java math error [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 7 years ago.
I'm working on a lab for programming principles II, and I have a class that makes a point, with methods for setting the point, and calculating the distance between other points. Calculating the distance worked fine when testing it with a runner for just the class, but when I make other classes that use it as an object, I'm getting an error with the distance formula.
import java.lang.Math;
public class MyPoint {
private double x;
private double y;
public MyPoint(double dubx, double duby)
{
x=dubx;
y=duby;
}
public void setX(double dub) {
x = dub;
}
public void setY(double dub) {
y = dub;
}
public double getX() {
return x;
}
public double getY()
{
return y;
}
public double distance (MyPoint otherPoint)
{
return Math.sqrt(Math.pow((otherPoint.getX()-getX()),2)+(Math.pow((otherPoint.getY()-getY()),2)));
}
public MyPoint midpoint(MyPoint otherPoint)
{
MyPoint point = new MyPoint((otherPoint.getX()+getX()/2),(otherPoint.getY()+getY())/2);
return point;
}
}
That's the class I'm getting the error on. The distance part is getting a null pointer exception.
Here's what I'm passing in:
import java.lang.Math;
public class MyTriangle
{
private MyPoint v1;
private MyPoint v2;
private MyPoint v3;
public MyPoint getPoint1()
{
return v1;
}
public MyPoint getPoint2()
{
return v2;
}
public MyPoint getPoint3()
{
return v3;
}
public void setPoint1(double x, double y)
{
v1= new MyPoint(x,y);
}
public void setPoint2(double x, double y)
{
v2 = new MyPoint(x,y);
}
public void setPoint3(double x, double y)
{
v2= new MyPoint(x,y);
}
public double getArea()
{
double a= v2.distance(v3);
double b= v1.distance(v3);
double c= v1.distance(v2);
double s= (a+b+c)/2;
return Math.sqrt(s*(s-a)*(s-b)*(s-c));
}
}
public class TestMyTriangle
{
public static void main(String [] args)
{
MyTriangle tr1 = new MyTriangle();
tr1.setPoint1(17,17);
tr1.setPoint2(5,30);
tr1.setPoint3(5,17);
System.out.println("Area:\t"+tr1.getArea());
}
}
And the error:
Exception in thread "main" java.lang.NullPointerException
at MyPoint.distance(MyPoint.java:34)
at MyTriangle.getArea(MyTriangle.java:37)
at TestMyTriangle.main(TestMyTriangle.java:9)
I can't seem to figure it out. Please help.
You get the Nullpointer because v3 is null:
fix with:
public void setPoint3(double x, double y)
{
v3= new MyPoint(x,y); // instead of v2
}
Another tipp: to calculate a square dont use Math.pow(x,2).
Altough it works.
The code is cleaner and faster if you use
x*x instead Math.pow(x,2);

Java OOP - Physics Engine type

I am trying to create a n-body simulator in Java while also learning OOP.
I want to have a file that contains all physical constants and physics formulas and I want to use these in other classes when calculating forces etc
Should this file be a regular class with all variables static, an interface or an abstract class, or something else? I am quite confused with all the definitions.
In your case I would create a class named Physics or something of that nature. Inside this class you can then accomplish all of the things you want to do by creating static methods and static variables, as JayC667 has pointed out. It should look something like this:
public class Physics {
public static final int GRAVITY_ACCELERATION = 9.58;
public static double formula(double x, double y) { ... }
// etc.
}
Then, to utilize this class from a different one, you simply reference the variables and use the methods like so:
System.out.println("Acceleration of Gravity = " + Physics.GRAVITY_ACCELERATION);
double speed = Physics.formula(23.5, 840);
You use interfaces to force classes (implementing those interfaces) to have defined methods (defined in the interface) you can can ensure basic functionality, while all the classes can be totally different in all other regards.
In an interface, you only define the method signature (return value, name, parameter types). These are purely abstract.
Since Java 8, interfaces can also contain default methods, that may contain code, but can be overridden by the implementing classes.
Best example is the Comparable interface. You can use that for Numbers, Strings, and any other classes that should be comparable (usually to their own class instances aka objects).
Abstract classes are a mixture of regular classes and interfaces. They contain code and member variables, but can also contain abstract methods. When a class extends an abstract base class, they need to implement the abstract methods at some point.
The normal classes do not have any abstract methods.
This is a question Java-developers usually fight over. General rules of thumb are the following:
If you use a static field, always make it final and never try to mutate it.
If you need a mutable field, create a non-static field.
If possible, initialise the field in the constructor and mark it final.
Methods are static only if they access no non-static fields (ie. they do not have a context), there is no need to abstract over them
(for example in a test case) and they are completely functional (this should
be implied by the fact that no static field is mutable). A good example is Math.sqrt(), where the square root operation does not have a context, does not mutate the state of your application and you never want to abstract over it. In all other cases use a non-static method. Some people completely avoid static methods.
Interfaces are most useful when your classes interact with one another. You can specify certain common functionalities available in a group of classes in your application. Then if some of your code requires these functionalities, you can use them without knowing the actual implementation. Say, you handle shapes in a method and want to know the area of a shape. You may have many shapes and you can retrieve the area without knowing the exact type (circle, triangle etc.).
In general, try not to overuse inheritance. Follow the substitution principle: only use inheritance if the superclass could always be substituted by the subclass.
For example: in OOP a square with variable slides is not a rectangle with variable slides, because for rectangles you are allowed to call setSide(20, 30), while for squares you are not (the two sides must match). Note: if you use final fields which are initialized in the constructor, as suggested earlier, this problem is automatically solved and you are free to inherit square from rectangle.
In your case, I would create utility classes with static methods/fields for common functionalities that do not have a context, such as calculating a formula with given input parameters. The actual bodies could be objects with common interface or abstract parent class.
This is some simple example of how you could do it.
Please ignore the aerial resistance part, didn't really think about that, some movements may be funny :-)
import java.util.ArrayList;
/**
* Contains constants and convenience methods
* #author JayC667
*/
class Globals {
static public final float GRAVITY_ACC = -9.81f; // meters per secondĀ²
static public float getTotalSpeed(final float pSpeedX, final float pSpeedY) {
return (float) Math.sqrt(Math.pow(pSpeedX, 2) + Math.pow(pSpeedY, 2));
}
static public float getDistanceBetweenObjects(final PhysicalObjectInterface pObj1, final PhysicalObjectInterface pObj2) {
final float distX = pObj2.getPosX() - pObj1.getPosX();
final float distY = pObj2.getPosY() - pObj1.getPosY();
return getTotalSpeed(distX, distY); // coincidentally same as average speed :-)
}
static public String toString(final PhysicalObjectInterface pObject) {
return pObject.getClass().getSimpleName() + "\tX=" + pObject.getPosX() + "\tY=" + pObject.getPosY();
}
}
interface PhysicalObjectInterface {
default boolean collidesWith(final PhysicalObjectInterface pOther) {
final float distance = Globals.getDistanceBetweenObjects(this, pOther);
return distance < getRadius() + pOther.getRadius();
}
float getPosX();
float getPosY();
float getSpeedX();
float getSpeedY();
float getMass();
float getRadius();
float getAerialResistanceCofactor();
void calcNextCycle();
}
/**
* Does most of the simple work
* #author JayC667
*/
abstract class PhysicalObjectABC implements PhysicalObjectInterface {
private float mPosX;
private float mPosY;
private float mSpeedX;
private float mSpeedY;
public PhysicalObjectABC(final float pPosX, final float pPosY, final float pSpeedX, final float pSpeedY) {
mPosX = pPosX;
mPosY = pPosY;
mSpeedX = pSpeedX;
mSpeedY = pSpeedY;
}
#Override public float getPosX() {
return mPosX;
}
#Override public float getPosY() {
return mPosY;
}
#Override public float getSpeedX() {
return mSpeedX;
}
#Override public float getSpeedY() {
return mSpeedY;
}
#Override public abstract float getMass();
#Override public abstract float getAerialResistanceCofactor(); // could also derive this from radius
// getRadius is not repeated here, but still is abstract and has to be defined in the implementing subclass
#Override public void calcNextCycle() {
final float gravForceY = getMass() * Globals.GRAVITY_ACC; // F = m * a
final float aerialResistForceX = -Math.signum(mSpeedX) * (float) (Math.pow(mSpeedX, 2) * getAerialResistanceCofactor());
final float aerialResistForceY = -Math.signum(mSpeedY) * (float) (Math.pow(mSpeedY, 2) * getAerialResistanceCofactor());
final float totalForceX = aerialResistForceX;
final float totalForceY = gravForceY + aerialResistForceY;
final float accX = totalForceX / getMass(); // a= F / m;
final float accY = totalForceY / getMass(); // a= F / m;
mSpeedX += accX;
mSpeedY += accY;
mPosX += mSpeedX;
mPosY += mSpeedY;
}
#Override public String toString() {
return Globals.toString(this);
}
}
class Stone extends PhysicalObjectABC {
public Stone(final float pPosX, final float pPosY) {
super(pPosX, pPosY, 0, 0);
}
#Override public float getRadius() {
return 0.1f;
}
#Override public float getMass() {
return 1;
}
#Override public float getAerialResistanceCofactor() {
return 0.2f;
}
}
class Leaf extends PhysicalObjectABC {
public Leaf(final float pPosX, final float pPosY) {
super(pPosX, pPosY, 0, 0);
}
#Override public float getRadius() {
return 0.1f;
}
#Override public float getMass() {
return 0.003f;
}
#Override public float getAerialResistanceCofactor() {
return 0.95f;
}
}
class StaticObject implements PhysicalObjectInterface {
private final int mPosX;
private final int mPosY;
private final int mRadius;
public StaticObject(final int pPosX, final int pPosY, final int pRadius) {
mPosX = pPosX;
mPosY = pPosY;
mRadius = pRadius;
}
#Override public float getPosX() {
return mPosX;
}
#Override public float getPosY() {
return mPosY;
}
#Override public float getSpeedX() {
return 0;
}
#Override public float getSpeedY() {
return 0;
}
#Override public float getMass() {
return 0;
}
#Override public float getRadius() {
return mRadius;
}
#Override public float getAerialResistanceCofactor() {
return 0;
}
#Override public void calcNextCycle() { /* ignore, does not move */}
#Override public String toString() {
return Globals.toString(this);
}
}
public class PhysicsEngine {
static private ArrayList<PhysicalObjectInterface> sObjects = new ArrayList<>();
public static void main(final String[] args) {
sObjects.add(new Leaf(10, 100));
sObjects.add(new Stone(20, 100));
sObjects.add(new Leaf(30, 100));
sObjects.add(new Stone(40, 100));
sObjects.add(new StaticObject(30, 100, 1)); // lantern
sObjects.add(new StaticObject(40, 100, 5)); // tree
for (int cycle = 0; cycle < 1000; cycle++) {
simulateCycle(cycle);
printData(cycle);
checkCollisions(cycle);
try {
Thread.sleep(1000);
} catch (final InterruptedException e) { /* ignore */}
}
}
private static void simulateCycle(final int pCycle) {
System.out.println("Simulating cycle #" + pCycle);
for (final PhysicalObjectInterface o : sObjects) {
o.calcNextCycle();
}
}
private static void printData(final int pCycle) {
System.out.println("Printing cycle #" + pCycle);
for (final PhysicalObjectInterface o : sObjects) {
System.out.println("\t" + o);
}
}
private static void checkCollisions(final int pCycle) {
System.out.println("Checking for collisions in cycle #" + pCycle);
final ArrayList<PhysicalObjectInterface> destroyedItems = new ArrayList<>();
for (final PhysicalObjectInterface o1 : sObjects) {
for (final PhysicalObjectInterface o2 : sObjects) {
if (o1 == o2) continue; // ignore IDENTICAL, not equal, items
if (o1.collidesWith(o2)) {
System.out.println("CRASH!\n\tObject 1 (" + o1 + ") \ncollides with \n\tObject 2 (" + o2 + ")");
destroyedItems.add(o1);
destroyedItems.add(o2);
}
}
}
sObjects.removeAll(destroyedItems); // can't delete within loop, would invalidate iterators or migh also f*** up loop indices
}
}

aggregation in Java and methods in main method

I have such code which works well, but I wonder why method area is not possible to put in the main method
public class Circle {
Operation op;
double pi = 3.14;
double area(int radius) {
op = new Operation();
int rsquare = op.square(radius);
return rsquare * pi;
}
public static void main(String arg[]) {
Circle c = new Circle();
double s = c.area(5);
System.out.println(s);
}
class Operation {
int square(int n) {
return n * n;
}
}
}
Example which doesn't work:
public static void main(String arg[]) {
double area ( int radius){
op = new Operation();
int rsquare = op.square(radius);
return rsquare * pi;
}
The only way to nest method implementation code inside Java methods is with anonymous classes. In your case this would look like this (code has to be nested inside a class of sorts):
public static interface Circle {
double area(int radius);
}
public static interface Operation {
int square(int n);
}
public static void main(String arg[]) {
Circle c = new Circle() {
Operation op;
double pi = 3.14;
public double area(int radius) {
op = new Operation() {
public int square(int n) {
return n * n;
}
};
int rsquare = op.square(radius);
return rsquare * pi;
}
};
double s = c.area(5);
System.out.println(s);
}
Take
double area(){...}
Outside of the main method
Java doesn't support nested methods, even if it did, there would be no point to put a nonstatic method in a static method
The closest thing would be nested classes that contain methods, declared in the method

Accessing values of a given object

I am wondering why i have to deal with two types of arguments;that of a constructor and that of a method.For instance i have this simple class that adds two numbers
class Calc{
private int x = 6;
private int y;
private char z = 'z';
public int getx(){
return x;
}
public char selfrecur(){
return this.z;
}
public int add(int one,int two){
return one + two;
}
public static void main(String[] args) {
Calc gx = new Calc();
System.out.println(gx.x);
System.out.println(gx.add(44,3));
System.out.println(gx.selfrecur());
}
}
That works,and wow,wasn't that great.Now,i have this idea of having the constructor provide the arguments and the function's work will be to do the heavy computations.For instance in my class Kalc
class Kalc{
//** This example won't work **
private int x;
private int y;
private int z;
public Kalc(int v1,int v2,int v3){
this.x = v1;
this.y = v2;
this.z = v3;
}
public int add(){
return newObject.x + newObject.y + newObject.z;
//Gets the values of a new object and add them up
}
public int multiply(){
return newObject.x * newObject.y * newObject.z;
//Gets the values of a new object and multiply them
}
public static void main(String[] args) {
Kalc k = new Kalc(4,5,6);
System.out.println(k.add());
System.out.println(k.multiply());
}
}
I have been looking here http://docs.oracle.com/javase/6/docs/api/java/lang/Class.html for clues but so far nothing.Is this even possible?.
Edit
class Kalc{
private int x;
private int y;
private int z;
public Kalc(int v1,int v2,int v3){
this.x = v1;
this.y = v2;
this.z = v3;
}
public int add(){
return this.x + this.y + this.z;
}
public static void main(String[] args) {
Kalc k = new Kalc(4,5,6);
System.out.println(k.add);
}
}
Error
C:\ja>javac Kalc.java
Kalc.java:17: error: cannot find symbol
System.out.println(k.add);
^
symbol: variable add
location: variable k of type Kalc
1 error
C:\ja>
Use this key word:
public int add(){
return this.x + this.y + this.z;
}
You can use this key word inside non-static methods too.
About your edit:
add is a function (and not a member) of class Kalc so you can call it as a function only:
System.out.println(k.add());
You can do the below
class Kalc{
private int x;
private int y;
private int z;
public Kalc(int v1,int v2,int v3)
{
this.x = v1;
this.y = v2;
this.z = v3;
}
public int add(){
return x+y+z;
}
public int multiply(){
return x*y*z;
}
public static void main(String[] args) {
Kalc k = new Kalc(4,5,6);
System.out.println(k.add());
System.out.println(k.multiply());
}
}
What is newObject?
You have instantiated an object with prescribed values. If you want to add them with an instance method, try this
return this.x + this.y + this.z;
I think you need to print :
System.out.println(k.add());
Instead of :
System.out.println(k.add);
as in the second case the compiler show k.add as add variable
but in the first case add() the compiler show add() as a function which you define in Kalc Class

Categories

Resources