import java.util.ArrayList;
public class bugs
{
public ArrayList<Integer> elements1;
public ArrayList<Integer> elements2;
public bugs(ArrayList<Integer> args)
{
elements1 = args;
elements2 = args;
}
public void change(int index, int value)
{
elements1.set(index, value);
}
public void reset()
{
elements1 = elements2;
}
public static void main(String[] a)
{
ArrayList<Integer> stuff = new ArrayList<Integer>();
stuff.add(1);
stuff.add(1);
stuff.add(1);
stuff.add(1);
bugs b = new bugs(stuff);
b.change(2, 999);
b.reset();
System.out.println(b.elements2);
}
}
This outputs:
[1, 1, 999, 1]
The second arraylist elements2 is there to reset the arraylist elements1 to its original position. However, for some reason elements1 is being copied to elements2, printing
[1, 1, 999, 1]
and not
[1, 1, 1, 1]
You are passing the same ArrayList reference to both variables.
What you meant to do is:
public bugs(ArrayList<Integer> args)
{
elements1 = new ArrayList<Integer>(args);
elements2 = new ArrayList<Integer>(args);
}
EDIT:
Note that this is only a temporary fix. Calling reset() will pass the reference of elements2 to elements1 and then you have the same situation. If you create a new arraylist and you pass another list as argument, you create a new reference with the same contents. This means you must also adjust your reset() method to create a new list and pass elements2 as argument.
In java you can pass by reference or by value. If you are using primitive data types, you are passing by value. So:
public void method(int num)
{
int num1 = num;
int num2 = num;
}
This method pass num value to num1 and num2 primitive data types. If you add something to num1 it will not change num2 to the same value. But if you are using non primitive data types like ArrayList:
public bugs(ArrayList<Integer> args)
{
elements1 = args;
elements2 = args;
}
You should expect that change in elements1 array will change elements2 array also. In this example you are passing the same ArrayList reference to both variables.
The solution for your problem is create copy of your arrays:
public bugs(ArrayList<Integer> args)
{
elements1 = new ArrayList<>(args);
elements2 = new ArrayList<>(args);
}
public void reset()
{
elements1 = new ArrayList<>(elements2);
}
Related
I hava a question about array initialization in java.
The code is as below:
public class Sentence {
int size;
int[] words=new int[size];
public Sentence(int size) {
this.size=size;
}
public static void main(String[] args) {
Sentence falseOne = new Sentence(6);
falseOne.words[0] = new int[6];
}
}
The problem shows: Type provided "int[]", but required "int"
Could anyone tell me where is wrong?
The field words for an object of class Sentence is of type int[] i.e. it is an array whose elements must be of integer type. In the second line within the main function, you are trying to initialize the first element of the words array with an integer array, instead of an integer.
Also, you should also create the array itself within the constructor.
The code should look like this:
public class Sentence {
int size;
int[] words;
public Sentence(int size) {
this.size = size;
this.words = new int[size];
}
public static void main(String[] args) {
Sentence falseOne = new Sentence(6);
falseOne.words[0] = 7; //just picked an arbitrary integer to demonstrate what should be initialized
}
}
I am working on a problem to find which all combinations of integer in a given list can sum up to a given number.
public class SumProblem {
/*
* Input 2-2-3-7
* Output 2+2+3 and 7
*/
public static ArrayList<ArrayList<Integer>> find(ArrayList<Integer> input, int requiredSum) {
ArrayList<ArrayList<Integer>> result = new ArrayList<>();
find(result, requiredSum, 0, new ArrayList<>(), 0, input);
return result;
}
public static void find(ArrayList<ArrayList<Integer>> result , int requiredSum , int currentSum, ArrayList<Integer> partialResult, int i, ArrayList<Integer> input) {
if (currentSum == requiredSum ) {
ArrayList<Integer> temp = new ArrayList<>();
temp = (ArrayList<Integer>) partialResult.clone();
result.add(temp);
return;
}
if (i >= input.size()) {
return;
}
find(result, requiredSum, currentSum , partialResult, i +1, input );
partialResult.add(input.get(i));
find(result, requiredSum, currentSum + input.get(i) , partialResult, i +1, input );
}
public static void main(String[] args) {
ArrayList<Integer> input = new ArrayList<>();
input.add(2);
input.add(1);
input.add(3);
ArrayList<ArrayList<Integer>> output = find(input, 3);
System.out.println(output.toString());
}
}
I have written code below.
I am facing one problem. In the below line of code, it is adding up all the numbers i traverse even if i create new ArrayList object and assign it to partialResult.
partialResult.add(input.get(i));
Could anyone suggest the solution ?
You have two recursive calls in this dynamic programming solution to the problem. One is supposed to not include the current value in the result, the other does.
You need to make a defensive copy of partialResult, otherwise both recursive calls are going to have a reference to the same list. A list is a mutable object. If both calls get a reference to the same list object, then when you add something to it anywhere, both of them will see the modified list.
The easiest way to make a defensive copy of a list is just to write:
new ArrayList<>(partialResult)
Here is a working version of the program:
import java.util.*;
public class SumProblem {
public static List<List<Integer>> find(List<Integer> input, int requiredSum) {
List<List<Integer>> result = new ArrayList<>();
find(result, requiredSum, 0, new ArrayList<>(), 0, input);
return result;
}
public static void find(List<List<Integer>> result, int requiredSum, int currentSum,
List<Integer> partialResult, int i, List<Integer> input) {
if (currentSum == requiredSum) {
result.add(new ArrayList<>(partialResult)); // add a copy of the list
return;
}
if (i >= input.size()) {
return;
}
// make defensive copies in the recursive calls
find(result, requiredSum, currentSum, new ArrayList<>(partialResult), i + 1, input);
partialResult.add(input.get(i));
find(result, requiredSum, currentSum + input.get(i), new ArrayList<>(partialResult), i + 1, input);
}
public static void main(String[] args) {
List<Integer> input = List.of(2, 8, 2, 3, 4);
List<List<Integer>> output = find(input, 7);
System.out.println(output);
}
}
Output:
[[3, 4], [2, 2, 3]]
I've made a few other changes:
Use List<Integer> and List<List<Integer>> as the types (code to the interface)
Use List.of() to create the input list (added in Java 9)
Don't call toString() on objects passed to println — it's unneeded
import java.util.*;
public class ArrayList5 {
static int max(ArrayList list) { // to be completed
if (list.size() == 0) {
return 0;
}
else
{
int first = (Integer) list.get(0);
list.remove(0);
if (first > max(new ArrayList(list)))
{
return first;
}
else
{
return max(list);
}
}
}
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList();
Collections.addAll(list, 4, 5, 3, 2, 3, 1, 3);
// int t=Console.readInt("Enter Target:");
int res1 = max(new ArrayList(list));
System.out.println("max=" + res1);
}
}
I don't understand why the max(new ArrayList(list))) part is required. Why does it have to create a new one and why can't it continue to work with the one list?
Also why doesn't it get caught in a loop (it's recursion so it will keep sending up a new list so I don't understand why 'first' isn't going to be 4 every time)?
Actually, there is a lot of superfluous code that is not required and make the code cumbersome/more difficult to read/understand.
You can simplify the code a lot and get rid of any reference to ArrayList which are not really necessary and by using proper generic at the right places, make the code actually readable.
You don't need to cast or create list all over the place.
public class ArrayList5 {
static int max(final List<Integer> list) {
if(list.isEmpty()) return 0;
final int head = list.get(0);
final List<Integer> tail = list.subList(1, list.size());
return (head > max(tail)? head:max(tail));
}
public static void main(final String... args) {
final int res1 = max(Arrays.asList(4, 5, 3, 2, 3, 1, 3));
System.out.printf("max=%d", res1);
}
}
You should try this:
static int max(ArrayList<Integer> list) {...}
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList();
Collections.addAll(list, 4, 5, 3, 2, 3, 1, 3);
// int t=Console.readInt("Enter Target:");
int res1 = max(new ArrayList(list));
System.out.println("max=" + res1);
}
The compiler is probably throws a warning because you don't declare the type of the ArrayList.
I need to create class that has a setter to assign values to an array, then in the main method take command line arguments and use the method to put that in an array. I have no clue how to do this. Any help would be appreciated.
import java.util.*;
public class Number{
private double [] number = new double[3];
private double value ;
private int i;
public double[] getNumber() {
return sweet;
}
public void printNumber() {
System.out.println("Array " + Arrays.toString(number));
}
public double getValue(int i) {
return this.i;
}
public void setMethod(int i, double value) {
this.value = value;
this.i = i;
}
public class Score {
public static void main (String [] args) {
Number score = new Number();
// code to get values from keyboard into the array
edit: Thank you for your help I managed to create the new array. Now I need to be able to change the array value. In my setMethod I am guessing I need to change it to something like this..,
public void setMethod(int i, double value { //
for ( i = 0; i < this.array.length; i ++){
this.array[this.i] =this. value;
}
this.mark = mark;
this.pos = pos;
}
If you look at main() method's list of arguments, you'll see String[] args - command line arguments are passed to the main() method as arguments. You can simply read them using a for loop:
String[] yourNewArray = new String[args.length]:
for(int i = 0; i< args.length; i++) {
yourNewArray[i] = args[i];
}
Now in yourNewArray you have stored command line arguments.
It is worth to mention that yourNewArray doesn't need to be an array containg Strings. Arguments passed as command line arguments can be parsed and used as, for example integers, doubles and other types of values.
Now, as you edited your question and have new thing to figure out, I will show you an example, how you could implement method to assign new array to an existing one and another method to change single value in this array:
import java.util.*;
// This is your class - there is String[] arr - you want to be able to change whole array or its single value:
class MyClass {
String[] arr;
// To change whole array:
public void setMethod(String[] array) {
this.arr = array;
}
// To change only one value in array:
public void changeSingleValue(int index, String value) {
arr[index] = value;
}
}
public class Test {
public static void main(String[] args) {
String[] arrayFromArgs = new String[args.length];
for(int i = 0; i < args.length; i++) {
arrayFromArgs[i] = args[i];
}
MyClass obj = new MyClass();
// In this method you assign array storing command line arguments to the array in MyClass:
obj.setMethod(arrayFromArgs);
System.out.println("obj.arr: " + Arrays.toString(obj.arr));
// Here is an example of assigning another array to obj.arr:
String[] anotherArray = { "A", "B", "C", "D"};
obj.setMethod(anotherArray);
System.out.println("obj.arr: " + Arrays.toString(obj.arr));
// Here is another way to assign new values to obj.arr:
obj.setMethod(new String[]{"x", "y", "z"});
System.out.println("obj.arr: " + Arrays.toString(obj.arr));
// Simple example how to change single value in obj.arr by passing the index where and value that needs to be changed:
obj.changeSingleValue(1, "Changed");
System.out.println("obj.arr: " + Arrays.toString(obj.arr));
}
}
And the output of the above program:
obj.arr: [] // in this array you will see values passed as the command line arguments
obj.arr: [A, B, C, D]
obj.arr: [x, y, z]
obj.arr: [x, Changed, z]
Try something like the following code to copy your array:
public static void main (String [] args) {
// code to get values from keyboard into the array
String[] myArgs = new String[args.length];
for (int i = 0; i < args.length; i++) {
myArgs[i] = args[i];
}
// ...
}
public class test{
public static void main(String args[]){
int val = 10;
System.out.println(val);
Obj obj = new Obj();
obj.def(val);
System.out.println(val)
}
}
public class OBJ{
public void def(int val){
val = 1;
}
}
that result is same (10 , 10) however..
public class test{
public static void main(String args[]){
double val[] = {0, 1, 2, 3, 4, 5};
Obj obj = new Obj();
for(int i = 0; i < val.length; i++){
System.out.println(val[i];
}
obj.def(val);
for(int i = 0; i < val.length; i++){
System.out.println(val[i];
}
}
}
public class OBJ{
public void def(double[] val){
for(int i = 0; i < val.length; i++){
val[i] = 1;
}
}
that is different, first print is 0 ~ 5, however, second print is 1 , 1, 1....
I don't know what is different,
in java, Array ( it mean likes int []..) use address?? like pointer in C?
P.S : Sorry for indentation.. above code write in web,
In java primitives, like the int are directly passed by value. Object, which arrays belong to aswell, are passed by value aswell, just that in this case the reference is passed as value. This means that you are working on the same instance of the array in your case.
As you can see in your example passing the int[] and changing the values in it are also affecting the original int[] that was passed to it. The true meaning of what is written above, that the reference is passed as value is that changing the reference of the object wont reflect in a change in the original value.
Here is a tiny example with comments demonstrating this.
public class TestObj {
private int val;
public TestObj(int value) {
this.val = value;
}
public static void main(String[] args) {
int value = 1;
int [] values = {1,2,3,4};
TestObj obj = new TestObj(15);
System.out.print("Print single int: ");
print(value);
System.out.println("Print int array:");
print(values);
System.out.print("Print TestObj val: ");
print(obj);
System.out.print("Changing single int value: ");
changeValue(value); // no effect
print(value);
System.out.println("Changing array int values: ");
changeValues(values); // effected
print(values);
System.out.println("Changing array value of reference: ");
changeRefValues(values); // no effect
print(values);
//
System.out.println("Changing val of TestObj");
changeVal(obj); // effected
print(obj);
System.out.println("Changing TestObj value of reference");
changeRef(obj); // not effected
print(obj);
}
static void changeValue(int value){
value *= 2; // Primitives are directly passed as value, so this wont effect the passed value.
}
static void changeValues(int[] values){
for(int i = 0;i<values.length;++i) {
values[i] *= 2; //You are working on the value of the reference that is passed. The passed int[] is effected
}
}
static void changeRefValues(int[] values){
values = new int[]{0,0,0,0}; // you change the value of the reference that is passed. The passed int[] is not effected
}
static void changeVal(TestObj obj) {
obj.val *= 2; // You are working on the value of the reference that is passed. The passed TestObj is effected
}
static void changeRef(TestObj obj) {
obj = new TestObj(30); // You change the reference, but since it is passed as value it has no effect on the passed TestObj
}
// Only used to print values from here
static void print(int[] values) {
for (int i : values) {
print(i);
}
}
static void print(int i) {
System.out.println(i);
}
static void print(TestObj obj) {
System.out.println(obj.val);
}
}
output :/
Print single int: 1
Print int array:
1
2
3
4
Print TestObj val: 15
Changing single int value: 1
Changing array int values:
2
4
6
8
Changing array value of reference:
2
4
6
8
Changing val of TestObj
30
Changing TestObj value of reference
30
The answere is quite simple looking at the first code snippet:
public class test{
public static void main(String args[]){
int val = 10; //variable var in main method
System.out.println(val); // prints var of main method
Obj obj = new Obj();
obj.def(val);
System.out.println(val) // prints var of main method
}
}
public class OBJ{
public void def(int val){
val = 1; // variable val in OBJ method
}
}
As you might see. both variables are called "var" but only one is printed out. The var variable in your OBJ method is never used.
now the other Case:
public class test{
public static void main(String args[]){
double val[] = {0, 1, 2, 3, 4, 5}; //array is an object, variable var is a pointer to the location of that object in your heap
Obj obj = new Obj();
for(int i = 0; i < val.length; i++){
System.out.println(val[i]; // you print out every number located at the space in your heap your pointer is pointing at
}
obj.def(val);
for(int i = 0; i < val.length; i++){
System.out.println(val[i]; //prints out the overwritten values
}
}
}
public class OBJ{
public void def(double[] val){ //you give the method the pointer to the location of your numbers in heap
for(int i = 0; i < val.length; i++
val = 1; //you have the exact pointer to the exact objects in your heap therefore you overwrite them
}
}
Now to this part. Your var variable is a pointer to your var[] object in your heap (yeah arrays are objects). You give your def method the pointer to your object. Therefore the object can be accessed and overwritten.
To put it in a nutshell. In your first snippet you create two int variables with no connection to each other. In your second snipped you ceate an object and a variable that is pointing to it. In that case the object can be accessed via the pointer. You could also do something like this:
int[] sameArray = var;
In this case "sameArray" would NOT be another object, but a pointer to your var[] object.
I am sorry for my terrible english, I'll correct it as soon as possible