dot operator and static keyword in Java - java

Hello fellow programmers.
I have a question about static and the dot operator using this example in Java.
So I have this class variable declaration of an ArrayList inside my Inventory class.
static List<Multimedia> list = new ArrayList<Multimedia>();
If I choose to use the add method of the ArrayList in the method, should I write the method call like this: Inventory.list.add(Object o) or should I use list.add(Object o). Do they mean the same thing? If they are not, which method call should I use?

from class both are same,
Use
Inventory.list.add(Object o )
It will keep telling you that its a static field in code

You can't access the list in other packages so it would be better to create private list and expose it via public wrapper methods.
private static List<Multimedia> list = new ArrayList<Multimedia>();
public static void addMultimedia(Multimedia media){
list.add(media);
}
public static List<Multimedia> getList(){
return list;
}
To add Multimedia object:
Inventory.addMultimedia(new Multimedia());
//or
Inventory.getList().add(new Multimedia());

Outside the class you have to access it via the class name (but it depends on the access modifier i.e private cannot be accessed outside the class), inside the class you could use either of them.

Definately you should use Inventory.list.add(Object o ) because static fields are at class level i.e. shared among objects of that class.

Related

modifying the value of a non static variable which was initialized with a static variable modifies the static variable as well

I need help !. I am trying to access the value of a static variable from one class in another class in an android project. This is the static class...
public class NamesStore {
private static NamesStore sNamesStore ;
private static List<Name> sNames = new ArrayList<>();
public static NamesStore getInstance() {
if (sNamesStore == null) {
return new NamesStore();
} else {
return sNamesStore;
}
}
public List<Name> getNames(){
return sNames;
}
}
now in other class, I try to get the static variable to use the value but modifying it before use like this ...
public class Utils{
public static removeTheseNamesFromTheGeneralNames(List<Name> namesToBeRemoved){
List<Name> names = NamesStore.getInstance().getNames();
names.removeAll(namesToBeRemoved);
return names;
}
}
when I call the method removeTheseNamesFromTheGeneralNames, the static variable in NamesStore is also modified and I can't figure out why.? Is this a normal behavior of a static field? and if so, please how can I copy the value of a static field and modify without changing the value stored in the static field.? I could make it static and final to resolve this but I also need to set that static variable from time to time with a setter method. Thanks for the help in advance.
'static' is not really the core problem here (though it might contribute). The problem is in method getNames() and how the result is used by its caller.
In your NamesStore class, there is one list of names (the ArrayList) and there is one reference to that list of names (sNames).
When you execute return sNames and the caller assigns the return value to his variable names, you still have exactly one list of names (one ArrayList), now with two references to the same list. This is not a consequence of 'static' but a consequence of how Java uses reference types; in short, assignment (and returning a value) makes a copy of a reference, it does not make another instance of the thing being referred to.
So, of course, when the list referred to by names is modified, that does modify the one and only list of names that exists.
If you wish to allow the caller to modify the list returned by your getNames() method without modifying your list, then you need to return a copy of your list, not your list itself.
Writing return new ArrayList<>(sNames) would do that; but note that only the list of names is copied, whatever is in the list is (presumably 'names') is not. In other words, if your caller modifies an actual name, it will modify the only instance of that name. You need to determine what your requirements are.
An alternative approach is to forbid your user from changing the returned list; that can be implemented as return Collections.unmodifiableList(sNames). If an attempt is made to change that list then the code doing that change will fail. Anyone who wants to modify the list (as in your example) must make themselves a copy first.
The decision between these two is probably made on the basis of considering how many users of getNames() expect to modify the result. If that is not the usual case, then making those users do the copying is generally the better approach.
I think is better to read about class members first, to understand how it works. https://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html
My advice is to refactor the code in this way:
public class NamesStore {
private static NamesStore sNamesStore = new NamesStore();
private List<Name> sNames = new ArrayList<>();
private NamesStore(){}
public static NamesStore getInstance() {
return sNamesStore;
}
public List<Name> getNames() {
return Collections.unmodifiableList(sNames);
}
public List<Name> getNamesWithout(List<Name> namesToBeRemoved) {
return sNames.stream().filter(name -> !namesToBeRemoved.contains(name)).collect(Collectors.toList());
}
}
EXPLANTION ABOUT FILTER METHOD
The method getNamesWithout(List namesToBeRemoved) can be written also in this way:
public List<Name> getNamesWithout(List<Name> namesToBeRemoved) {
return sNames.stream().filter(new Predicate<Name>() {
#Override
public boolean test(Name name) {
return !namesToBeRemoved.contains(name);
}
}).collect(Collectors.toList());
}
The interface Predicate, has a single abstract method (a single method that you have to implement in subclasses). In Java, an interface with a single abstract method is called functional interface. When you have to implement a functional interface, you can use lambda expression. What does't mean this: you can omit the boilerplate code and to keep only what is important. In the below picture, the important code is marked in green and the boilerplate code in red.
I hope that my explanation clarifies you what is with that name from the lambda expression.

Keeping track of all instances of a subclass in the superclass

I have the following, stripped-down Java code:
// Class, in it's own file
import java.util.*;
public class Superclass {
protected List<Subclass> instances = new ArrayList<>();
public class Subclass extends Superclass {
private int someField;
public Subclass(int someValue) {
this.someField = someValue;
updateSuperclass();
}
private void updateSuperclass() {
super.instances.add(this);
}
}
}
// Implementation, somewhere else, everything has been imported properly
Superclass big = new Superclass();
Subclass little1 = big.new Subclass(1);
Subclass little2 = big.new Subclass(2);
Subclass little3 = big.new Subclass(3);
I want to implement a method in Superclass to do something with all the Subclasses. When a Subclass is created, it should add itself to a list in Superclass, but whenever I try to loop through that list in Superclass, it says the size is 1. The first element in the list (instances.get(0)) just spits out a String with all the proper information, but not in object form, and not separately. It's like every time I go to add to the list, it gets appended to the first (or zeroeth) element in String form.
How can I solve this so I can maintain an ArrayList of Subclasses to later loop over and run methods from? I'm definitely a beginner at Java, which doesn't help my case.
If all you need is a count then I suggest a static value that is updated in the constructor of the parent class.
private static int instanceCount = 0;
public Constructor() {
instanceCount++;
}
If you absolutely need every instance in a list so you can do something with them then I recommend you strongly re-consider your design.
You can always create a utility class that will let you maintain the list of objects to run processes on. It's more "Object Oriented" that way. You can also create one class that has all of the operations and then a simpler bean class that has only the data values.
But, if you insist, you can still use the same technique.
private static List<SuperClass> list = new LinkedList<SuperClass>;
public Constructor() {
list.add(this)
}
Each instance gets its own copy of your superclass's variables.
What you want to do is make the variable "static" by putting the static keyword before it. You probably don't even need the superclass accomplish what you're trying to do.

how to call method that contains array

Complete beginner here. I am trying to call a method from a class to run in the main class. But I cannot seem to figure out why it is not work. Here is how I am calling the class
public static void main(String[] args) {
findMP3Tracks FT = new findMP3Tracks();
FT.findMP3();
This is the class method i want to call
public static List<String> findMP3(String p)
{
List<String> foundMP3Tracks = new ArrayList<>();
try (DirectoryStream<Path> folderContents = Files.newDirectoryStream(Paths.get(p)))
{
//Look for
for (Path folderItem: folderContents){
if(Files.isDirectory(folderItem, LinkOption.NOFOLLOW_LINKS)) {
foundMP3Tracks.addAll(findMP3(folderItem.toString()));
}
else if(isValidMP3(folderItem.toString())) {
foundMP3Tracks.add(folderItem.toString());
}
}
}
Assuming findMP3(String) is a method inside the class findMP3Tracks (I would recommend you to follow Java conventions for class names), you may call it in the main as:
public static void main(String[] args) {
...
List<String> result = findMP3Tracks.findMP3("Name of MP3");
}
You may use the name of the class findMP3Tracks to invoke the method findMP3, because it is declared as static. So it's not necessary to create an instance to call it. (Of course you may want to create instances of that class for other operations)
Also, since findMP3 is returning a List<String>, you may want to store it in a variable (In the example result)
First, you don't need instances to call a static method, so this line
findMP3Tracks FT = new findMP3Tracks();
is useless, you can remove it.
Use (for example)
findMP3Tracks.findMP3("Some MP3 name");
Also you need to get the returned value, so it should be:
final List<String> mp3List = findMP3Tracks.findMP3("Some MP3 name");
PS: in Java by convention class names start with uppercase, I suggest you change findMP3Tracks class name to FindMP3Tracks
You've declared the method as
public static List<String> findMP3(String p)
which means (among other things) that when you call it, you're going to pass in a String argument. But you wrote
FT.findMP3();
where you're not passing in any argument at all. Something like
FT.findMP3("Hello");
would compile; or if you had a String variable whose value was the name of the MP3 that you wanted to search for, you could use that too. But the call to any method MUST match the declaration of that method.
The method findMP3 is declared as static. Static variables and methods are members of the class.
You can invoke it directly using the classname. So, it should be findMP3Tracks.findMP3()
Also, a word about the static method. If you do know that the behaviour of the method isnt different for different instances, then you might/can declare it as static. Although, it is a design decision that you would make. If it does behave differently based on the passed in parameter, it is better off to have a method which isnt static.

What is the purpose of static keyword in this simple example? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
When should a method be static?
Usually when writing a static method for a class, the method can be accessed using ClassName.methodName. What is the purpose of using 'static' in this simple example and why should/should not use it here? also does private static defeat the purpose of using static?
public class SimpleTest {
public static void main(String[] args) {
System.out.println("Printing...");
// Invoke the test1 method - no ClassName.methodName needed but works fine?
test1(5);
}
public static void test1(int n1) {
System.out.println("Number: " + n1.toString());
}
//versus
public void test2(int n1) {
System.out.println("Number: " + n1.toString());
}
//versus
private static void test3(int n1) {
System.out.println("Number: " + n1.toString());
}
}
I had a look at a few tutorials. E.g. http://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html
My understanding of it is that instead of creating an instance of a class to use that method, you can just use the class name - saves memory in that certain situations there is no point in constructing an object every time to use a particular method.
The purpose of the static keyword is to be able to use a member without creating an instance of the class.
This is what happens here; all the methods (including the private ones) are invoked without creating an instance of SimpleTest.
In this Example,Static is used to directly to access the methods.A private static method defeats the purpose of "Data hiding".
Your main can directly call test1 method as it is also Static,it dosn't require any object to communicate.Main cannot refer non-static members,or any other non-static member cannot refer static member.
"non-static members cannot be referred from a static context"
You can refer This thread for more info about Static members.
static means that the function doesn't require an instance of the class to be called. Instead of:
SimpleTest st = new SimpleTest();
st.test2(5);
you can call:
SimpleTest.test1(5);
You can read more about static methods in this article.
A question about private static has already been asked here. The important part to take away is this:
A private static method by itself does not violate OOP per se, but when you have a lot of these methods on a class that don't need (and cannot*) access instance fields, you are not programming in an OO way, because "object" implies state + operations on that state defined together. Why are you putting these methods on that class, if they don't need any state? -eljenso
static means that the method is not associated with an instance of the class.
It is orthogonal to public/protected/private, which determine the accessibility of the method.
Calling test1 from main in your example works without using the class name because test1 is a static method in the same class as main. If you wanted to call test2 from main, you would need to instantiate an object of that class first because it is not a static method.
A static method does not need to be qualified with a class name when that method is in the same class.
That a method is private (static or not) simply means it can't be accessed from another class.
An instance method (test2 in your example) can only be called on an instance of a class, i.e:
new SimpleTest().test2(5);
Since main is a static method, if you want to call a method of the class without having to instantiate it, you need to make those methods also static.
In regards to making a private method static, it has more readability character than other. There isn't really that much of a difference behind the hoods.
You put in static methods all the computations which are not related to a specific instance of your class.
About the visibility, public static is used when you want to export the functionality, while private static is intended for instance-independent but internal use.
For instance, suppose that you want to assign an unique identifier to each instance of your class. The counter which gives you the next id isn't related to any specific instance, and you also don't want external code to modify it. So you can do something like:
class Foo {
private static int nextId = 0;
private static int getNext () {
return nextId ++;
}
public final int id;
public Foo () {
id = getNext(); // Equivalent: Foo.getNext()
}
}
If in this case you want also to know, from outside the class, how many instances have been created, you can add the following method:
public static int getInstancesCount () {
return nextId;
}
About the ClassName.methodName syntax: it is useful because it specifies the name of the class which provides the static method. If you need to call the method from inside the class you can neglect the first part, as the name methodName would be the closest in terms of namespace.

Having different ArrayLists for class objects in Java

I have a class and this class has one public element ArrayList myList.(I have other elements too in my class but they have nothing to do with this element)
What I am trying to do is having different ArrayLists for different Class Objects. However when I tried to code this, even if I use different class objects, the code reserves every entry in one single ArrayList. What am i doing wrong?
This is what i tried:
My class:
public class myClass {
public static ArrayList myList;
public static ArrayList getList() {
return myList;
}
public static void setList(ArrayList myList) {
myClass.myList = myList;
}
In main:
myClass my = new myClass();
myClass my2 = new myClass();
ArrayList tmp = new ArrayList();
ArrayList tmp2 = new ArrayList();
tmp.add("aaaaa");
tmp.add("bbbbb");
tmp2.add("ccccc");
tmp2.add("ddddd");
my.setList(tmp);
my2.setList(tmp2);
for(int i=0;i<my.getList().size();i++)
{
System.out.println(my.getList().get(i));
}
And the output of this main is being:
ccccc
ddddd
but i want it to be:
aaaaa
bbbbb
What am i doing wrong?
You declared myClass#myList static, which means only one instance of myList will exist, inside the CLASS myClass. Declare it non-static, including the getter and setter, to have different instances for my and my2 and you're good to go.
you are using static in your class.
remove static keyword for the variable in your class and you should be fine. Static is class scoped so will be shared across objects.
As identified by the other comments, you are declaring the ArrayList as static, which means it is shared across all object instances of the class - as such in the following statement:
my.setList(tmp);
my2.setList(tmp2);
...the second setList overwrites the first.
Read on up the Singleton pattern for a good example of where to use static fields:
Singleton pattern
As an aside, consider passing your values into the constructor and only providing a getter, thus encapsulating the use of ArrayList and making the values immutable - for example:
myClass my = new myClass("aaaa", "bbbb");
String element = my.get(0);
Finally, if using Java 5 or 6, think about using Generics when working with collections/lists:
List<String> tmp = new ArrayList<String>();
Hope that helps.
Modify your class as follows
public class myClass {
public ArrayList myList;
public ArrayList getList() {
return myList;
}
public void setList(ArrayList myList) {
listler.myList = myList;
}
You're using static ArrayList myList which is common to all the objects of your class myClass. Therefore, you're not getting what you expect. Avoid using static, if you need to use the ArrayList myList separately to all the objects of the class.
Java allows you to access static members of a class in both the ways with its objects and with associating them with their class name but its a bad practice to associate static members with the class objects.
Associating static members themselves with the class object was actual a flaw in language design itself (hence, should be avoided accessing them with objects) which was corrected by C# and hence in C# you can not associate static members with the respective class objects.
In java, some IDEs might issue warnings or errors, if you try to access static members with the respective class objects.

Categories

Resources