Class/Object/Method Organization Confusion - java

I'm beginning at Java, so the thinking behind organizing my code so it's cohesive isn't really coming naturally yet. Essentially, I have an ArrayList that has a method that populates it, another that shuffles it, and then a tester program to see if that even worked. My problem is organizing it. From my experience methods can't really see what's in each other, so I have it organized like so:
Class
ArrayList (named al)
Tester Method
Shuffle Method
ArrayList Population Method
My trouble is thusly; how do I, in the tester method, make the ArrayList undergo the actions defined for it in the methods. I've worked with Constructors and Objects, but they don't really seem to apply at least is what I've done so far. I thought it would be something like
al.Shuffle();
But it threw errors all over the place. Does anyone have any insight?
EDIT: as requested, here's the code
package deckofcards;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;
class Deck{
ArrayList<String> al = new ArrayList<String>();
//test method
public void main(String[] args){
Scanner input = new Scanner(System.in);
al.Deck();
//didn't get any further, that threw a "cannot find symbol" error
}
}
private void Shuffle(){
Collections.shuffle(al);
}
private void Deck(){
al.add(0, "Ace of Spades");
//and this goes on for a deck of cards
}
}

In Your components, the class is the main component that holds the rest of your component, then the methods is a task or action that the class can do.
ArrayList is a data structure that holds a data with a specific structure. which the class can use it.
so you orginization could look like this:
class MyClass {
private ArrayList<String> list = new ArrayList<String>();
public static void main(String[] args) {//Tester Method is the main method, because the execution began from here
}
private void populate() {
//
}
private void shuffle() {
//
}
}

Define another class that extends ArrayList
public class MyArrayList extends ArrayList<Object> {
public MyArrayList(){
super();
}
public MyArrayList shuffle(MyArrayList mal){
Collections.shuffle(mal);
return mal;
}
}
And then define everything as MyArrayList. This will basically be the exact same class as ArrayList with extra functionality you want.
public class Deck {
static MyArrayList al = new MyArrayList();
//test method
public static void main(String[] args){
Scanner input = new Scanner(System.in);
Deck();
al = al.shuffle(al);
//didn't get any further, that threw a "cannot find symbol" error
for(Object i : al)
System.out.println(i);
}
private static void Deck(){
al.add(0, "Ace of Spades");
al.add(1, "1");
al.add(2, "2");
al.add(3, "3");
//and this goes on for a deck of cards
}
}

Related

How do i make a static reference to a non-static method?

import java.util.Iterator;
import java.util.ArrayList;
import java.util.Arrays;
class Main {
public static void main(String[] args) {
ArrayList<String> original = new ArrayList<>(Arrays.asList("afd", "asdf", "aavdd", "sajf", "adnf", "afd", "fjfn"));
String find = "afd";
String replaceWith = "asd";
System.out.println(replaceIt(original, find, replaceWith));
}
public ArrayList<String> replaceIt(ArrayList<String> original, String find, String replaceWith){
ArrayList<String> newList = new ArrayList<String>();
for(int y = 0; y<original.size(); i++){
if(!original.get(y).equals(find))
newList.set(y, original.get(y));
newList.set(y, replaceWith);
}
original = newList;
return original;
}
}
How do i call the replaceIt method? I'm confused and I need to make it so it prints the output of that function. I'm so confused somebody please help.
public ArrayList<String> replaceIt() is an instance method, it is only called from Main instances/objects.
public static void main is a static method of class Main, static methods can’t access instance methods and instance variables directly.
Therefor, to call replaceIt() method from static main method, make replaceIt() static.
public static ArrayList<String> replaceIt(/*arguments*/){
//your code goes here
}
Having non-static method in Main is a little odd. It's not like you are going to construct new instances of Main (say, the same way you would construct new instances of a Person class).
These type of generic helpers/utils functions usually go into some sort Utils.java or Helpers.java class, and are declared as static in these files. This way you would be able to invoke: Utils.replaceIt(original, find, replaceWith));
Because replaceIt() is an instance method, you simply need to create an instance of the Main class to call it -
public static void main(String[] args) {
...
Main m = new Main();
System.out.println(m.replaceIt(original, find, replaceWith));
}

Calling a method on an Object from within a Class vs from within a method

This might be a really elementary question but it puzzles me at this stage of my Java learning.
I have got the following piece of code:
package com.soti84;
import java.util.ArrayList;
public class InvokeMethod {
public static void main(String[] args) {
ArrayList<String> exams= new ArrayList<String>();
exams.add("Java");
exams.add("C#");
}
}
If I move the line that instantiates the ArrayList object and the calls on that object outside the method, the line that creates the object is fine but the add() method calls on the object are not allowed. Why is that?
package com.soti84;
import java.util.ArrayList;
public class InvokeMethod {
ArrayList<String> exams= new ArrayList<String>();
exams.add("Java");
exams.add("C#");
public static void main(String[] args) {
}
}
Thanks.
You simply can't do that code outside of methods. If you wanted to do this you would need initializer block or static block.
public class InvokeMethod {
ArrayList<String> exams= new ArrayList<String>();
{
exams.add("Java");
exams.add("C#");
}
Now that block is gonna execute when you create an instance. If your variable was static, you could make that block static (just add static before that block). Static block is gonna execute when your class is initialized. Those blocks can be quite convenient when you need a populated static list/map. Ofcourse, everything that is convenient in programming is probably a bad practice, and same here, those blocks are frowned upon by some people, they can be quite dangerous and lead to hard-to-find bugs (mostly about the order of execution).
In the two examples you are trying to achieve two totally different things.
In the first example you declare the ArrayList inside the main method, therefore the scope of the list will be just this method. The enclosing class has absolutely no connection with that ArrayList.
In the second one you try to create a data member called exams in the class InvokeMethod. That means, every instance of this class will have its own list.
The addition of the elements does not work, because "out of the methods" only declaration and initialization can happen. To fix that, you can use an initialization block:
public class InvokeMethod {
ArrayList<String> exams = new ArrayList<String>();
{
exams.add("Java");
exams.add("C#");
}
public static void main(String[] args) {
}
}
or, the constructor of the class:
public class InvokeMethod {
ArrayList<String> exams = new ArrayList<String>();
public InvokeMethod() {
exams.add("Java");
exams.add("C#");
}
public static void main(String[] args) {
}
}
Note: You can also retrieve this list from main method via an instance of the InvokeMethod class:
public class InvokeMethod {
ArrayList<String> exams = new ArrayList<String>();
public InvokeMethod() {
exams.add("Java");
exams.add("C#");
}
public static void main(String[] args) {
InvokeMethod invokeMethod = new InvokeMethod();
System.out.println(invokeMethod.exams.toString());
invokeMethod.exams.add("Delphi");
System.out.println(invokeMethod.exams.toString());
}
}
will print
[Java, C#]
[Java, C#, Delphi]
That's because "you're calling it from outside the function/method"
ArrayList<String> exams= new ArrayList<String>();
The line above means you're declaring it as the property of an Object. which means you can only access it inside a Method.
If you're going to place the following in your Main
exams.add("Java");
exams.add("C#");
This should work just fine, although you declared the "exams" outside the method.
As per Java language specification, class body declaration has Instance Initializer but don't has method invocation. So in your example ArrayList<String> exams= new ArrayList<String>(); is allowed inside class body but not exams.add("Java");
JLS excerpt :
ClassBody:
{ ClassBodyDeclarationsopt }
ClassBodyDeclarations:
ClassBodyDeclaration
ClassBodyDeclarations ClassBodyDeclaration
ClassBodyDeclaration:
ClassMemberDeclaration
InstanceInitializer
StaticInitializer
ConstructorDeclaration
ClassMemberDeclaration:
FieldDeclaration
MethodDeclaration
ClassDeclaration
InterfaceDeclaration
;

How do I pass objects along from my Main class to other classes

I'm learning to code java and I encountered some problems in which I could use help understanding how things work.
I've made a list containing "Images", on my Main class, called "myList".
public class Main{
public static void main(String[] args) {
List<Images> myList = new ArrayList<Images>();
...
And I want to access it on this "System" class. But it doesn't seem to let me.
The plan is to access a position (the 3rd, in this example) on the given list (list.get(2)).
So I created the method "work".
//Example
public class System{
public static boolean work(List<Images> list){
if( list.get(2).equals(Something) )
return false;
else ... return true;
}
On this same System class I'm trying to use the method "work", giving it the List that I created on my Main class (myList).
public class System{
...
if( work(myList) ) //Don't know how to reffer to myList
return something;
Gives me the error "myList cannot be resolved to a variable".
So the problem is how to reffer to the list I made on my Main, named "myList".
Not sure if I explained that too well but any suggestions?
Make a List a property of System class, then pass it in the constructor
public class System {
private List<Images> images;
public System(List<Images> images) {
this.images = images;
}
//your other methods
}
Ah, in your main you should also pass the list:
System system = new System(myList);
Another option its to make myList public static and access it like this:
Main.myList
Declare one helper class and declare your list with setter and getters. Mainatin a singleton object of this class and use that list then in different other classes.
you need to make sure its accessible.
Right now your list is scoped the main() function. which is static to boot.
You need to make it accessible. You can do this by storing it in a static variable and having a static function return it.
Or you pass the main object along to other object, so they can access it.
public class Main {
private List<Images> myList = new ArrayList<Images>();
public static void main(String[] args) {
new Main(args);
}
public Main(String[] args) {
myList.add('foo.png');
myList.add('bar.png');
System mySystem = new System(this);
}
public List<Images> getImages() {
return myList();
}
}
public class System{
Main global;
public System(Main main) {
global = main;
}
public void doSomething() {
Iterator<Images> it = global.getImages().iterator();
while(it.hasNext()) {
Images images = it.next();
}
}
}

Arraylist in driver class not resolved to variable

Alright, so in my driver class, I want to call my arraylist from another class and print it out. However, when I attempt to call the method, it says that the variable cannot be resolved to a variable. Does anyone have any idea how I can get it "to be resolved".
Here's my code:
Driver:
public static void showing(){
OtherClass.initializeStrings();
System.out.println(OtherClass.showLists(mouseTypes));
}
Other Class:
static ArrayList <String> mouseTypes;
public static void initializeStrings(){ //initialize the strings outside the main
Strings = new ArrayList <String>();
Strings.add("goodbye");
Strings.add("hello");
Strings.add("hi");
}
public static void main(String[] args) {
OtherClass.initializeStrings();
Driver.showing();
}
public static void showLists(ArrayList list){
for (int i = 0; i < list.size(); i++){
System.out.println(list.get(i));
}
}
Any help is appreciated.
Use .showLists(OtherClass.mouseTypes).
However, that breaks both the Single Responsibility Principle, and Encapsulation. Fix it.
Also, you have done a very bad copy-paste job, you have two main methods...

ArrayList syntax error

I tried writing a small program, but it will not compile. Eclipse shows the following errors on the last line:
Syntax error on token(s), misplaced
construct(s)
Syntax error on token "200000", delete
this token
import java.util.ArrayList;
public class Books{
ArrayList<String> booksDB = new ArrayList<String>();
booksDB.ensureCapacity(200000); //Compilation Errors
}
public class Books{
ArrayList<String> booksDB = new ArrayList<String>();
booksDB.ensureCapacity(200000); //Compilation Errors
}
You might be under the impression that this code is executing sequentially (from top to bottom) but that is not the case. What you are doing is creating a private instance field named booksDB that every instance of Books will carry.
Most likely, you want that code to go in the Books constructor (which gets called whenever a new instance of Books is created. Try the following:
public class Books {
private ArrayList<String> booksDB; // this is a field of the Books class
// when we create a new Books instance, we will initialize the booksDB field
public Books() {
booksDB = new ArrayList<String>();
booksDB.ensureCapacity(20000);
}
}
Then use as follows:
public class Main {
public static void main(String[] args) {
Books b = new Books(); // the Books object is constructed, and its private field booksDB is initialized as we specified.
}
}
Except for declarations and imports, all code in Java must reside inside a method (or, as discussed below, inside initializers, which are essentially methods too):
import java.util.ArrayList;
public class Books {
ArrayList<String> booksDB = new ArrayList<String>();
public void doSomething() {
booksDB.ensureCapacity(200000); //Compilation Errors
}
}
Since you seem to be initializing the contents of the object, you might want to put that line in a constructor, which is a method that is automatically run on newly-created objects:
import java.util.ArrayList;
public class Books {
ArrayList<String> booksDB = new ArrayList<String>();
public Books() {
booksDB.ensureCapacity(200000); //Compilation Errors
}
}
You can use constructor of ArrayList that accepts initial capacity like below
import java.util.ArrayList;
public class Books{
ArrayList<String> booksDB = new ArrayList<String>(200000);
}
Access variables ( booksDB ) only from methods. That's all you have to do.

Categories

Resources