I've recently started writing android applications in Java, I'm completely new to Java and I did the basics of object oriented programming in c++ at college. My question is, what is good and bad practice when passing variable data to different methods in Java? For example, something I have been doing in my code is:
String one;
String two;
String three;
String four;
exampleOne(one, two, three, four);
exampleOne(String one, String two, String three, String four) {
// do something
exampleTwo(one, two, three, four);
}
exampleTwo(String one, String two, String three, String four) {
// do something
exampleThree(one, two, three, four);
}
exampleThree(String one, String two, String three, String four) {
// do something
}
In my code I've done something like this where I pass arguments up to 5 times, is it bad practice to do this? What would be a cleaner more eco option?
If there are many arguments and they would be passed many times, I would go for a DTO object.
Create a Pojo class which encapsulates those parameters and pass the instance between methods. You can add some helper functions/methods in the DTO as well, to ease some processing.
It could be useful to declare a class like this:
public class YourClass{
private String one;
private String two;
private String three;
private String four;
public YourClass(String one, String two, String three, String four){
this.one = one;
this.two = two;
this.three = three;
this.four= four;
}
public void exampleOne() {
// do something
exampleTwo();
}
public void exampleTwo() {
// do something
exampleThree();
}
public void exampleThree() {
// do something
}
}
And use it:
YourClass c = new YourClass(one, two, three, four);
c.exampleOne();
There is nothing wrong in what you did but you can clarify things up using varargs (as TAsk stated) or by creating a small container class (like a c struct, often called bean) which represents a set of parameters.
This allows you to tidy things and make code more readable.
Please be aware that when creating a class you will introduce a little overhead due to a new allocation while this wasn't true with c-struct as it is the compiler which manage references to struct members.
Parameters are passed in stack like in c and there is no concept of by-reference-arguments in java, using a bean can overcome this limitation.
Well,Passing Argument is required when ever you want to call method with some attributes but for huge number of arguments of Same type you can use following.
You can use VarArgs instead.
public void Method(String.. str) {
//Here you will have Array str[](Of String)
if(str!=null)
for (String s: str)
System.out.println(s);//Iterate through Array for More Processing
}
If you want to Pass Other Argument as well
Method(int i, String... Other) {
//VarArgs Must be Last
}
NOTE:
Pass Arguments of Different type and Use conversion methods to convert String to Double,Int,etc.(well This is not recommended but can be done because you need to make sure at which place you have passed double,int etc.)
Related
Is it a standard way to code or any other alternatives are there? I thinking this a while about the code that I've written. Finally gave up and thought to check with you guys.
Here is the scenario I had.
private String functionNameXYZ(String a,String b) {
//Logic goes here
}
private String functionNameXYZ(String a,String b,String c) {
//Same logic goes here , Nothing much difference because of String c
}
So I tho
ught to skip two functions for same purpose and I created a single function as below.
private String functionNameXYZ(String a, String b,String... c){
return performlogic(a,b,(c.lenght!=0)? c[0]:null);
}
private String performlogic(String a,String b, String c) {
//logic , return "string"
}
Which is standard way of coding? Was it to seperate logic into new method instead of repeating[Second case] or Was it other way? Kindly suggest if you find any better ways?
If your only two valid options are two String arguments and three String arguments, using varargs is a tad overkill, and worse - it's confusing, as it implies that you could also pass five or ten or a gazillion arguments. Instead, you could do something much simpler:
private String functionNameXYZ(String a, String b) {
functionNameXYZ(a, b, null);
}
private String functionNameXYZ(String a, String b, String c) {
// One place for the logic
}
Your first scenario is fine, except you want to maybe take any large bulk of common code in the functions and put it in a separate function (or more easily, have the function with less params call the one with more).
The overloading is fine, but rewriting the same code both places is not good practice.
Also, since Java doesn't have default parameters, I'm not too keen on having a public method's argument that is nullable, even if noted on the JavaDocs. Overloading is the way to go.
I think you need to ask yourself a question: what input is legal?
If your program should handle 2...n arguments, then absolutely go with the varargs. However if the legal input to your function is either exactly 2 or 3 arguments, then you should use the pattern:
private String functionNameXYZ(String a, String b) {
// logic of function
}
private String functionNameXYZ(String a, String b, String c) {
// place the logic for handling 'c' input then call
functionNameXYZ(a, b);
}
Alternatively, as the other poster mentioned:
private String functionNameXYZ(String a, String b) {
functionNameXYZ(a, b, null);
}
private String functionNameXYZ(String a, String b, String c) {
// One place for the logic
}
Personally, I prefer the first approach as it clearly separates the logic used to handle the 'c' parameter and the others. This is commonly used when you can seperate that logic, e.g. in constructors. However, when the logic can't easily be untangled go for the second approach.
I have this problem where there are several parts in my code where I check if these certain conditions are met so that I can understand if what I am checking is of one type or the other. this ends up becoming large if else trees because I am making lots of checks, the same checks in each method, and there are several different types the thing I am checking can be. This I know can be solved using objects!
Specifically, the things I am checking are 4 string values from a file. based on these string values, the 4 strings together can make one of 3 types. Rather than making these same checks every time I need to get the type the 4 strings make up, I am wondering if I can create a general object given these 4 strings and then determine if that object is an instanceof either specific class 1, 2, or 3. Then I would be able to cast that general object to the specific object.
Say I name the general object that the 4 strings create called Sign. I would take those 4 strings and create a new Sign object:
Sign unkownType = new Sign(string1, string2, string3, string4);
I need to check which specific type of sign this sign is.
EDIT:
for more detail, the Signs I am checking are not symbols like "+" or "-", they are signs with text like you would see on the road. there are 4 lines on each sign and they need to be checked to see if each line evaluates to match a specific type of sign.
The first line of SignType1 will be different of the first line of SignType2, and I want to take those 4 lines (Strings) and pass it onto an object and use that object throughout my code to get the values from it rather than making the same checks in each method.
If you want me to show some code, I can, but it won't make much sense.
What you seem to asking for is a factory pattern
public interface ISign {
public void operation1();
public void operation2();
}
and a Factory class to generate classes based on input
public class SignGenerator {
public static ISign getSignObject(String str1,String str2, String str3, String str4) {
if(str1.equals("blah blah"))
return new FirstType();
if(str1.equals("blah blah2") && str2.equals("lorem ipsum"))
return new SecondType();
return new ThirdType();
}
}
public class FirstType implements ISign {
}
public class SecondType implements ISign {
}
public class ThirdType implements ISign {
}
Implement all Type specific logic in these classes so you can call them without checking with tons of if..else clauses first
From what I gathered from your statement.
Say: create the method that returns a certain object provided the given string is equal to whateva value you specify
//provided the objects to be returned are subtypes of Sign
public Sign getInstance(String first, String second, String third, String fourth)
{
if(first==null || second==null || third==null || fourth===null )
return null;
if(compare1.equals(first))
return new SignType1();
else
if(compare2.equals(second))
return new SignType2();
else
if(compare3.equals(third))
return new SignType3();
else
if(compare4.equals(fourth))
return new SignType4();
}
Above code checks and returns thee appropriet instance corresponding to the string passed
Hope that's what was your concern
I sometimes (actually, often) find myself using a one-element array to return multiple values from a method. Something like this:
public static int foo(int param1, int param2[], String param3[])
{
// method body
....
// set return values
param2[0] = <some value>;
param3[0] = <some value>;
return <some value>;
}
Is this a bad practice? (It seems like it is because some of my friends said they didn't know what it was doing for 2 seconds!)
But the reason I used this in the first place was because this looked closest to what is know as pass-by-reference in C++. And the practice wasn't discouraged in C++, so ...
But if this is really a wrong way of doing things, any idea how to rewrite this in the clean way?
Thanks
Create an object that contains the data you want to return.
Then you can return an instance of that object.
class FooData {
private int someInt;
private int anotherInt;
private String someString;
public FooData(int a, int b, String c) {
someInt = a;
anotherInt = b;
someString = c;
}
}
public FooData foo() {
// do stuff
FooData fd = new FooData(blah, blahh, blahhh);
return fd;
}
While I agree with the general opinion here that using arrays for such a purpose is bad practice, I'd like to add a few things.
Are you sure that "pass by reference" really is what you need in the first place?
Many have said that your code is bad style, but now let me tell you why that is IMHO.
"Pass by reference" is mostly a synonym for "programming by side effect" which is a thing you always want to avoid. It makes code much harder to debug and understand, and in a multi-threaded environment, the bad effects of this attitude really can hit you hard.
To write scalable and thread-safe code in Java, you should make objects "read-only" as much as possible, i.e. ideally, you create an object and initialize it at the same time, then use it with this unmodifiable state throughout your application. Logical changes to the state can almost always be considered a "creation" of new state, i.e. creation of a new instance initialized to a state then needed. Many modern scripting languages only let you work in this way, and it makes things much easier to understand.
As opposed to C++, Java is much more efficient in allocating and releasing short-lived objects, so there is actually nothing wrong with what others here have suggested: To create an instance of a special class to hold the function result, just for the purpose of returning the result. Even if you do that in a loop, the JVM will be smart enough to deal with that efficiently. Java will only allocate memory from the OS in very large chunks when needed, and will deal with object creation and release internally without the overhead involved in languages like C/C++. "Pass by reference" really doesn't help you very much in Java.
EDIT: I suggest you search this forum or the net for the terms "side-effect", "functional programming" or "immutability". This will most likely open a new perspective to your question.
I believe that it is bad practice to "return" values using one-element arrays that are parameters to your method.
Here's another SO question about this topic. In short, it's very bad for readability.
There is an easy workaround: Wrap all values that you wish to return in a class you define specifically for this purpose, and return an instance of that class.
return new ValueHolder(someValue1, someValue2, someValue3);
That's not very idiomatic java. There are usually better approaches to software design.
What you're really doing with the "one-element array" is creating a mutable object (since String is immutable, as are primitives like int) and passing it by reference. Modifying this mutable object is called a "side effect" of the method. In general, you should minimize mutability (Effective Java Item 15) and your methods should be side-effect free. There are a couple approaches here.
1. Split the method into two (or three) methods that all take the same params:
public static int foo1(int param1)
{
// method body
....
return <some value>;
}
Similarly, you might have
public static int foo2(int param1) { ... }
and
public static String foo3(int param1) { ... }.
2. Return a composite object.
public Container {
private final int originalReturn;
private final int param2;
private final String param3;
public Container(int originalReturn, int param2, String param3) {
this.originalReturn = originalReturn;
this.param2 = param2;
this.param3 = param3;
}
// getters
}
public static Container foo(int param1, int param2[], String param3[])
{
// method body
....
// set return values
return new Container(<some value>, <some value>, <some value>);
}
This is indeed bad practice if the values are unrelated. This is usually an indicator that you can split that function into two, with each returning one of the values.
EDIT:
I am assuming that you are returning two values calculated in the method in an array. Is this not the case?
e.g.
public int[] getStatistics(int[] nums)
{
//code
int[] returns = new int[2];
returns[0] = mean;
returns[1] = mode;
return returns;
}
The above function could be split into getMean() and getMode().
Passing variables by reference allows the function to "legally" change their value. See this article to clear up the confusion of when this is possible in Java, and when it's not...
This is bad practice if the values are of different type and different entities, e.g. name and address, etc. It is fine with create an array with same data type, e.g list of addresses.
Between interfaces and enums, which is better for declaring constants? Why is it so?
Its always better to use Enums to declare constants as the objective of interfaces are on a totally different level. Yes, there are lots of interfaces which have a public static final constants, but I feel that enums exclusive job is to provide you these constants.
If there is a reason for your constants to have a specific type, if they need some kind of behavior (i.e., methods), or if they are composites of other values, enums are the way to go.
For example, let's assume you're implementing a card game and you want to represent values and suits:
enum Rank {
ACE, TWO, THREE, FOUR, FIVE, SIX, SEVEN,
EIGHT, NINE, TEN, JACK, QUEEN, KING;
}
enum Suit { SPADES, CLUBS, DIAMONDS, HEARTS }
There, it's now impossible to create cards with bogus suits or ranks.
Sometimes, though, you are just interested in having a bunch of frequently used values declared somewhere. In that case, putting them in an enum would just be unnecessary effort, since these constants are just a tool to save us from remembering all the decimals of, say, π when we are calculating the circumference of a circle, or something. Which looks better?
// Using enum:
enum MathConstant {
PI(3.14159265358979323846), E(2.7182818284590452354);
private final double value;
MathConstant(double v) { value = v; }
public double value() { return value; }
}
// Usage:
double circumference = MathConstant.PI.value() * diameter;
// Using a constant class:
final class MathConstants {
private MathConstants() { throw new UnsupportedOperationException(); }
public static final double PI = 3.14159265358979323846,
E = 2.7182818284590452354;
}
// Usage:
double circumference = MathConstants.PI * diameter;
As for interfaces: Never put constants in an interface. The "constant interface" pattern is bad (justification), and the only argument to use it has been rendered invalid since import static was added to Java.
Interfaces are designed to define common behaviours, enums to define common values.
Enum represents a real value which can be compared to another value, or stored in the database easily.
You can also have a flag-enum (in C#, don't know in Java) which let you perform binary operations on enum's values (AND, OR, XOR, etc).
If you work with Java 5 or newer then Enum are the way to go. The only exception is if your list of const is open and can be extended. Enums can not be extended. Another exception is if it are single values like a MAX_INTEGER.
Just a code :
public interface InterfaceForConstants() {
String **TOTO** = "Et voilà !";
double **PI** = 3.14159265358979323846;
}
Using :
class ClasseName implements InterfaceForConstants () {
String myString;
if (myString.equals(**TOTO**) {
// do something
}
double circumference = **PI** * diameter; // instead of MathConstants.PI * diameter;
}
Clean and simple. If something can do what you need, take the simplest one!
Writing code by the rules is good, writing code that is easy to read is better, even if a rule is not respected. Think about when you have to read your code after a few months.
If you want to be more specific, make a javadoc to explain it!
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 4 years ago.
I have an assignment that is supposed to use three stacks to ultimately find palindromes. Two stacks will need to hold the reverse of the input sequence. I need to pop the items from one of those stacks and push them into the third stack. This will obviously create two stacks with reverse items that can be compared to see if the input string is a palindrome.
I have already written a class 'ArrayStack' and 'LinkedStack'. I am now supposed to write a class that has three ArrayStack instance variables, a constructor that takes no parameters and will create three stacks of type ArrayStack and a method that takes a string parameter and returns a boolean. The incoming string will be used to check for Palindromes. The individual characters of the string will need to pushed into one of the stacks.
After that is figured out, I need to do the same thing, but with using the 'LinkedStacked' class.
This is the code I have so far and have tried multiple things and have gotten multiple errors (NPE, etc). Any pointers / explanations / advice would be appreciated. I think I have gotten myself really confused. Thanks in advance for any help offered.
Please note I am a beginner.
public class ArrayPalindrome {
static ArrayStack one;
static ArrayStack two;
static ArrayStack three;
public ArrayPalindrome(){
this.one = one;
this.two = two;
this.three = three;
}
public static boolean isPalindrome (String input ){
String input2 = "";
for (int i = 0; i < input.length(); i++) {
char character = input.charAt(i);
one.push(character);
}
while (!one.isEmpty()) {
// add the character at the top to a string
input2 = input2 + one.pop();
}
return true;
}
public static void main(String[] args) {
if (one.equals(two)){
System.out.println("Palindrome");
}
else {
System.out.println("Not a Palindrome");
}
}
If you have a NPE in one.equals(two) is becausw one is null. One is a reference pointing to nothing, you are not setting it in your main method.
I suppose that you set this reference in the constructor of ArrayPalindrome. You have to call in your main method the constructor ArrayPalindrome.
Remeber that your constructor should be change, not to use this.one=one where you are saying the one variable has to refer to one and one is nothing. You have to create an object f.e: one=new ArrayStack().
You are not calling isPalindrom anywhere you have only defined It.