Java - for loop every object of class - java

I'm learning to code and currently I'm trying to clean up my massive code by finally learning classes. I'm telling you this just to give a heads-up my terminology might still be off :) :)
The situation
My code works with "layers" that will be drawn on top of each other
There are two types of layers: video layers and image layers.
Both types of layers are child from parent class "Layer"
They need to be run by creation order
The goal
I want to run a code for each item/object of the class.
current code
import java.util.*;
public class main {
public static void main(String[] args){
// defining the objects
LayerVideo item01 = new LayerVideo();
item01.path = "import/01/";
LayerVideo item02 = new LayerVideo();
item02.path = "import/02/";
LayerImage item03 = new LayerImage();
item03.path = "import/03/";
// here is the main goal:
// to run/call each object from class "Layer"
// "allLayers" does not exist, but that's what I don't know how to do.
allLayers.forEach( item ->{
System.out.println( item.path );
// expected result in console:
// import/01/
// import/02/
// import/03/
});
}
public static class Layer {
}
public static class LayerVideo extends Layer {
public String path;
}
public static class LayerImage extends Layer {
public String path;
}
}
Thoughts
How to get all excising objects from a class
If I have them, how to ID them?, by var name?
Could I sort/filter the objects in a loop?

Two things:
consider to make your classes top level ones. So don't go public static class LayerVideo inside your Main class. If they are that important, the classes should each go into their own java file.
then learn about Java collections to organized object instances. You could define use an ArrayList for example.
Beyond that, the point is probably: if you want common things for two different classes, then your base class needs to have that, like:
public abstract class Layer {
private String path;
public String getPath() { return path; }
public void setPath(String newPath) { path = newPath; }
and then your subclasses simply inherit that behavior.
Then, you simply can add objects with that extend that base type to a collection:
List<Layer> layers = new ArrayList<>();
Layer layer = new VideoLayer();
layers.add(layer);

So, with the help and pointers of #GhostCat I've came to the following working code:
main.java
public class main {
public static void main(String[] args){
// debug to see amount of elements in list
System.out.println( settings.layers.size() );
// Aggregate with .forEach(), but will switch to .stream() to also be able to filter
settings.layers.forEach( layer -> {
System.out.println( layer.path );
// do stuff
});
}
}
settings.java
import java.util.ArrayList;
import java.util.List;
public class settings extends main{
public static List<Layer> layers = new ArrayList<>();
static {
layers.add( new LayerImage(true, "input/01/", new int[] {255,255,255} ) );
layers.add( new LayerImage(false, "input/02/", new int[] {255,0,0} ) );
layers.add( new LayerVideo(true, "input/03/", new int[] {0,0,255} ) );
}
}
Layer.java
public abstract class Layer {
boolean run;
String path;
int[] color;
public Layer(boolean startRun, String startPath, int[] startColor) {
run = startRun;
path = startPath;
color = startColor;
}
}
LayerImage.java
public class LayerImage extends Layer {
public LayerImage( boolean startRun, String startPath, int[] startColor) {
super( startRun, startPath, startColor) ;
}
}
LayerVideo.java
public class LayerVideo extends Layer {
public LayerVideo( boolean startRun, String startPath, int[] startColor) {
super( startRun, startPath, startColor) ;
}
}
In the main.java I'll swap the aggregator .forEach() with .stream() later on. Sounds more flexible and to be able to filter the results in advance seems like a big advantage. (then I can also use the item.run to see if I want to run this layer).
Why is there a settings class? I want to be able to have ALL the settings and variables to set for the outcome in one file. This way I can (I think) quickly use different setting files. Maybe also change it to XML input later. Use a GUI or whatever. (You might think "ah, sweet summer child", I'll cross that bridge when I get there).
The Layer SuperClass will have around the 10 parameters/arguments in the constructor when finished. Feels a lot to change and maintaining for the SubClasses by passing it with super(); And later on make changes. What is I will have around, say, 20 SubClasses. Is there a more efficient way?
Any other pointers on what I can do better in this code above?
All in all a LOT learned today! Thanks everyone and special thanks to #GhostCat

I personally create an static ArrayList from the object for every class and add the objects to it in the constructor (with list.add(this)).
Like:
public class Layer{
static ArrayList<Layer> layerList = new ArrayList<>();
public Layer() {
layerList.add(this);
}
}

Related

ANTLR How to specify which listener (or lexer/parser) I want to be used based on input on my multi-grammar structure?

MainLangFile.g4
grammar MainLangFile;
import Child1LangFile, Child2LangFile;
parse:
A (child1 | child2) EOF
;
A: 'A';
B: 'B';
C: 'C';
Child1LangFile.g4
grammar Child1LangFile;
child1:
CHILD1
;
CHILD1: 'CHILD1';
Child2LangFile.g4
grammar Child2LangFile;
child2:
CHILD2
;
CHILD2: 'CHILD2';
My Java application:
public static class MyApp {
public void execute(String query) {
MainLangFileLexer lexer = new MainLangFileLexer(CharStreams.fromString(query));
MainLangFileParser parser = new MainLangFileParser(new CommonTokenStream(lexer));
MainLangFileParser.ParseContext parse = parser.parse();
ParseTreeWalker walker = new ParseTreeWalker();
walker.walk(new Child1Listener(), parse);
walker.walk(new Child2Listener(), parse);
}
static class Child1Listener extends MainLangFileBaseListener {
#Override
public void enterChild1(MainLangFileParser.Child1Context ctx) {
}
}
static class Child2Listener extends MainLangFileBaseListener {
#Override
public void enterChild2(MainLangFileParser.Child2Context ctx) {
}
}
}
I'm trying to have a multi-grammar structure. The solution I've above works perfectly in the sense that each ChildXListener is properly invoked based on the query. It would be the same as just having a single listener and implementing both methods.
The issue begins where there is a enterCommon() method invoked, it is invoked for both listeners even though I "forked" the language and went only on one specific direction.
I need a clever way of selecting which listener should be used by ParseTreeWalker.
Also, I'd rather have each listener, extending their respective grammars, i.e.: Child1Listener should extends Child1LangFileBaseListener, by doing so I have a clear scope of what methods I can safely override as only Child1LangFile.g4 rules will be available.
I couldn't figure out a way of doing this without initializing Child1Lexer, Child1Parser and parsing everything again, either way, this brings me back to the previous issue, how do I know which lexer/parser to use?
Any thoughts? Thanks in advance.
There is no way to tell up front which parser rule(s) are going to be invoked for a given input source.
Since a visitor will not cause the entire parse tree to be visited (you determine that by overriding only the method you wish to visit), you could start off by writing a visitor that can be used up until the rule that contains the (child1 | child2) and inside that visit... method, invoke the specific listener.
That could look something like this:
class MainVisitor extends MainLangFileBaseVisitor<Object> {
#Override
public Object visitParse(MainLangFileParser.ParseContext ctx) {
if (ctx.child1() != null) {
ParseTreeWalker.DEFAULT.walk(new Child1Listener(), ctx);
}
else {
ParseTreeWalker.DEFAULT.walk(new Child2Listener(), ctx);
}
return null;
}
}
class Child1Listener extends Child1LangFileBaseListener {
// ...
}
class Child2Listener extends Child2LangFileBaseListener {
// ...
}

How to instantiate, configure and use a lib/framework in a oo-application?

I decided to split the last part of that question here into a new question here: https://softwareengineering.stackexchange.com/questions/411738/extension-of-classes-where-to-put-behaviour-how-much-direct-access-is-allowe
If i have a lib and i want to use it, i wrote mostly a own class. This class has one method. In that there is the code how to instantiate the lib/framework. Sometimes there are a few more methods, with them i not only instantiate the class but use it. For example if i want to start a http-server i have there a start-method.
class Container
{
TheLib theLib;
public void init() //or a constructor
{
//some init of the theLib
}
public void start() //
{
theLib.doSomething(...)
theLib.doSomethingmore(...);
theLib.start(...);
}
//important!
public TheLib getTheLib()
{
return this.theLib; //after i started configured it and so on, i want of course use all methods,
which the lib have in some other parts in my application
}
}
But it seems not to be the best solution.
Are there any better solutions, that OO is?
Often i also use only one method, a own class for this seems to be here a big overhead?
Exposing the lib breaks encapsulation? Tell-Dont-Ask is also violated?
Everything depend on what you actually need or how you have access to your 'the lib' instance.
public class Container {
private TheLib theLib;
/* #1: Do you already created the instance before? */
public Container(TheLib theLib) {
this.theLib = theLib;
}
/* #2: Do you need to created the instance each time? */
public Container() {
this.theLib = new TheLib();
}
public void start() {
theLib.doSomething(...)
theLib.doSomethingmore(...);
theLib.start(...);
}
public TheLib getTheLib() {
return this.theLib;
}
public static void main(String[] args) {
/* #1 */
TheLib theLib = ...;
Container container = new Container(theLib);
/* #2 */
Container container = new Container();
/* Continue the flow of your program */
container.start();
container.getTheLib().doSomethingEvenMore();
}
}
Or maybe you actually need only one instance of your 'Container' class. In this case, you should look on how to make a singleton: Java Singleton and Synchronization
Anwser: Often i also use only one method, a own class for this seems to be here a big overhead?
Well, in Java, you cannot do formal programming like in C, so everything line of code that you write, or will be using, has to be in a class of some sort.
If your piece of code is small and don't really need an object, static function might do the work.

Java ArrayList a good way to access same list from many classes

Hello i am trying to familiarize myself with Java by doing a very simple "bankaccount" application and it doesn't even save to db or something so it resets all data on rerun.
The problem i am trying to find a good way of doing is that i have an ArrayList of accounts that i want to be able to access from any class so that during runtime for example after an deposit if i access that account later when i want to get balance i get an that account from the ArrayList and it is updated to the deposit value.
When googling i found this solution but i dont like it since it uses static ArrayList. is there any more elegant way than this for an applicaiton that only saves the state/data during runtime.
Simple class that adds the test accounts and so on where first value is acountId and second is balance
public class AccountsModel {
private ArrayList<AccountModel> listOfAccounts;
public AccountsModel() {
listOfAccounts = new ArrayList<AccountModel>();
listOfAccounts.add(new AccountModel(1,0));
listOfAccounts.add(new AccountModel(2,0));
listOfAccounts.add(new AccountModel(3,0));
listOfAccounts.add(new AccountModel(4,0));
}
public ArrayList<AccountModel> getListOfAccounts(){
return listOfAccounts;
}
}
Then in my main class i just do this
static AccountsModel accounts = new AccountsModel();
public static ArrayList<AccountModel> listOfAccounts = accounts.getListOfAccounts();
this "works" as i can get the same list from anywhere within the application. But is there any simple and elegant way of doing this some other way?
You said you dislike the static solution but to me "It needs to be accessed by many classes" screams static variables.
Basically, you create a wrapper for your ArrayList which carries out operations:
class AccountsModel {
private static ArrayList<AccountModel> singleton;
// a static constructor also wouldn't be a bad idea here
public static void init() {
/* add a bunch of AccountModels here*/
}
public static ArrayList<AccountModel> getAccounts() {
return singleton;
}
}
An example of a main method:
public static void main(String[] args) {
ArrayList<AccountModel> accounts = AccountModels.getAccounts();
}

Concept to create thread wide/class wide object

I'm searching for a concept to forward an object to subobjects.
Example:
I would like to create log files for several main Objects, that include sub objects (imagine a REST server that would log every single connection by ID).
Creating one big log file is simple ( redirect System.out.println, I already encapsulated that)
Example code:
class SubElementA{
public SubElementA(){
Debugger.debug("I am called, too");
}
}
Application.java
package com.dev4ag;
class Application{
private ElementA elA;
private String prefix;
public Application(String name){
this.elA = new ElementA();
this.prefix = name;
}
public void countUp(){
Debugger.debug(this.prefix+": I will now count up");
this.elA.doSomeStuff();
}
}
ElementA.java
package com.dev4ag;
class ElementA{
private int counter;
private SubElementA subElementA;
public void doSomeStuff(){
counter++;
Debugger.debug("Counter is: "+counter);
}
//Constructor
public ElementA(){
subElementA = new SubElementA();
this.counter = 0;
};
}
SubElementA.java
package com.dev4ag;
class SubElementA{
public SubElementA(){
Debugger.debug("I am called, too");
}
}
Debugger.java
package com.dev4ag;
public class Debugger {
public static void debug(String output){
//Just imagine we would write to a file here ;)
System.out.println(output);
}
}
(it was more easy to write system.out.println than to create a file, just imagine, Debugger.debug would write to a file).
Now I am thinking about a solution to create one Debug output target for each App. I could definitely change debug to not being static and create a debug object within Application.
But is there any way to use this object in the sub classes without forwarding the debug object either through Constructor or setter function, which would mean to have to add an object for the debugger to each class?
What would be the most beautiful solution for that?
Note that this solution might decrease performance a lot and it is pretty dirty way, but some loggers include such data.
But you can use Thread.currentThread().getStackTrace() to get stacktrace like in error and get class and method from where your method was called.
If you are using java9+ then you should probably use StackWalker API instead, especially that it have nice filters and other useful features.
So then you could guess app by class/method names on the stack.

ArrayStoreException: null while casting List to Array

This may sound silly, but, I get this error while casting from List to Array:
ArrayStoreException: null
The code that i am using right now is :
public void onSuccess(List<Agent> resultList) {
Agent[] array = new Agent[resultList.size()];
resultList.toArray(array);
Agent its a class that i have defined with their own field definitions, being all of them private final Strings
But i dont know what i could be missing atm.
Thank you in advance for your help.
Kind regards,
You're probably passing your ArrayList<Agent> to some method which
has just an ArrayList or List parameter (untyped). This method
can pass compilation but mess things up at runtime. Example below.
If you comment out the call to messUp in my example things are OK.
But messUp can add things which are not Agents to your list,
and cause problems this way.
This is my best guess without seeing your code.
Hope it helps.
import java.util.ArrayList;
import java.util.List;
public class Test009 {
public static void main(String[] args) {
List<Agent> resultList = new ArrayList<Agent>();
resultList.add(null);
resultList.add(new Agent1());
resultList.add(new Agent());
messUp(resultList);
test(resultList);
}
private static void messUp(List lst){
lst.add("123");
}
public static void test(List<Agent> resultList){
Agent[] array = new Agent[resultList.size()];
resultList.toArray(array);
System.out.println("done");
}
}
class Agent {
protected int x;
}
class Agent1 extends Agent{
protected int y;
}
Additional Note: OK, well, this doesn't explain
the "null" part of your error message.
So the root cause is somewhat different.

Categories