So I have been pulling my hair out trying to understand how to call methods on objects in an array. The gist of this homework is to create a comparable interface from scratch, an abstract class called "Weapon", an interface called "Drawable", a couple classes that extend Weapon, and a "Spaceship" class that creates a spaceship with an array of weapon objects.
The following is the code for the "Spaceship" class. The error "not a statement" occures at line 40. The intended purpose of the fireFastestWeapon method is to sort the object array based on each objects fire time, and then activate the fire method for the first n weapons.
public class Spaceship implements Drawable
{
private Weapon [] mountedWeapons = new weapon[4];
private int curWeapon = 0;
public void draw()
{
System.out.print("Ship will be drawn here");
}
public void addWeapon(Weapon w)
{
if (curWeapon<mountedWeapons.length)
{
mountedWeapons [curWeapon] = w;
curWeapon++;
}
else System.out.print("The weapons bay is full Commander");
}
public void fireFastestWeapon(int n)
{
int count=mountedWeapons.length;
int k;
for (int m = count; m>=0;m--)
{
for(int i = 0; i<count-1;i++)
{
k=i+1;
if (mountedWeapons[i].compareTo(mountedWeapons[k]) == 1){
Weapon temp;
temp = mountedWeapons[i];
mountedWeapons[i] = mountedWeapons[k];
mountedWeapons[k] = temp;
}
}
}
if(n>mountedWeapons.length)
{
n=mountedWeapons.length;
}
for (f=0;f<n-1;n++)
{
mountedWeapon[f].fire;
}
}
}
Thank you for looking!
The parentheses on a method call are not optional in Java:
mountedWeapon[f].fire();
Related
Cheers, I am pretty new to java and I and I have ran across a problem
I have three classes, all inheriting things between them. Starting I have a class A:
public class A{
private int index;
public A(int index) {
System.out.println("Creating an instance of A");
this.index = index;
}
}
then I have a sublass of A, class M which has a enum inside as:
public class M extends A{
public enum Letter {
A,B,C;
}
private Letter letter;
public M(int index, Letter aLetter) {
super(index);
System.out.println("Creating an instance of M");
this.letter = aLetter;
}
}
and finally a last class P , subclass of M:
public class P extends M {
private T t;
public enum T{
o,
a,
t
}
public P(int index, Letter aLetter, T aT) {
super(index,aLetter);
System.out.println("Creating an instance of P");
this.t = aT;
}
}
What I want to do is create e.g. 3 objects of the class P, and pass on to them RANDOMLY a value of each of these enums. I thought of creating a function in the main class which would be kind of like:
Letter getRandLetter() {
Random rand = new Rand();
int pick = rand.nextInt(M.Letter.values().length);
if (pick == 0) {
return Letter.A;
} else if (pick == 1) {
return Letter.B;
} else {
return Letter.C;
}
}
my main looks like this:
int N = 3;
M[] new_m = new M[N]
for(int i = 0; i < N; i++) {
new_m[i] = new P(i, getRandLetter(), getRandT());
}
however I get this error: Cannot make a static reference to the non-static method . What Can I do to achieve what I want?
The error is telling what to do:
Cannot make a static reference to the non-static method
Your main method is static, and the methods called from it should be static as well. So your getRandLetter() and getRandT() methods should be static.
getRandLetter() should look like this:
static Letter getRandLetter() {
Random rand = new Rand();
int pick = rand.nextInt(M.Letter.values().length);
if (pick == 0) {
return Letter.A;
} else if (pick == 1) {
return Letter.B;
} else {
return Letter.C;
}
}
And getRandT() should be static as well.
The question is to create objects of both sub classes and store them in an array .
So I create a abstract Super class and made a method area abstract after that I created the two sub classes and implemented that method on the main method I declared array and given the values this is it. I am new here so sorry if I'm asking it in wrong way.
And yes the output should be the area and types of two figure.
package Geometric;
public abstract class GeometricFigure {
int height;
int width;
String type;
int area;
public GeometricFigure(int height, int width) {
//super();
this.height = height;
this.width = width;
}
public abstract int area();
}
package Geometric;
public class Square extends GeometricFigure {
public Square(int height, int width) {
super(height,width);
}
public int area(){
return height * width;
}
}
package Geometric;
public class Triangle extends GeometricFigure {
public Triangle(int height, int width) {
super(height ,width);
}
public int area() {
return (height*width)/2;
}
}
package Geometric;
public class UseGeometric {
public static void main(String args[]) {
GeometricFigure[] usegeometric = { new Square(12, 15), new Triangle(21, 18) };
for (int i = 0; i < usegeometric.length; i++) {
System.out.println(usegeometric[i]);
usegeometric[i].area();
System.out.println();
}
}
}
You already are storing both elements in an array, I think your question is more related to this part:
usegeometric[i].area();
System.out.println();
You get the area of both elements, but you don't assign it to a variable, and you don't do anything with it. Change those lines of code to this:
System.out.println("Area: " + usegeometric[i].area());
EDIT:
Geometric.Square#19dfb72a Geometric.Triangle#17f6480
This is the kind of output you can expect because you didn't overwrite the toString method in your classes.
If you don't, it will take the inherited version of Object, which prints this information
--
In your Square class, add this:
public String toString() {
return "Square - area = " + area();
}
or something similar, depending on what you want to be printed. (And a similar adjustment to your Triangle class).
At this time, you are printing Object's version of toString, since you didn't provide a new one. By overwriting that method, you should get the output you want after turning your loop into:
for (int i = 0; i < usegeometric.length; i++) {
System.out.println(usegeometric[i]);
}
What println actually does, is not print the object itself, but a String representation of the object, which is provided by the toString method.
public class UseGeometric {
public static void main(String[] args) {
// TODO Auto-generated method stub
GeometricFigure[] usegeometric = { new Square(12, 15), new Triangle(21, 18) };
for (int i = 0; i < usegeometric.length; i++) {
System.out.println("Area is: " + usegeometric[i].area());
}
} }
Say I have a object class as follows:
public class MyObject() {
// ...
public double distanceTo(MyObject other) {
// **edit: check if desired distance is contained in distanceMatrix**
// **of the collection in which this object is contained**
// **if not:** some time-consuming calculation
}
}
I also have a custom collection that contains such objects:
public class MyObjectCollection() {
private List<MyObject> objects;
private double[][] distanceMatrix;
// ...
public void add(MyObject obj) {
this.objects.add(obj);
}
public void calcDistanceMatrix() {
for (int i = 0; i < objects.size(); i++) {
for (int j = 0; j < objects.size(); j++) {
this.distanceMatrix[i][j] = objects.get(i).distanceTo(objects.get(j));
}
}
}
}
So the idea is to calculate all the distances between all MyObject's only once and to store them in a matrix. Now when someone calls distanceToon a MyObject, it should use the cached value instead of calculating it again.
However, for this to work, each MyObject must know the collection in which it is contained - or does it? I want to avoid this due to separation.
(I know that I could store all the distances from a MyObject obj1 to other MyObject's as a field in obj1, but I do not want to do this either. For example, this would mean rebuilding the MyObjectCollection structure (which I need anyway for other reasons) for each MyObject.)
I think you need to do 2 things in order to separate time consuming calcultion and dependency from collection:
1) On the MyObject separate the logic that gets cached distance and the that does actual calculation into different methods.
2) Move the logic that gets distance between two object into an interface following Strategy pattern:
Here is the modified code showing it:
public interface DistanceCalc{
public double distanceTo(MyObject from, MyObject to);
}
public class MyObject{
private DistanceCalc distanceCalc = null;
public void setDistanceCalc(DistanceCalc distanceCalc) {
this.distanceCalc = distanceCalc;
}
public double distanceTo(MyObject other) {
return distanceCalc.distanceTo(this, other);
}
public double calculateDistance(MyObject to) {
return 5.0; //this is where time consuming calculation happens
}
}
public class MyObjectCollection implements DistanceCalc{
private List<MyObject> objects;
private double[][] distanceMatrix;
public void add(MyObject obj) {
this.objects.add(obj);
obj.setDistanceCalc(this);
}
#Override
public double distanceTo(MyObject from, MyObject to) {
if (distanceMatrix == null) calcDistanceMatrix();
return distanceMatrix[ objects.indexOf(from) ][ objects.indexOf(to) ];
}
public void calcDistanceMatrix() {
for (int i = 0; i < objects.size(); i++) {
for (int j = 0; j < objects.size(); j++) {
this.distanceMatrix[i][j] = objects.get(i).calculateDistance( objects.get(j) );
}
}
}
}
Ok, I have an object with multiple instance variables that I would like to sort by, so I read that i have to implement a comparator class and use it.
Basically its a plane class with PlaneSeats object as its member.
PlaneSeats has SeatID, CustomerID
I wish to print the occupied seats by CustomerIDs, does anyone know how?
//This Prints it by SeatID (Since it starts from 0)
for (int i = 0; i < seat.length; i++) {
if (seat[i].isOccupied()) {
System.out.println("SeatID " + seat[i].getSeatID() + " assigned to CustomerID " + seat[i].getCustomerID());
}
}
my failed Comparator code is as follows: I hope to NOT use a seperate class though, hopefully so sort of array.sort function?
import java.util.*;
public class Comparator implements Comparator<Plane> {
public int compare(Plane CustomerID[], Plane CustomerID[]) {
}
}
Arrays.sort(CustomerID, new Comparator<Plane>() {
public int compare(Plane p1, Plane p2) {
PlaneSeat ps1 = p1.getPlaneSeat();
PlaneSeat ps2 = p2.getPlaneSeat();
return ps1.getSeatID().compareTo(ps2.getSeatID());
}
});
This will sort on basis of SeatId. If you want to sort on basis of CustomerId, replace getSeatID() with getCustomerID().
This won't compile
public class Comparator implements Comparator<Plane> {
public int compare(Plane CustomerID[], Plane CustomerID[]) {
}
}
You are breaking the contract.
See this code for a possible solution.
PlaneSeat class definition
public class PlaneSeat {
//Create your custom comparator strategy
public static final Comparator<PlaneSeat> CUSTOMER_COMPARATOR = new CustomerComparator();
//fields
private final Integer customerID;
public PlaneSeat(Integer customerID){
this.customerID= customerID;
}
private static class CustomerComparator implements Comparator<PlaneSeat>{
#Override
public int compare(PlaneSeat o1, PlaneSeat o2) {
return o1.customerID.compareTo(o2.customerID);
}
}
#Override
public String toString() {
return "PlaneSeat [customerID=" + customerID + "]";
}
}
Plane class
public class Plane{
private List<PlaneSeat> seats;
public List<PlaneSeat> getSeats() {
return seats;
}
public void setSeats(List<PlaneSeat> seats) {
this.seats = seats;
}
public void sortSeatsByCustomer(){
Collections.sort(seats,PlaneSeat.CUSTOMER_COMPARATOR);
}
#Override
public String toString() {
return "Plane [seats=" + seats + "]";
}
}
Then in your client code:
public static void main(String args []){
List<PlaneSeat> seats = new ArrayList<>();
for(int i =10;i>0;i--)
seats.add(new PlaneSeat(i--));
Plane plane = new Plane();
plane.setSeats(seats);
System.out.println(plane);//print before sorting
plane.sortByCustomers();
System.out.println(plane);//after sorting by customer
}
You shouldn't name your class "Comparator", since that's already a Java interface name.
Plane CustomerID[]
This does not make sense.
Didn't I answer your prior question about seats?
Your PlaneSeat class should implement Comparable<PlaneSeat> and a method named
public int compareTo(PlaneSeat seat)
In this method, seat is the second seat, the object you're comparing with. The other object is
this
In this method, you can call the
getCustomerID()
method on the objects. It should look like:
public int compareTo(PlaneSeat seat) {
if (this.getCustomerID() > seat.getCustomerID()) return 1;
if (this.getCustomerID() < seat.getCustomerID()) return -1;
return 0;
}
If this gives you the reverse order of what you wanted, swap 1 and -1.
Before your comment
//This Prints it by SeatID (Since it starts from 0)
call
seat = Arrays.sort(seat);
to sort the seats.
You can't implement Comparator class again, it's defined as an interface and you have to implement it by naming a different class.
This feels like a very obvious question but I can't figure out how to do it. I have a class called Hive and I want to add a hive object to my Garden class using an addHive method. I know it is going to be something very simple but I can't figure it out =/
My Garden class:
import java.util.ArrayList;
import java.util.Random;
public class Garden {
ArrayList<Flower> flowerbed = new ArrayList<Flower>();
Hive hive = null;
public void anotherDay(){
int size = flowerbed.size();
for(int i = 0; i < size; i++) {
Flower flower = flowerbed.get(i);
flower.grow();
}
}
public void addHive(Hive hive){
}
public void addFlower(Flower flower){
flowerbed.add(flower);
}
public Flower getFlower(int fi){
if(fi < flowerbed.size()){
return flowerbed.get(fi);
}else{
return null;
}
}
public Integer getRandomInteger(Integer max)
{
Random rand = new Random();
int number;
number = rand.nextInt(max) + 1;
return new Integer(number);
}
public Flower findFlower(){
return getFlower(getRandomInteger(flowerbed.size()));
}
public int size(){
return flowerbed.size();
}
}
I have also used what I feel is a rather untidy roundabout method for getting a random flower from my arraylist of flowers- can anyone suggest a better method or is this as good as it gets?
if you need only one hive, use:
public void setHive(Hive hive){
this.hive = hive;
}
If you need multiple hive, do exact the same as with flower. Including creating the list.
ArrayList<Hive> hives = new ArrayList<Hive>();
public void addHive(Hive hive){
hives.add(hive);
}