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

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));
}

Related

Unable to see ArrayList elements in another object in Java

I'm trying to view the elements of an ArrayList in a different class but it shows that there is nothing. In the other class, you can see the element in the ArrayList though.
Here are the codes.
First class
import java.util.ArrayList;
public class Test {
ArrayList<String> inventory = new ArrayList<String>();
public void test() {
inventory.add("item");
}
public void check() {
System.out.println(inventory);
}
}
Second class
import java.util.ArrayList;
public class Test2 {
Test testObj = new Test();
public void test2() {
System.out.println(testObj.inventory);
}
}
Main class
public class Main {
public static void main(String[] args) {
Test testObj = new Test();
Test2 test2Obj = new Test2();
testObj.test();
testObj.check();
test2Obj.test2();
}
}
Output
[item]
[]
In java Class level variables are Object associated until unless they are not declared static.
By means of Object associated is that when a object is initialized with new keyword in Java all Object will be having it's own memory and own class variables.
In your case inside main method when you create a Object of Test class and when you create a another test class object inside Test2 class, both will be totally independent of each other. And both will be having their own memory and own variables.
If you want that to get the updates of inventory variables from first object to be available in another object you need to declare it as static and should be initialized inside static block. Static variables are shared across all objects of class. As below:
static ArrayList<String> inventory;
static {
inventory = new ArrayList<String>();
}
In your main method, you call the method that handles adding operation yet you do not call any add methods in the second class and in your main method.
testObj.test();
testObj.check();
This one shows that you add an item into the arraylist and show it. But in the second class you do not add anything but calling it. Therefore there is no way to show any element from that method. What has should be done is that you just need to call the adding method inside of the second class and then try to use the display method.
You didn't call test() method in Test2 class.
To make it work change the Test2 class as follows.
import java.util.ArrayList;
public class Test2 {
Test testObj = new Test();
public void test2() {
testObj.test();
System.out.println(testObj.inventory);
}
}

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...

Class/Object/Method Organization Confusion

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
}
}

Categories

Resources