Equivalent function to .push() in java? - java

I'm trying to have a dynamic array with objects inside. I need a function that is equivalent to the .push() function in Javascript but in Java. The errors occur in the pipe.push(new Pipe()) inside of the setup function.
Bird bird;
Pipe[] pipe;
boolean keyDown = false;
void setup() {
size(800, 800);
frameRate(60);
bird = new Bird();
pipe.push(new Pipe());
}
//------------------------------------------------------------
void draw() {
background(0);
bird.gravity();
bird.show();
bird.edge();
}
//-----------------------------------------------------------
void keyPressed(KeyEvent e) {
if(e.getKeyCode() == 32) {
if(keyDown == false) {
bird.jump();
keyDown = true;
}
}
}
void keyReleased() {
keyDown = false;
}
//-----------------------------------------------------------------

Arrays in Java arrays are fixed size. you have to specify the size and then cant expand them. Unfortunate to change the size you need to declare new array.
But fortunately Java provides different data structures e.g. list, set which can grow dynamically as size of increases.
eg
ArrayList<Pipe> pipes = new ArrayList();
pipes.add(new Pipe());
pipes.add(new Pipe());
for(Pipe pipe : pipes){
pipe.update();
}

Here:
pipe.push(new Pipe());
simply isnt possible in Java. In Java, an array has a fixed size. You can't dynamically add/remove slots.
If you need that, you can use List/AbstractList for example.
Beyond that, the real answer here is: don't start by assuming that Java has anything to do with JavaScript. So, when you think "let's use arrays in Java", then start by researching how Java treats arrays. Don't assume that anything there is like in JavaScript.

Related

How do I write this code without using Lambda and still have it work? [duplicate]

This question already has an answer here:
How do I transform this code into something simpler that I am more familiar with? [closed]
(1 answer)
Closed 2 years ago.
I'm trying to transform this code to work without using lambdas so that I can better understand it, but I am having no luck at all. How can I write it with ActionEvents similar to buttons?
enemyBoard = new Board(true, event -> {
if (!running)
return;
Cell cell = (Cell) event.getSource();
if (cell.wasShot)
return;
enemyTurn = !cell.shoot();
if (enemyBoard.ships == 0) {
System.out.println("YOU WIN");
System.exit(0);
}
if (enemyTurn)
enemyMove();
});
Here is the Board constructor:
public Board(boolean enemy, EventHandler<? super MouseEvent> handler) {
this.enemy = enemy;
for (int y = 0; y < 10; y++) {
HBox row = new HBox();
for (int x = 0; x < 10; x++) {
Cell c = new Cell(x, y, this);
c.setOnMouseClicked(handler);
row.getChildren().add(c);
}
rows.getChildren().add(row);
}
getChildren().add(rows);
}
The code belongs to a battleship game, and here is the link to the game code: https://github.com/AlmasB/Battleship/tree/master/src/com/almasb/battleship.
enemyBoard = new Board(true, event -> {
...
});
A lambda is a shorthand way of implementing a functional interface, which is an interface with a single (non-default) method. The equivalent code without a lambda is:
enemyBoard = new Board(true, new EventHandler<MouseEvent>() {
public void handle(MouseEvent event) {
...
}
});
That's it. It's just syntactic sugar† for instantiating an anonymous EventHandler and implementing its single handle() method.
I've elided the method body because it's the same in both.
If that still looks weird, writing new ClassOrInterface() { ... } is itself also a form of syntactic sugar. We could apply another round of de-sugaring and write out the anonymous class explicitly:
class EventHandler$1 implements EventHandler<MouseEvent> {
public void handle(MouseEvent event) {
...
}
}
enemyBoard = new Board(true, new EventHandler$1());
Note that EventHandler$1 is an auto-generated class name that is guaranteed not to clash with any other real classes. The compiler uses a $ character, which isn't legal in end user code, to name the class such that it couldn't possible conflict. If you've ever seen class names with dollar signs in your stack traces, this is where they come from: anonymous classes.
† As #user points out, it's actually more complicated under the covers. Lambdas don't always de-sugar to an anonymous class. Often the compiler can do something a little more efficient. But conceptually, thinking of them as anonymous classes is a good way to mentally translate them.

Java ArrayList trying to check if object with this name exists

I'm having a bit of trouble in my head trying to solve this:
I'm working on a "rankList", an arrayList made of "Score". Score it's the object that has the following atributes: name,wins,loses,draws. My class Ranking has an ArrayList of Score objects. To create a new Score object I just use the name (and set the rest to 0 since it's new). However I'm trying to check if the player's name it's already in rankList I don't have to create new but sum a win or lose or draw.
I have been reading arround that I have to override equals then others say I have to override contains... It's getting a big mess in my head. My fastest solution would be to write an "for" that goes arround the arrayList and use the getName().equals("name"); however this is getting too messi in my code. I have checkPlayer (if the palyer is in the list):
public boolean checkPlayer(String playerName) {
for (int i = 0; i < this.rankList.size(); i++) {
if (this.rankList.get(i).getName().equals(playerName)) {
return true;
}
}
return false;
}
then if I want to incrase the wins i have this :
public void incraseWins(String playerName) {
if (checkPlayer(playerName)) {
for (int i = 0; i < this.rankList.size(); i++) {
if (this.rankList.get(i).getName().equals(playerName)) {
this.rankList.get(i).setWins(this.rankList.get(i).getWins() + 1);
break;
}
}
} else {
createPlayer(playerName);
//more for to get to the player i'm looking for...
for (int i = 0; i < this.rankList.size(); i++) {
if (this.rankList.get(i).getName().equals(playerName)) {
this.rankList.get(i).setWins(this.rankList.get(i).getWins() + 1);
break;
}
}
}
So i guess there is a better way to do this... :/
ArrayList is not the right data structure here. To check if an element exists in the array you are searching the entire arraylist. Which means it's O(N).
To keep an array list is sorted order and do a binary search on it would definitely be faster as suggested in the comments. But that wouldn't solve all your problems either because insert into the middle would be slow. Please see this Q&A: When to use LinkedList over ArrayList?
One suggestion is to use a Map. You would then be storing player name, player object pairs. This would give you very quick look ups. Worst case is O(log N) i believe.
It's also worth mentioning that you would probably need to make a permanent record of these scores eventually. If so an indexed RDBMS would give you much better performance and make your code a lot simpler.
Try using a hashtable with a key, it would be much more efficient!
e..Why not using map<>.
a binary search is good idea if you must use List,code like this
List<Method> a= new ArrayList<>();
//some method data add...
int index = Collections.binarySearch(a, m);
Method f = a.get(index);
and class method is impl of Comparable,then override compareTo() method
public class Method implements Comparable<Method>{
........
#Override
public int compareTo(Method o) {
return this.methodName.compareTo(o.getMethodName());
}
if you don't want use binsearch,CollectionUtils in commons can help you
CollectionUtils.find(a, new Predicate() {
#Override
public boolean evaluate(Object object) {
return ((Method)object).getMethodName().equals("aaa");
}
});
in fact CollectionUtils.find is also a 'for'
for (Iterator iter = collection.iterator(); iter.hasNext();) {
Object item = iter.next();
if (predicate.evaluate(item)) {
return item;
}
}

Copying Array from ArrayList Element

I'm building a Java based game in Swing, which is essentially a grid of Jbuttons
I have an Object called Cell, which is a custom JButton with additional parameters for storing objects. The game grid is represented by Cell[][]
I have an arraylist of type Cell[][] to allow me to store the state of the gamegrid after each move. If I want to undo the move, I need to copy the last element of the ArrayList to the game grid to allow it to be displayed on the UI.
My gamegrid is panelHolder and my arraylist is moveHolder.
So far I've tried Collections.copy(panelHolder, moveHolder.get(moveHolder.size())); which will not compile due to the "arguments not being applicable for the type Cell[][]"
I've also tried System.arraycopy(moveHolder.get(moveHolder.size()-1), 0, panelHolder, 0, panelHolder.length);, which throws and out of bounds exception. Initially I thought this was due to the moveHolder.size()-1, but even just as moveHolder.size() it has the same problem.
I've found numerous questions on StackOverflow and others that both show these two ways of doing it, but I can't seem to get it to work. Is there something more obvious I'm missing? Full class method below:
public class UndoClass implements MoveCommand{
public ArrayList<Cell[][]> moveHolder = new ArrayList<Cell[][]>();
public Cell[][] execute(Cell[][] panelHolder) {
if (moveHolder.size() > 0){
Collections.copy(panelHolder, moveHolder.get(moveHolder.size()));
if (moveHolder.size() > 0){
moveHolder.remove(moveHolder.size());
}
}
System.out.println("Move Undone. Undos available:" + moveHolder.size());
return panelHolder;
}
public void addMove(Cell[][] panelHolder){
moveHolder.add(panelHolder);
}
public ArrayList<Cell[][]> getMoves(){
return moveHolder;
}
}
Cell Class
public class Cell extends JButton {
int co_x = 0;
int co_y = 0;
ArrayList<Players> current = new ArrayList <Players>();
}
Just wanted to point our your execute(...) method accepts the Cell[][] both as a parameter and the return argument. That approach is going to force all of your commands to keep copying your input param arrays to the return statement array. Notice if you don't need to keep the two in sync and you just use the return arg, you don't have to worry about copying at all:
Cell[][] lastState = moveHolder.get(moveHolder.size()-1);
moveHolder.remove(moveHolder.size()-1);
return lastState; // Not updating the panelHolder array, just returning
But of course now the input parm and return are out of sync. Instead you might want to encapsulate that state into a single object to make your life easier. Something like this (note that the execute now returns a void):
public ArrayList<GameState> previousStates = new ArrayList<GameState>();
public void execute(GameState currentState) {
if (previousStates .size() > 0) {
GameState lastState = previousStates.get(previousStates.size()-1);
currentState.restoreFrom(lastState);
previousStates .remove(moveHolder.size()-1);
}
}
Good luck on the game!
if (moveHolder.size() > 0) {
for (int i = 0; i < panelHolder.length; i++) {
panelHolder[i] = moveHolder.get(moveHolder.size()-1)[i].clone();
}
moveHolder.remove(moveHolder.size()-1);
}
Try this. You need to make copies of each internal array when copying 2D arrays.
Try a Linked List
LinkedList<Cell[][]> ll = new LinkedList();
ll.removeLast();
panelHolder = ll.clone();

Set variable to reference another variable, Java

In Android Studio, I have two array lists with a custom object
ArrayList<MenuMaker> consessionlist = new ArrayList<MenuMaker>();
ArrayList<MenuMaker> entrylist = new ArrayList<MenuMaker>();
And have a few voids that depending on which mode we are in, it needs to use one ArrayList or the other:
private void createMenuButtons()
{
int FoodSize = consessionlist.size();
...
I realize I could do an if statement that if mode = 0 use consessionlist, else use entrylist, but is there a way to say
private void setmode(mode)
{
if (mode == 0){
menulist = consessionlist;
}
else
{
menulist = entrylist;
}
}
private void createMenuButtons()
{
int FoodSize = menulist.size();
...
*Pass-by-reference vs pass-by-value seem to kick my butt on the Oracle test.
I thought I would have to use an if statement overtime I need to choose or have to add some weird complexity, but thus far its actually working as I wanted it to.

How do I check if I have just clicked on a certain object from an array?

Basicly I am creating a game that you click on falling objects, E.G cookies, and I need to know how to check and see if a certain cookie has been pressed so it can disappear but the problem is that its in an array.
Here is a bit of my code:
Input class...
public class Input implements MouseListener, MouseMotionListener{
#Override
public void mousePressed(MouseEvent e) {
if(e.getSource().equals(MainGame.CG)){
if(MainGame.MG.inGame){
//There is actually something else here but its classified (haha sorry about that)
if(e.getPoint().x > /*I NEED SOMETHING HERE*/){
//tells you if the object has been pressed
MainGame.CG.cookieClicked = true; //CG = ClickerGame
}
}
}
}
}
class with array...
public class ClickerGame extends JPanel{
public int amount;
public FallingObject[] fo = new FallingObject[120]; //THE ARRAY I'M HAVING TROUBLES WITH
/*THE REST IS A SECRET (SORRY ABOUT THAT)*/
}
If you don't understand here is a picture to demonstrate what I need...
In order to avoid having to check the coordinates of 120 different items on each click, make every element inside FallingObject[] aware of three things:
Its own area of influence (see sn00fy's answer)
The containing class (in this case probably ClickerGame
Its location in the array (an int)
To do this, you would need to change your FallingObject constructor to look something like this:
public void FallingObject(ClickerGame master, int index); //add whatever else is needed for Falling Object.
Then you could instantiate the array as follows.
for(int i = 0; i < 120; i++) {
fo[i] = new FallingObject(this, i ); //add anything else needed for the constructor
}
Then each FallingObject is responsible for its own state, and when clicked it is able to report back to the ClickerGame instance. All you need now is a method in ClickerGame which each FallingObject can call.
public void clickedObj(int index) {
FallingObject temp = null;
if(index >= 0 && index < 120) {
temp = fo[index];
//Do stuff with temp :)
}
}
To call this method from within FallingObject just reference the 'master' variable (which you should probably save as a global variable within the class.
You have to check every element in your FallingObject[] array if it intersects with the mouse pointer coordinates at the moment of the click.
You can implement a simple rectangle test or use a circle for each cookie as explained here:
Equation for testing if a point is inside a circle

Categories