Java : Static methods - java

I am at beginner stage in learning java, I made a program for bubble sort. Code is as follows
package bubblesort;
public class Bubblesort {
public static void main(String[] args) {
int[] arr = new int[] {10,20,40,30,50};
arr = BubbleSort(arr);
for(int i:arr) {
System.out.println(i+" ");
}
}
public static int[] BubbleSort(int[] arr) {
int temp;
for(int i = 0;i<arr.length;i++) {
for(int j =i+1;j<arr.length;j++) {
if(arr[i] > arr[j]) {
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
return arr;
}
}
My question is as following :
"Since a static method can only take static data variables as parameters, then why 'BubbleSort' function in my program is not reporting any error because of arr not being a static variable ?"

Since a static method can only take static data variables as parameters
Incorrect.
A static method can only directly reference other static members, not instance members. This refers to class-level fields, methods, etc.
But any method can accept as a parameter/argument any value you pass to it. And can internally declare and use any local variable it wants.

A static method can only access static members of its containing type. So in your case the BubbleSort method cannot access any instance fields or methods of the BubbleSort class. Arguments and local variables are of course always allowed.

Static methods neither know nor care where the parameters came from in the first place. It doesn't matter that it's a local variable because it has a reference to the array.
What you actually can't do is "directly" refer to instance methods or fields from a static method because, by definition, it needs a specific instance to call those methods on.

Related

Method to print through an arraylist not working right

Okay, I'm a newbie and I need some advice about organization in my code. I've been getting an error that says my arraylist cannot resolved.
What I'm doing is I'm extending an abstract class (I don't know if thats relevant) and I've created an array list in my main and filled it with things and then I've got my method to print out the contents of that array list.
If anyone can help me, please do. Thanks
Here's my code:
public static void main(String[] args) {
ArrayList <String> Strings = new ArrayList <String>();
Strings.add("Hi");
Strings.add("How are you");
Strings.add("Huh");
}
public void showFirstString(){
for (int i = 0; i < Strings.size(); i++){
System.out.println(Strings(i));
}
}
Please avoid using the word String as a variable name because java already used it as a keyword. Just replace it with another name.
Here is what you should do because you are using ArrayList:
public static void main(String[] args) {
ArrayList <String> list= new ArrayList <String>();
list.add("Hi");
list.add("How are you");
list.add("Huh");
showFirstString(list);
}
public static void showFirstString(ArrayList list){
for (int i = 0; i < list.size(); i++){
System.out.println(list.get(i));
}
}
And make sure to import the ArrayList library.
read more about its docu here
You need to use the .get(index) method, where index is the element you want to access. For example:
System.out.println(Strings.get(i));
You would also want to call that method in main.
You never call showFirstString() and in addition, Strings isn't a global variable, so you will get an error on the first line of that method. To fix this, put showFirstString(Strings) in your main method and change your method signature to public void showFirstString(Arraylist Strings). In addition, arraylists are accessed using list.get(index) so change the line in your loop to System.out.println(Strings.get(i));
If you want to get elements from an array list, you have to use list.get(index) method as follows. It's because you cannot access elements as in arrays when it comes to array lists.
public void showFirstString(){
for (int i = 0; i < Strings.size(); i++){
System.out.println(Strings.get(i));
}
}
First of all, your naming convention is not very good.
Second,List collection circular elements is list.get(index),is not list(index)
There are answers that address what OP should do to improve but I feel the important part in his question my arraylist cannot resolved. is not discussed. My answer adds to that part.
When compilers complain XXX cannot be resolved, it means that the compiler is encountering the variable's name for the first time and has no idea of what the stuff with that name is. In your case, the compiler does not know what is Strings in showFirstString(), and because it does not know what is Strings, it stops compiling and complains to you instead of keep going with knowing nothing about it, which could potentially be dangerous.
The reason the compiler could not know what was Strings in showFirstString() is known as the scope of variables. Basically, there are lots of blocks in Java as in:
public void myMethod()
{ /* method body block is here* }
or even like,
public class myClass
{
/* here starts the class body */
public static void myMethod()
{ /* method body block is here* }
}
And the thing is that the variables are known only within a block where it's declared. So for example, if your codes looks like this:
public class myClass
{
int foo; // it is known to everywhere within this class block
public static void myMethod()
{
// boo is known only within this method
int boo = foo + 1; // fine, it knows what foo is
}
public static void myMethod2()
{
// bar is known only within this method
int bar = boo + 1; // cause errors: it does not know what boo is
}
}
Now you should understand why your programme was not able to know what is Strings. But passing around data within your codes is a common stuff that is often required to do. To achieve this, we pass parameters to methods. A parameter is a data specified within () that follows the name of the method.
For example:
public class myClass
{
int foo; // it is known to everywhere within this class block
public static void myMethod()
{
// boo is known only within this method
int boo = foo + 1; // fine, it knows what foo is
myMethod2(boo); // value of boo is passed to myMethod2
}
public static void myMethod2(int k) // value of k will be boo
{
// bar is known only within this method
int bar = k + 1; // cause errors: it does not know what boo is
}
}
With parameters like above, you can use boo in myMethod2(). The final thing is that with the codes above, your codes will compile but will do nothing when you run it, because you did not start any of the methods. When a programme runs, it looks for the main method and any other methods that you want to invoke should be called in methods, or by other methods that are in main.
public class myClass
{
int foo; // it is known to everywhere within this class block
public static void main(String[] args)
{
// start myMethod
myMethod();
}
public static void myMethod()
{
// boo is known only within this method
int boo = foo + 1; // fine, it knows what foo is
myMethod2(boo); // value of boo is passed to myMethod2
}
public static void myMethod2(int k) // value of k will be boo
{
// bar is known only within this method
int bar = k + 1; // cause errors: it does not know what boo is
}
}
I hope you get the idea. Also note that to get the items in an ArrayList, you need to use ArrayList.get(int index), as others noted.
First of all, as others have pointed out, you will need to use the Strings.get(i) method to access the value stored inside a given list element.
Secondly, as Matthias explains, the variable Strings is out of scope and therefore cannot be accessed from the showFirstString() method.
Beyond that, the problem is that your main() method, which is static, cannot interact with the instance method showFirstString() and vice versa.
Static methods live at the class level and do not require an instance of that class to be created. For example:
String.valueOf(1);
Instance methods on the other hand, as the name implies, require an instance of that class to be created before they can be called. In other words, they are called on the object (instance of the class) rather than the class itself.
String greeting = "hi there";
greeting.toUpperCase();
This provides further details:
Java: when to use static methods
Without knowing your specific situation, you have two options...
Make both your Strings list as static (class level) field and showFirstString() method static.
public class ListPrinterApp {
static ArrayList<String> Strings = new ArrayList <String>();
public static void main(String[] args) {
Strings.add("Hi");
Strings.add("How are you");
Strings.add("Huh");
showFirstString();
}
static void showFirstString(){
for (int i = 0; i < Strings.size(); i++){
System.out.println(Strings.get(i));
}
}
}
Move code that deals with the list into a separate class, which is then called from your application's static main method. This is likely a better option.
public class ListPrinter {
ArrayList<String> Strings = new ArrayList<String>();
public ListPrinter() {
Strings.add("Hi");
Strings.add("How are you");
Strings.add("Huh");
}
public void showFirstString() {
for (int i = 0; i < Strings.size(); i++) {
System.out.println(Strings.get(i));
}
}
}
public class ListPrinterApp {
public static void main(String[] args) {
ListPrinter printer = new ListPrinter();
printer.showFirstString();
}
}
(I put the the Strings.add() calls into the constructor of ListPrinter as an example. Presumably, you would not want to hardcode those values, in which case you should add an add() method to your ListPrinter class through which you can populate the list.)
A few additional points not directly related to your question:
Take a look at the naming conventions for variables in Java. Specifically:
If the name you choose consists of only one word, spell that word in
all lowercase letters. If it consists of more than one word,
capitalize the first letter of each subsequent word.
Consider using the interface List instead of the concrete implementation of ArrayList when declaring your variable (left side of the equals sign). More info here.

How can I use an array within a method that was called in as a parameter for a different constructor initializer?? (Java)

How can I use an array within a method that was called in as a parameter for a different constructor initializer in the same class?
For example:
private static Initialize(int[] array)
private static void Display()
I want to take the array called in above in the Initialize method and use it in the Display method. I kept getting null reference pointer errors when I first tried it. Thank you for any help in advance!!
You can declare your array outside the method Initialize to have access in your class body.
For example:
private static int[] array;
private static Initialize() {
array = new int[] { 1, 2, 3 };
}
private static void Display() {
for (int i : array) {
System.out.println(i);
}
}
Assign the array to a class variable when Initialize() is called.
private static int[] array;
private static Initialize(int[] array) {
this.array=array;
}
The array can then be referenced as array as long as Initialize has already been called.
You probably mean how you can transfer one instance of array between classes.
Simplest way is using simple composition(in this case for one Array, but you can use it on n number of object):
First you need to define new class, which constructor takes in the array data as parameter and define the uninitialized array(which serves as a bridge between classes and also a container for the instantiated data).
public class TransferArray {
private String[] transferredArray;
public TransferArray(String[] originalArray){
transferredArray = originalArray;
}
String[] getArray() {
return transferredArray;
}
}
now to test this work, use this in the main class(both arrays now printing Hello)
String[] originalArray = {"Hello"};
TransferArray transfer = new TransferArray(originalArray);
String[] newArray = transfer.getArray();
System.out.println(originalArray[0]);
System.out.println(newArray[0]);

Can instance variable be declared as static variable in java

I wrote the following code:
public class Count
{
private static int[] array;
public Count( int[] array )
{
this.array = array;
}
public int count()
{
int count = 0;
for (int i = 0; i < array.length; i++) {
int x = array[i];
if (x < 0) {
if (x == -1 && i > 0 && array[i - 1] == -1) {
break;
}
} else {
count++;
}
}
return count;
}
}
and then in another class I wrote:
Count c = new Count(new int[]{1,-1,-1});
and checked the result of c.count().
I didn't get a compiler error,and I got 1 as I wanted.
I wonder why because how can I assign a static variable to an instance variable?
And also, what happens if I create another instance of class Count?
Will they both have the same variable?or just their own copy of it? and what should happen if I try to access the variable by writing Count.array?
Thanks.
array is shared between all the instances of Count - they can all read from it and write to it. And as you stated, if you instance modifies it, all the other instances will see the newly modified value.
Classes can access their own static members.
All classes will see the same static members (ignoring thread contention complications).
If you create another instance of Count they will both be modifying the same variable.
That's what static means...
I'd recommend that you write the example you're asking about and see. There's no better authority than the JVM, and it'll tell you faster than SO will.
I think you should understand the meaning of class and instance variables and pick the one that matches your intent.
So it's either class:
public class Count
{
// Shared by all
private static int[] array;
}
or instance:
public class Count
{
// Owned by instance
private int[] array;
public Count(int [] v) {
if (v == null) throw new IllegalArgumentException("array cannot be null");
this.array = new int(v.length);
System.arraycopy(v, this.array, 0, v.length);
}
}
You should not just assign the array reference to the private data member. You need to allocate memory and copy the values into it. Otherwise the supplier of the input array will modify the private values if it updates using their reference.
Too many people don't realize that assigning mutable references to private members breaks encapsulation. Maybe you won't be one of them now.

'This method must return a result of type int' Java?

public static void main(String args[])
{
double arr[] = {1,-6.3,9000,67.009,1.1,0.0,-456,6,23,-451.88};
ArrayList<Integer> List = new ArrayList<Integer>();
List.add(1);
List.add((int) -6.3);
List.add(9000);
List.add((int) 67.009);
List.add((int)1.1);
List.add((int)0.0);
List.add(-456);
List.add(6);
List.add(23);
List.add((int)451.88);
}
public static int ArrayListMax(ArrayList List)
{
for (int i=0; i<List.size(); ++i)
{
System.out.println(List.get(i));
}
The error is in:
public static int ArrayListMax(ArrayList List)
This is probably a very nooby mistake, but I'm new to Java so forgive me.
Any help please?
Thank you.
EDIT:
I want the ArrayListMax method to print the size of the List!
Assuming you are trying to get the maximum value in your List in the method arrayListMax, you need to return an integer in accordance with your method signature, which the error is telling you
This method must return a result of type int
Instead of printing all the values in the list, you could do:
public static int arrayListMax(List<Integer> List) {
return Collections.max(list);
}
Use Java Naming Conventions. Method & variable names begin with a lowercase letter. Using this approach helps avoid confusion between instances & types (e.g. in the case of List in the main method).
Either add a return statement to your ArrayListMax() method that returns an int or change the method signature from public static int to public static void. And add a closing } to the method too.
Also, you shouldn't use List as a name for the argument to that method because it's the name of an interface that you're actually importing in this code. The convention in java is for variable names and method names to begin with a lowercase letter (camel case) and class names to begin with an uppercase letter (pascal case).
Problem is in this method:
public static int ArrayListMax(ArrayList List)
{
for (int i=0; i<List.size(); ++i)
{
System.out.println(List.get(i));
}
}
You are not returning from this method, you must return of type int to solve that error. Since you have specified int as return type.
You created the function as returning a result
public static int ArrayListMax(ArrayList List)
In order to remove your problem, if you need not return anything, write
public static void ArrayListMax(ArrayList List)
void means you do not want the method to return a result.
if you are just printing out values the signature should be public static void ArrayListMax(ArrayList List).
First, you are not returning anything with ArrayListMax method even if you have set its retun type to int. Either return void as you are directly printing from the list.
Second, even if you set the correct return type to ArrayListMax method, you will still need to call that method in the main method as below:
public static void main(String args[])
{
double arr[] = {1,-6.3,9000,67.009,1.1,0.0,-456,6,23,-451.88};
ArrayList<Integer> List = new ArrayList<Integer>();
List.add(1);
List.add((int) -6.3);
List.add(9000);
List.add((int) 67.009);
List.add((int)1.1);
List.add((int)0.0);
List.add(-456);
List.add(6);
List.add(23);
List.add((int)451.88);
YourClassNameInWhichMethodIs.ArrayListMax(List);
}
You should use a return statement as Methode is returning an int type value.

Varargs, immutable array, and thread-safety

Hi all I have an immutable array implementation which looks like this:
public static final class FixedArray<T> {
private final T[] array;
public final int Length;
#SafeVarargs
public FixedArray(T... args) {
array = args;
Length = args.length;
}
public T Get(int index) {
return array[index];
}
}
public static final class FixedIntArray {
private final int[] array;
public final int Length;
public FixedIntArray(int... args) {
array = args;
Length = args.length;
}
public int Get(int index) {
return array[index];
}
}
public static final class FixedLongArray {
private final long[] array;
public final int Length;
public FixedLongArray(long... args) {
array = args;
Length = args.length;
}
public long Get(int index) {
return array[index];
}
}
Initially I'd thought that it is guaranteed to be thread-safe. But after reading the discussion regarding immutable arrays and the Java Memory Model, I believe alone, I can't be sure.
I've not used a defensive copy, with the contract that the calling code "does the right thing" (and as usual, if it doesn't follow the contract, the behavior is undefined).
The calling method looks like this:
public static void main(String args[]) {
int[] ints = new int[10000];
FixedIntArray fixed_ints = new FixedIntArray(ints);
SendToThreadA(fixed_ints);
SendToThreadB(fixed_ints);
SendToThreadC(fixed_ints);
SendToThreadD(fixed_ints);
//caller (which is this method) does the right thing, ints goes out of scope without anyone trying to modify it.
}
I was wondering is the code above guaranteed to be thread-safe?
As we don't know what happens to the array (and its values) to which you store a reference, I think your classes would be much safer if the constuctors create a copy of the argument array and set the internal final reference to the copied array.
It's OK. You can require caller to "hand-off" the array to you. Caller can clone one if necessary.
Memory write is usually the most expensive thing in a program (sans external IO).
Not everybody is stupid. You only need to be defensive enough to protect your target user base.
Given that you can pass an array to a varargs method, you'd need to make a copy of the constructor input to ensure it can't be modified outside the class. Having done that, as long as you don't assign the final field until after all the values are assigned in the copy array, you should be fine because the assignment to the final field is guaranteed to happen before any read of that field from another thread.
So a constructor would look like:
array = Arrays.copyOf(args, args.length);
Orrrr you could just use a Guava ImmutableList and get a lot more power.
I'm not sure it's meaningful to examine it for thread-safety, because it's missing even a more basic level of safety. Consider this method:
public static void main(final String... args)
{
final int[] arr = new int[] { 3, 3, 3 };
final FixedIntArray threeThrees = new FixedIntArray(arr);
System.out.println(threeThrees.Get(0)); // prints "3"
System.out.println(threeThrees.Get(1)); // prints "3"
System.out.println(threeThrees.Get(2)); // prints "3"
arr[0] = arr[1] = arr[2] = 4;
System.out.println(threeThrees.Get(0)); // prints "4"
System.out.println(threeThrees.Get(1)); // prints "4"
System.out.println(threeThrees.Get(2)); // prints "4"
}
The problem is that, when a method that takes int... (or Object... or long... or anything else), it can receive either an array that's implicitly constructed by the compiler (as would happen if you typed new FixedIntArray(3,3,3)), or an array that's explicitly passed in by the calling code (as I did above). In the latter case, the calling code can continue to modify the array that it passed in!

Categories