This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
How to write a basic swap function in Java
Hi. I don't know java at all, and in the near future have no wish to study it. However I have lots of friends that are java programmers and from conversations I learnt that there is no analog of C#'s ref keyword in Java. Which made me wonder how can one write a function that swaps two integers in Java. My friends (though not very good java experts) could not write such a function. Is it officially impossible? Please note, that I understand that one can swap two integers without a function, the question is exactly to write a function that takes two integers and swaps them. Thanks in advance.
Short: You can't.
Long: You need some workaround, like wrapping them in a mutable datatype, e.g. array, e.g.:
public static void swap(int[] a, int[] b) {
int t = a[0]; a[0] = b[0]; b[0] = t;
}
but that doesn't have the same semantic, since what you're swapping is actually the array members, not the a and b themselves.
In Java, all the arguments are passed by value. So there is no such thing as a ref.
However, you might achieve variable swapping by wapping values in objects (or arrays).
public class Holder<T> {
public T value = null;
public Holder(T v) { this.value = v; }
}
public static <T> void swap(Holder<T> a, Holder<T> b) {
T temp = a.value; a.value = b.value; b.value = temp;
}
Related
So, I am in a course to learn java, and I'm learning about sorting, searching, algorithms, and generics. I am trying to recreate a binary search method/class that accepts any type of Comparable object (like the ArrayList<Type>).
I understand how to do it with ints, but I dont really know how to go about it with non-primitive types.
This is what I assume it should roughly look like:
public class Objects<T> implements Comparable //I'm not sure about this,
//but I need to call compareTo() to compare the objects?
{
/**
* called from other program to find an element index in an array
*/
public static int binSearchAll(T find, T array[])
{
return binarySearch(array, 0, (array.length)-1, find);
}
public static int binarySearch(T array[], int lower, int upper, T X)
//x is the element to find
{
if (upper < lower)
return -1;
int middle = (lower + upper) / 2;
if (array[middle].compareTo(X))
return middle;
if (array[middle] < X)
return binarySearch(a, middle+1, upper, X);
else
return binarySearch(a, lower, middle-1, X);
}
}
I tried to figure out how to make this work, but I'm at a loss. In the int version, it works, but then it's only for integer types and doesn't accept double or string types as the problem asks.
in the driver class, I want to be able to create a new object and use it like this:
String[] str = {"a", "b", "c"};
Objects<String> s = new Objects<String>();
int indexOfB = s.binSearchAll("b", str);
or, if it's possible, like this:
String[] str = {"a", "b", "c"};
int indexOfB = Object<String>.binSearchAll("b", str);
The exact wording of the problem is:
Create an ObjectBinarySearcher class that can search an array of Comparable objects.
Demonstrate the class in a program that searches for a String in an array of String
objects.
I'm almost sure I'm overthinking this.
Thanks for any help you can give!
These two lines are the problem:
if (array[middle].compareTo(X))
...
if (array[middle] < X)
... compareTo returns an int rather than a boolean, and you can't use < on arbitrary types. I suspect you've realized that much, but I'll just give you a hint: read the Comparable.compareTo documentation. You need to use compareTo instead of <... read the documentation for the return value to work out what you need to do.
(You probably just want to call compareTo once, and then check the result twice. There are three possibilities to consider, as documented...)
You need that your template class T implements the Comparable interface. Your actual code means that only your Objects class implement the interface. You must turn
public class Objects<T> implements Comparable {
//class content...
}
Into
public class Objects<T extends Comparable<T>> {
//class content...
}
And also, follow the advice from JonSkeet's answer about compareTo method.
You need that your template class T implements the Comparable
interface. Your actual code means that only your Objects class
implement the interface. You must turn
public class Objects<T> implements Comparable {
//class content...
}
Into
public class Objects<T extends Comparable<T>> {
//class content...
}
Luiggi Mendoza
And...
These two lines are the problem:
if (array[middle].compareTo(X)) ... if (array[middle] < X) ...
compareTo returns an int rather than a boolean, and you can't use < on
arbitrary types. I suspect you've realized that much, but I'll just
give you a hint: read the Comparable.compareTo documentation. You need
to use compareTo instead of <... read the documentation for the return
value to work out what you need to do.
(You probably just want to call compareTo once, and then check the
result twice. There are three possibilities to consider, as
documented...)
Jon Skeet
Thanks for the answers. combined, I managed to get the program working.
It now works with:
String[] str = {"a", "b", "c"};
Objects<String> s = new Objects<String>();
int indexOfB = s.binSearchAll("b", str);
This question already has answers here:
Difference between int[] array and int array[]
(26 answers)
Closed 10 years ago.
When I want to implement a function in C++ , if it matters to receive the int array in the following cases?
void fn1(int []a) {
a[0] = 1;
}
void fn2(int a[]) {
a[0] = 1;
}
In Java, there is no semantic difference.
In C++, the first syntax is invalid.
In Java,the declaration is same...
but in C++,the fn1() declaration need to be different
Well, the question is not clear.. Whether to receive the int array or not, it depends on the logics of your method. In Java it is better to write a[], but you can write either way.
Also, look over here - pass array to method Java
I need to convert C code to Java.
The minimal C code is:
void changeX(int *x)
{
*x=5;
}
changeX is called in function B as:
void B()
{
int k= 2;
changeX((int*) &k);
}
The problem while converting it into Java is that x is not a class member so i cannot use this. How can i convert such code to Java?
Assuming you're really asking, "Can I use pass-by-reference in Java" (which that C code isn't using, but is emulating with pointers, which also aren't supported in Java) the answer is no.
Options:
Pass in a reference to an object which does contain a field you can change
(Ugly, but equivalent to the above in some senses) Pass in an array of size 1 constructed using the local variable, mutate the variable in the method, and then set the local variable again based on the array contents afterwards
Return the new value and assign it that way
Change your design so you don't need this
The last two of these options are the nicest ones. If you could give more information about the bigger picture - why you think you want to do this - that would be helpful.
Use one-element array reference:
void changeX(int[] x) {
// do not forget about checks
x[0] = 5;
}
void test() {
int[] x = {0};
changeX(x);
}
Being a primitive, and not a class member, you cannot pass the reference to another method. Use a class member instead.
You should return the new value of x,the method should as follow:
private int changeX(int x){
return 5;
}
You existing C code is incorrect:
void B()
{
int k= 2;
// you are not passing address of variable k but instead
// you are passing k (which is 2) as the address whose location needs
// to be changed. So you are writing to address 2 which you don't own.
changeX((int*) k);
}
What you need is:
changeX(&k);
Now this is changing the value of a variable by passing it by address. Now such a thing is not possible in Java which always uses pass by value. But you can get similar effect by enclosing the int variable inside an Integer object or an integer array (also an object) and pass the object by value.
Simply put Java has no equivalent to a pointer to a basic type - in order to achieve this you need a reference int type something like
class RefInt {
public int Value;
RefInt(int x) { Value=x; }
}
And you pass this in the same context and it works like so:
RefInt X=new RefInt(3)
ChangeX(X);
Obviously in this context simply changing the return value to type int and assigning it would be better but that doesn't solve your general problem.
Option1:
Put the int variable in a wrapper class. Pass that the method. In the method you can change the value in wrapper instance.
Option2:
Make changeX() return int and replace all changeX(k) with k = changeX(k).
I'm doing a task for a course in Java programming and I'm not sure how the following thing is working? The method below takes the value from an array and a integer. The integer should be added to the array and then be used outside the method in other methods and so on, but how could this work when the method has no return for the new content of the array? There is a void in the method? Have I missed something? Preciate some help? Is there something about pointers?
public static void makeTransaction(int[] trans, int amount);
Arrays in Java are objects. If you modify the trans array inside the method, the changes will be reflected outside of it1. Eg:
public static void modify(int[] arr)
{
arr[0] = 10;
}
public static void main(...)
{
int x = {1, 2, 3};
System.out.println(x[0]); // prints 1
modify(x);
System.out.println(x[0]); // now it prints 10
}
Note that native arrays can't be dynamically resized in Java. You will have to use something like ArrayList if you need to do that. Alternatively you can change the return type to int[] and return a new array with the new element "appended" to the old array:
public static int[] makeTransaction(int[] trans, int amount)
{
int[] new_trans = Arrays.copyOf(trans, trans.length + 1);
new_trans[trans.length] = amount;
return new_trans;
}
1 It is also worth noting that as objects, array references are passed by value, so the following code has no effect whatsoever outside of the method:
public void no_change(int[] arr)
{
arr = new int[arr.length];
}
You can't add anything to an array. Java arrays have a fixed length. So indeed, what you want to do is impossible. You might make the method return an int[] array, but it would be a whole new array, containing all the elements of the initial one + the amount passed as argument.
If you want to add something to an array-like structure, use an ArrayList<Integer>.
Do you have to keep the method signature as is?
Also, can you be a bit more specific. When you say "the integer should be added to the array", are you referring to the amount argument? If so, then how is that amount added? Do we place it somewhere in the array or is it placed at the end, thus extending the array's length?
As far as pointers go, Java's pointers are implicit, so if you don't have a strong enough knowledge of the language, then it might not be so clear to you. Anyways, I believe that Java methods usually will pass objects by reference, and primitives by value. But, even that isn't entirely true. If you were to assign your object argument to new object, when the method terminates, the variable that you passed to the method is the same after the method executed as it was before. But, if you were to change the argument's member attributes, then when the method terminated those attributes values will be the same as they were inside of the method.
Anyways, back to your question, I believe that will work because an array is an object. So, if you were to do the following:
public static void makeTransaction(int[] trans, int amount)
{
trans[0] = amount;
}
// static int i;
/**
* #param args
*/
public static void main(String[] args)
{
int[] trans = {0,1,3};
makeTransaction(trans, 10);
for(int i = 0; i<trans.length; i++)
{
System.out.println(trans[i]);
}
}
The output of the array will be:
10
1
3
But, watch this. What if I decided to implement makeTransaction like so:
public static void makeTransaction(int[] trans, int amount)
{
trans[0] = amount;
trans = new int[3];
}
What do you think that the output will be? Will it be set to all zero's or will be the same as it was before? The answer is that the output will be the same as it was before. This ties in to what I was saying earlier.
I might've assigned that pointer to a new object in memory, but your copy of the pointer inside of the main method remains the same. It still points to the same place in memory as it did before. When the makeTransaction method terminates, the new int[3] object that I created inside of it is available for garbage collection. The original array remains intact. So, when people say that Java passes objects by reference, it's really more like passing objects' references by value.
This question already has answers here:
How to write a basic swap function in Java [duplicate]
(19 answers)
Java method to swap primitives
(8 answers)
Closed 6 years ago.
Here is the question: write a method that swaps two variables. These two variables should be primitives. It doesn't need to be generic e.g. two int variables. Is there a way?!
While it is not possible to write a function that simply swaps two variables, it is possible to write a helper function that allows you to:
Swap two variables using only one statement
Without temporary variables in the caller's code
Without 'boxing' primitives
With a few overloads (one of them using generics), it works for any type
That's how you could do it:
int returnFirst(int x, int y) {
return x;
}
<T> T returnFirst(T x, T y) {
return x;
}
// other overloads as needed
int a = 8, b = 3;
a = returnFirst(b, b = a); // try reading this as a = b; b = a;
System.out.println("a: " + a + ", b: " + b); // prints a: 3, b: 8
This works because the Java language guarantees (Java Language Specification, Java SE 7 Edition, section 15.12.4.2) that all arguments are evaluated from left to right (unlike some other languages, where the order of evaluation is undefined), so the execution order is:
The original value of b is evaluated in order to be passed as the first argument to the function
The expression b = a is evaluated, and the result (the new value of b) is passed as the second argument to the function
The function executes, returning the original value of b and ignoring its new value
You assign the result to a
If returnFirst is too long, you can choose a shorter name to make code more compact (e.g. a = sw(b, b = a)).
Suppose you need to swap many variables of different types one after the other. By using returnFirst there's no need for intAux, objAux, etc. There's less risk of mistakenly using the wrong variable somewhere, because there are no extra variables (in the caller, at least).
Without using an array or objects, no, it is not possible to do it within a method.
Check out this JavaWorld article that explains it in detail:
http://www.javaworld.com/javaworld/javaqa/2000-05/03-qa-0526-pass.html
A swap of two primitives will never work because primitives are passed by value in Java. You can't even write a method to swap two objects for that matter.
Like #Thomas said, the only thing you could do is have your primitives contained within other objects/arrays and modify those.
One-liner for any primitive numbers:
a += (b - (b = a));
You can make a generic version of #marcus's swap method that swaps any number of objects of the same type:
<T> T swap(T... args) { // usage: z = swap(a, a=b, b=c, ... y=z);
return args[0];
}
b = swap(a, a=b);
z = swap(x, x=y, y=z);
In java5, the closest I can think of, which may help you, is :
The AtomicInteger class (and others) have getAndSet() atomic methods ..
To write a swap method that swaps primitives you'd have to have the concept of "out" variables, i.e. variables whose values are passed up to the calling context. C# has those but you must still specify that they're out variables.
This function will swap two ints
Integer[] swap(int a, int b){
return new Integer[]{b,a};
}
Here's a method that swaps two primitive variables
private void swap(){
int a = 1;
int b = 2;
int temp = a;
a = b;
b = temp;
}
It might not be of much use though ;)
Ok seriously, it could be done if the variables are class level:
public class MyClass{
// excuse horrible coding practice of public mutable fields
public int a = 1;
public int b = 2;
public void swap(){
int temp = a;
a = b;
b = temp;
}
}
Again though, I fail to see what the use of this could be
I have read the above answers seeking an explanation as to why it is said that a swapping program cannot be written in java in the way it is written in c++.
I did the following way
program screenshot
As Thomas Owens said. You could probably do it in C by passing variables by &reference, but afaik not in Java without using objects.
Yes it is possible to swap two variable using a method.
But you should declare that method with empty parentheses and then call it by
reference(empty parentheses) .
Here is an example that illustrates swapping of two variable using a method.
public class Swapping
{
static String A="Apple";
static String B="Bat";
public static void swap()
{
String k;
k=A;
A=B;
B=k;
}
public static void main(String[] args)
{
System.out.println("Before swapping");
System.out.println("A= "+A);
System.out.println("B= "+B);
swap();
System.out.println("After swapping");
System.out.println("A= "+A);
System.out.println("B= "+B);
}
}
By compiling the above code the output comes as follows:
Before swapping
A= Apple
B= Bat
After swapping
A= Bat
B= Apple
//In case of call by reference original value is changed if we made changes in the called method
public class Swap
{
public static void main (String[]args)
{
int y = 5;
int x = 4;
int c;
System.out.println("y = "+y);
System.out.println("x = "+x);
c=x; //c = 4
x=y; //x = 5;
y=c;
System.out.println("\n");
System.out.println("y= "+y);
System.out.println("x= "+x);
}
}