I am new to using generics. I want to print out a pair of Integers and Strings. Here is my code:
public class Pair<T> {
private T first;
private T second;
public Pair(T first, T second) {
this.first = first;
this.second = second;
}
public T getFirst() {
return first;
}
public T getSecond() {
return second;
}
public void setFirst(T first) {
this.first = first;
}
public void setSecond(T second) {
this.second = second;
}
public <T> void toString(Pair<T> k) {
System.out.println(k.getFirst());
System.out.println(k.getSecond());
}
}
public class TestPair {
public static void main(String[] args) {
Pair<String> pS = new Pair<String>("yay", "it worked" );
Pair<Integer> pI = new Pair<Integer>(1, 2);
pS.toString();
pI.toString();
}
}
At the moment, it compiles but upon running TestPair class, I don't get anything printed out.
You need to be aware that now, your toString() method doesn't override Object.toString() method (as it is stated in official Java tutorial here: The overriding method has the same name, number and type of parameters, and return type as the method that it overrides). . If you want to call you implementation of toString() you need to pass argument of type Pair to it, as your toString() requires Pair instance as an argument. I rather suggest you to change your toString method to:
public void toString() {
System.out.println(this.getFirst());
System.out.println(this.getSecond());
}
In that case when you call:
pS.toString();
pI.toString();
, you get correct results as now your toString() doesn't require Pair argument.
The way you have it now, your "toString" takes a parameter so you have to pass it like so (note the parameters added to toString).
public static void main(String[] args) {
Pair<String> pS = new Pair<String>("yay", "it worked");
Pair<Integer> pI = new Pair<Integer>(1, 2);
pS.toString(pS);
pI.toString(pI);
}
Without the parameters - it calls the default toString() method of the object which returns a string representation like "test.Pair#33909752" which the class name followed by "#" followed by the address/pointer to the class. But since you are not printing the returned value from the default toString method of Object class - nothing prints.
The way toString typically should be coded is to return a String (you would override the toString method of the object). Something like:
#Override
public String toString() {
return "Pair [first=" + first + ", second=" + second + "]";
}
Then in your main program you should print it like:
System.out.println (pS.toString());
System.out.println (pI.toString());
or simply (because when printing "toString()" is implied)
System.out.println (pS);
System.out.println (pI);
There are two problems with your code:
In your main method you are calling toString() (with zero arguments) which the Pair class inherits from Object. This method returns a generic string like Pair#123. But as you don't do anything with this string, you don't get an output. You could create an output by writing System.out.println(pS.toString()); (or even System.out.println(pS);.
In your Pair-class, you have defined a toString method with one parameter. I suppose you wanted to overwrite the Object.toString(), so you should also use code like public String toString() {return first.toString() + " " + second.toString()} (plus null checks)
Related
I'm taking those first steps from python to java and here is my first of many Java questions do doubt.
When printing via a shortened print method, I'm running into a problem with the return value from a inherited class. I'm sure it's something simple about Java I don't get yet. I'm also trying to convert any integers the println method receives to a string with .tostring(), but I'm not sure if that is correct.
class Inheritance {
private static void println (Object line){
System.out.println(line.toString());
}
static class A {
public int multiply(int a, int b){
int val = a*b;
return val;
}
}
static class B extends A {
public int multiply(int a, int b) {
int val = a * b * 5;
return val;
}
}
public static void main(String[] args) {
B b_class = new B();
b_class.multiply(3,4);
println(b_class);
println("Hello World");
}
}
The output is as follows:
Inheritance$B#74a14482
Hello World
You can just use the method inside println
public static void main(String[] args) {
B b_class = new B();
println(Integer.ToString(b_class.multiply(3,4)));
println("Hello World");
}
For Java toString method default it will
returns a string consisting of the name of the class of which the object is an instance, the at-sign character `#', and the unsigned hexadecimal representation of the hash code of the object. In other words, this method returns a string equal to the value of:
getClass().getName() + '#' + Integer.toHexString(hashCode())
https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#toString()
so when you println b_class it will print: Inheritance$B#74a14482.
For your println (Object line) it's receiving Reference type(Object) to println, but as multiply method it's return a primitive type(int), it's not an object, you need to convert it to an Object for println method, as #StanteyS's answer, use Integer.toString can convert int to String.
What's the difference between primitive and reference types?
When you are executing println(b_class); implicitly it calls toString method of same class, which is inherited from Object class.
You need to override toString method to display correct output.
static class B extends A {
int val=0;
public int multiply(int a, int b) {
val = a * b * 5;
return val;
}
public String toString(){
return String.valueOf(val);
}
}
Now, println(b_class); will work as per your expectation.
When i run 2nd class i see " Car#15ab7626 " why ? in teory i must see 20, yes?
I have alredy used differnet combinatoin & ask google but dont understent why.
i have 1 class
public class Car {
public int drive(int a) {
int distance = 2*a;
return distance;
}
}
and 2nd class
public class CarOwner {
public static void main(String[] args) {
Car a = new Car();
a.drive(10);
System.out.println(a);
}
}
You are printing the car object, not the result printed by drive
That incomprehensible value JAVA is textual representation of Object.
When you do System.out.println(a); then by default toString() method calls on passed object.
As per docs of toString()
Returns a string representation of the object. In general, the toString method returns a string that "textually represents" this object.
So
Car#15ab7626 is the textual representation of Values class.
To print result which is returned by your drive() method, print,
System.out.println(a.drive(10));
If you want to print the result from the drive() method, assign the result to a variable and then print it.
int result = a.drive(10);
System.out.println("Result = " + result);
or directly pass the result to the System.out.println() method;
System.out.println("Result = " + a.drive(10));
If you want to print the a object in a readable way, override the toString() method in the Car class definition.
#Override
public String toString() {
return "This is a car"; //for example
}
You are returning the value you have from a drive method, but you're not printing it.
To print out the value of the drive method, use
public class CarOwner {
public static void main(String[] args) {
Car a = new Car();
System.out.println(a.drive(10));
}
}
That's not the way method return values work. If you want to see the result as 20, replace your SOP with the following
System.out.println(a.drive(10));
I was wondering if it's possible to call another function just by adding the function name to the parameter. So for instance I want to make a script with 4 parts. Each part requires input (I am using a scanner, dont ask why :P its the assignment) and then needs to pass it to another script for e.g. calculations and stuff.
I start of with this:
static int intKiezer(String returnFunctie, String text) {
Scanner vrager = new Scanner(System.in);
while (true) {
System.out.println(text);
int intGekozen = vrager.nextInt();
if (vrager.hasNextInt()) {
returnFunctie(intGekozen);
}
else {
vrager.next();
System.out.println("Verkeerde invoer!");
}
}
As you see I am trying to push the obtained value to another function by trying to call it (returnFunctie(intgekozen)). It should be calling returnFunctie with intgekozen as parameter. But its not working
I would be calling the function like this: intKiezer(sphereCalculations, "What radius do you want to have?"). So the answer from the input, if its correct should be passed to another function called sphereCalculations
Here is an idea.
Define an interface that has a method that does whatever calculation you want to perform. For example:
interface Algorithm {
int execute(int value);
}
Then define one or more classes that implement the interface and do whatever calculations you want them to do. For example:
class MultiplyByTwo implements Algorithm {
public int execute(int value) {
return value * 2;
}
}
class AddThree implements Algorithm {
public int execute(int value) {
return value + 3;
}
}
Then, write your method so that it accepts an Algorithm as a parameter. Execute the algorithm with the desired value.
static int intKiezer(Algorithm algo, String text) {
// ...
return algo.execute(intGekozen);
}
Call your method by passing in an instance of one of the implementation classes of interface Algorithm.
int result = intKiezer(new MultiplyByTwo(), "Some question");
System.out.println("Result: " + result);
As #Jesper said, it is possible with reflection, and probably only with reflection. Reflection is the process in which an object can analyze itself and iterate through it's members (attributes and methods). In your case, it seems you are looking for a method.
By the looks of your code, it seems like what you want is, in fact, passing a function object to your code, where a parameter could be applied. This isn't possible in Java. Something similar will be possible in Java 8 with the addition of closures. You could do that in Groovy, by passing a Closure as a parameter, or other language with support for closure or functions.
You can get near what you want by defining an abstract class/interface, passing an instance of it to your method, and then calling a method passing the parameter to it, like:
interface Function <T> {
public Integer call(T t);
}
public class TestFunction {
static int intKiezer(Function<Integer> returnFunctie, String text)
{
int a = 10;
System.out.println(text);
return returnFunctie.call(a);
}
public static void main(String[] args)
{
Function<Integer> function = new Function<Integer>() {
public Integer call(Integer t) { return t * 2; }
};
System.out.println( intKiezer(function, "Applying 10 on function") );
}
}
If your intention is to call a method, then you are better using some reflection library. Apache Common's MethodUtil comes to mind. I think this your man:
invokeMethod(Object object, String methodName, Object arg)
Invoke a named method whose parameter type matches the object type.
Java is a 'pass by value' language, meaning that sending in a variable into a method, pointing the variable to a new object, does not effect the outer variable.
public void one() {
String s = "one";
two(s);
System.out.println(s);
}
public void two( String s ) {
s = "two";
}
Would write "one".
Is there a way to prevent this? Or what is the most common solution or pattern to actually change s to "two" inside the method?
Is not possible to prevent it.
You can emulate it with a generic wrapper like this:
class _<T>{
public T _;
public _(T t ) {
_ = t;
}
public String toString(){ return _.toString(); }
}
And then use it as you intended.
class GeneriWrapperDemo {
public static void main(String [] args ) {
_<String> one = new _<String>("One");
two( one );
System.out.println( one );
}
public static void two( _<String> s ) {
s._ = "two";
}
}
But looks ugly. I think the best would be to change the reference it self:
public String two( String a ) {
return "two";
}
And use it
String one = "one";
one = two( one );
:)
You can't pass-by-reference - at least not the variable itself. All parameters are passed by value. However, objects contain references - and are represented as references themselves. You can always change the insides of the object, and have the changes stick. Thus, send an array, or create a wrapper class, or make your own reference object:
class Ref<T> {
T obj;
public Ref(T value) {
this.obj = value;
}
public void set(T value) {
obj = value;
}
public T get() {
return obj;
}
}
As the others have said, String is not mutable anyway, so you're not actually changing the string here, but making the variable point the other way, so it does not really make that much sense not to simply return the new string.
If s were a mutable object, you could change its value (i.e. the value of its data members). And the member can be a String too. This doesn't work with a String parameter directly, as it is immutable, so the only way to "change" it is to direct the reference to a different object.
Create an object, which contains the string, then pass that into the method.
public class StringHolder {
public String s;
public StringHolder(String s) {
this.s = s;
}
}
Then the code would look like:
public void two(StringHolder sh) {
sh.s = "two";
}
StringHolder sh = new StringHolder("one");
two(sh);
System.out.println(sh.s);
Although, for the above example, you could just return the value you want:
public String two(String s) {
return "two";
}
String s = "one";
s = two(s);
System.out.println(s);
And for Strings, you can always use StringBuffer, which is mutable:
public void two(StringBuffer buf) {
buf.setLength(0);
buf.append("two");
}
You can't prevent Java from passing by value; that's the language semantics.
You can, one way or another, get around it, depending on what you want to do.
You can return a new value based on the parameter that's passed:
static String scramble(String s) {
return s.replaceAll("(.*) (.*)", "$2, $1");
}
// then later...
String s = "james bond";
s = scramble(s);
System.out.println(s); // prints "bond, james"
You can also pass something that is mutable:
static void scramble(StringBuilder sb) {
int p = sb.indexOf(" ");
sb.append(", ").append(sb.substring(0, p)).delete(0, p+1);
}
// then later...
StringBuilder sb = new StringBuilder("james bond");
scramble(sb);
System.out.println(sb); // prints "bond, james"
Strings are immutable... otherwise, though, all you would have to do is call a method to operate on the same object and have that somehow change the string value.
I'm sure there are a number of Java classes that will do the job for you, but you could also roll your own simply by creating an encapsulating class with either a public field or a setter/getter. An example of the former is something like this:
public class EncapsulatedString
{
public String str;
public EncapsulatedString(String s)
{
str = s;
}
}
Create a wrapper that contains your object and change contents of the wrapper:
public class StringWrapper {
private String str;
public String getString() {
return str;
}
public String setString(String str){
this.str = str;
}
public String toString() {
return str;
}
}
public void one() {
StringWrapper s = new StringWrapper();
s.setString("one");
two(w);
// This will print "two"
System.out.println(s);
}
public void two( StringWrapper s ) {
s.setString("two");
}
One ugly solution that comes to my mind is to pass around a String array of length 1. It's not something I would encourage but if you feel that you want to do it...
1 public class One {
2
3 public static void main( String[] _ ) {
4 String[] s = {"one"};
5 two(s);
6 System.out.println(s[0]);
7 }
8
9 public static void two( String[] s ) {
10 s[0] = "two";
11 }
12 }
1-length array is a bit ugly, but perfectly working solution. No need to create surplus wrapper classes:
public void one() {
String[] s = new String[]{"one"};
two(s);
System.out.println(s[0]);
}
public void two(String[] s) {
s[0] = "two";
}
This pattern is especially useful when translating old (e.g. C) code where pass by reference has been extensively applied.
That said, returning a new, fresh value is always less confusing than mutating the "input" value.
Use StringBuffer, or StringBuilder, which are mutable.
Java is not a pass-by-value language. On the contrary - it is a pass-by-reference language. (passing-by-reference does not mean you can change the original "pointer" to point elsewhere like C++ allows).
The only things which are passed by value are primitives (int, long, char etc.)
Object references are always passed by reference - so if your Object is able to support change to its contents (e.g. via getter and setter methods) - it can be changed.
String specifically is immutable - meaning that its contents may never be changed. So for your specific question, if you want the String referred to by the local variable 's' to change you need to provide it with a reference to a new instance of a String object.
Example:
public void one()
{
String s = "one";
s = two(); // Here your local variable will point to a new instance of a String with the value "two"
System.out.println(s);
}
public String two()
{
return "two";
}
If you use objects other than String - you can define setter methods on them that will update their contents for you.
This question already has answers here:
Does Java have something like C#'s ref and out keywords?
(7 answers)
Closed 1 year ago.
Could someone please give me some sample code that uses an output parameter in function? I've tried to Google it but just found it just in functions. I'd like to use this output value in another function.
The code I am developing intended to be run in Android.
Java passes by value; there's no out parameter like in C#.
You can either use return, or mutate an object passed as a reference (by value).
Related questions
Does Java have something like C#'s ref and out keywords?
? (NO!)
Is Java pass by reference? (NO!)
Code sample
public class FunctionSample {
static String fReturn() {
return "Hello!";
}
static void fArgNoWorkie(String s) {
s = "What am I doing???"; // Doesn't "work"! Java passes by value!
}
static void fMutate(StringBuilder sb) {
sb.append("Here you go!");
}
public static void main(String[] args) {
String s = null;
s = fReturn();
System.out.println(s); // prints "Hello!"
fArgNoWorkie(s);
System.out.println(s); // prints "Hello!"
StringBuilder sb = new StringBuilder();
fMutate(sb);
s = sb.toString();
System.out.println(s); // prints "Here you go!"
}
}
See also
What is meant by immutable?
StringBuilder and StringBuffer in Java
As for the code that OP needs help with, here's a typical solution of using a special value (usually null for reference types) to indicate success/failure:
Instead of:
String oPerson= null;
if (CheckAddress("5556", oPerson)) {
print(oPerson); // DOESN'T "WORK"! Java passes by value; String is immutable!
}
private boolean CheckAddress(String iAddress, String oPerson) {
// on search succeeded:
oPerson = something; // DOESN'T "WORK"!
return true;
:
// on search failed:
return false;
}
Use a String return type instead, with null to indicate failure.
String person = checkAddress("5556");
if (person != null) {
print(person);
}
private String checkAddress(String address) {
// on search succeeded:
return something;
:
// on search failed:
return null;
}
This is how java.io.BufferedReader.readLine() works, for example: it returns instanceof String (perhaps an empty string!), until it returns null to indicate end of "search".
This is not limited to a reference type return value, of course. The key is that there has to be some special value(s) that is never a valid value, and you use that value for special purposes.
Another classic example is String.indexOf: it returns -1 to indicate search failure.
Note: because Java doesn't have a concept of "input" and "output" parameters, using the i- and o- prefix (e.g. iAddress, oPerson) is unnecessary and unidiomatic.
A more general solution
If you need to return several values, usually they're related in some way (e.g. x and y coordinates of a single Point). The best solution would be to encapsulate these values together. People have used an Object[] or a List<Object>, or a generic Pair<T1,T2>, but really, your own type would be best.
For this problem, I recommend an immutable SearchResult type like this to encapsulate the boolean and String search results:
public class SearchResult {
public final String name;
public final boolean isFound;
public SearchResult(String name, boolean isFound) {
this.name = name;
this.isFound = isFound;
}
}
Then in your search function, you do the following:
private SearchResult checkAddress(String address) {
// on address search succeed
return new SearchResult(foundName, true);
:
// on address search failed
return new SearchResult(null, false);
}
And then you use it like this:
SearchResult sr = checkAddress("5556");
if (sr.isFound) {
String name = sr.name;
//...
}
If you want, you can (and probably should) make the final immutable fields non-public, and use public getters instead.
Java does not support output parameters. You can use a return value, or pass in an object as a parameter and modify the object.
You can either use:
return X. this will return only one value.
return object. will return a full object. For example your object might include X, Y, and Z values.
pass array. arrays are passed by reference. i.e. if you pass array of integers, modified the array inside the method, then the original code will see the changes.
Example on passing Array.
void methodOne{
int [] arr = {1,2,3};
methodTwo(arr);
...//print arr here
}
void methodTwo(int [] arr){
for (int i=0; i<arr.length;i++){
arr[i]+=3;
}
}
This will print out: 4,5,6.
As a workaround a generic "ObjectHolder" can be used. See code example below.
The sample output is:
name: John Doe
dob:1953-12-17
name: Jim Miller
dob:1947-04-18
so the Person parameter has been modified since it's wrapped in the Holder which is passed by value - the generic param inside is a reference where the contents can be modified - so actually a different person is returned and the original stays as is.
/**
* show work around for missing call by reference in java
*/
public class OutparamTest {
/**
* a test class to be used as parameter
*/
public static class Person {
public String name;
public String dob;
public void show() {
System.out.println("name: "+name+"\ndob:"+dob);
}
}
/**
* ObjectHolder (Generic ParameterWrapper)
*/
public static class ObjectHolder<T> {
public ObjectHolder(T param) {
this.param=param;
}
public T param;
}
/**
* ObjectHolder is substitute for missing "out" parameter
*/
public static void setPersonData(ObjectHolder<Person> personHolder,String name,String dob) {
// Holder needs to be dereferenced to get access to content
personHolder.param=new Person();
personHolder.param.name=name;
personHolder.param.dob=dob;
}
/**
* show how it works
*/
public static void main(String args[]) {
Person jim=new Person();
jim.name="Jim Miller";
jim.dob="1947-04-18";
ObjectHolder<Person> testPersonHolder=new ObjectHolder(jim);
// modify the testPersonHolder person content by actually creating and returning
// a new Person in the "out parameter"
setPersonData(testPersonHolder,"John Doe","1953-12-17");
testPersonHolder.param.show();
jim.show();
}
}
Wrap the value passed in different classes that might be helpful doing the trick, check below for more real example:
class Ref<T>{
T s;
public void set(T value){
s = value;
}
public T get(){
return s;
}
public Ref(T value) {
s = value;
}
}
class Out<T>{
T s;
public void set(T value){
s = value;
}
public T get(){
return s;
}
public Out() {
}
}
public static void doAndChangeRefs (Ref<String> str, Ref<Integer> i, Out<String> str2){
//refs passed .. set value
str.set("def");
i.set(10);
//out param passed as null .. instantiate and set
str2 = new Out<String>();
str2.set("hello world");
}
public static void main(String args[]) {
Ref<Integer> iRef = new Ref<Integer>(11);
Out<String> strOut = null;
doAndChangeRefs(new Ref<String>("test"), iRef, strOut);
System.out.println(iRef.get());
System.out.println(strOut.get());
}
This is not accurate ---> "...* pass array. arrays are passed by reference. i.e. if you pass array of integers, modified the array inside the method.
Every parameter type is passed by value in Java. Arrays are object, its object reference is passed by value.
This includes an array of primitives (int, double,..) and objects. The integer value is changed by the methodTwo() but it is still the same arr object reference, the methodTwo() cannot add an array element or delete an array element. methodTwo() cannot also, create a new array then set this new array to arr. If you really can pass an array by reference, you can replace that arr with a brand new array of integers.
Every object passed as parameter in Java is passed by value, no exceptions.
Thank you. I use passing in an object as a parameter. My Android code is below
String oPerson= null;
if (CheckAddress("5556", oPerson))
{
Toast.makeText(this,
"It's Match! " + oPerson,
Toast.LENGTH_LONG).show();
}
private boolean CheckAddress(String iAddress, String oPerson)
{
Cursor cAddress = mDbHelper.getAllContacts();
String address = "";
if (cAddress.getCount() > 0) {
cAddress.moveToFirst();
while (cAddress.isAfterLast() == false) {
address = cAddress.getString(2).toString();
oPerson = cAddress.getString(1).toString();
if(iAddress.indexOf(address) != -1)
{
Toast.makeText(this,
"Person : " + oPerson,
Toast.LENGTH_LONG).show();
System.out.println(oPerson);
cAddress.close();
return true;
}
else cAddress.moveToNext();
}
}
cAddress.close();
return false;
}
The result is
Person : John
It's Match! null
Actually, "It's Match! John"
Please check my mistake.