This method should invert the numbers in the ArrayList [duplicate] - java

This question already has answers here:
Java ArrayList copy
(10 answers)
Closed 4 years ago.
import java.util.*;
public class Metodo {
public static void main(String[] args) {
ArrayList<Integer> a = new ArrayList();
a.add(1);
a.add(2);
a.add(3);
a.add(4);
a.add(5);
Metodo.inverte(a);
for(int i=0; i<a.size(); i++) {
System.out.println(a.get(i));
}
}
public static void inverte(ArrayList<Integer> a) {
ArrayList<Integer> other = new ArrayList();
other = a;
for(int i=0; i<a.size(); i++) {
a.set(i, other.get(other.size()-i-1));
}
}
}
This method should ivert the numbers in the ArrayList so it should print "5 4 3 2 1" but it prints "5 4 3 4 5" instead. Why?

other = a;
does not create a copy of the original List.
Both a and other reference the same List object, so when you call a.set(0,other.get(other.size()-1), you lose the original value of other.get(0).
You should use:
ArrayList<Integer> other = new ArrayList<>(a);
to create a copy of the original List and remove other = a;

Eran already answered this question, but a simple note here. that you can reverse ArrayList using:
Collections.reverse(arrayList)

You can add the items of a into other in the reverse order and return the result:
public static ArrayList<Integer> inverte(ArrayList<Integer> a) {
ArrayList<Integer> other = new ArrayList<>();
for(int i = a.size() - 1; i >=0 ; i--) {
other.add(a.get(i));
}
return other;
}
So you do:
a = Metodo.inverte(a);

As you can see in answers made, you can learn two things about your programing language:
What is the difference between a copy and a reference? See #Eran's answer
If you change the order of the items in a list when you make a loop on it, you will encounter problems.
How standard libraries and built-in types can help you? See #Mahmoud Hanafy's answer
You need to spend time to know what the language and its ecosystem can afford to you. For instance, it is very important you understand that reverse a collection is something very common, and on every new line you have to ask you: how other developers handle this.

Related

int[] vs ArrayList<>() in memoization, dynamic programming in Java

I recently watched a dynamic programming tutorial on Youtube explaining dynamic programming but the Tutor solved problems in JavaScript. I, on the other hand, use Java for data structures and algorithms. While implementing dynamic programming to solve a question. I discovered that I got the solution to the problem when using int[] but had wrong answer when using ArrayList<Integer> because somehow, the ArrayList already stored in the HashMap was being modified internally.
Question:
Write a function bestSum(targetSum, numbers) that takes in a targetSum and an array of numbers as arguments and returns an array containing the shortest combination of numbers that add up to exactly the target sum.
Example:
bestSum(7,new int[]{2,1,3}) => [3,3,1] //other possibilities but not answer:[2,2,2,1], [1,1,1,1,1,1,1], [2,2,1,1,1], etc
bestSum(100,new int[]{2,5,25}) => [25,25,25,25]
Code using int[]:
public class Persist {
public static HashMap<Integer,int[]> memo = new HashMap<>();
public static int[] bestSum(int n, int[] arr){
if(memo.containsKey(n)){
//System.out.printf("From memo: %d->"+ Arrays.toString(memo.get(n)) +"%n",n);
return memo.get(n);
}
if(n==0)return new int[0];
if(n<0)return null;
int[] minn = null;
for(int i = 0;i<arr.length;i++){
//recursion
var temp = bestSum(n-arr[i],arr);
if(temp!=null){
// ttemp is used to add arr[i] to the initial arr <<temp>>
int[] ttemp = new int[temp.length+1];
System.arraycopy(temp,0,ttemp,0,temp.length);
ttemp[temp.length] = arr[i];
temp = ttemp;
if(minn==null||temp.length<minn.length){
minn = temp;
}
}
}
//System.out.println(n+": "+minn);
memo.put(n,minn);
//System.out.println(memo.get(n));
return minn;
}
public static void main(String[] args){
System.out.println(Arrays.toString(bestSum(7, new int[]{2,1,3})));
}
}
Code using ArrayList<Integer> :
public class Persist {
public static HashMap<Integer,ArrayList<Integer>> memo = new HashMap<>();
public static ArrayList<Integer> bestSum(int n, int[] arr){
if(memo.containsKey(n)){
//System.out.printf("From memo: %d->"+ memo.get(n)+"%n",n);
return memo.get(n);
}
if(n==0)return new ArrayList<>();
if(n<0)return null;
ArrayList<Integer> minn = null;
for(int i = 0;i<arr.length;i++){
var temp = bestSum(n-arr[i],arr);
if(temp!=null){
temp.add(arr[i]);
if(minn==null||temp.size()<minn.size()){
minn = temp;
}
}
}
//System.out.println(n+": "+minn);
memo.put(n,minn);
//System.out.println(memo.get(n));
return minn;
}
public static void main(String[] args){
System.out.println(bestSum(7,new int[]{2,1,3}));
}
}
The only differences between the two code snippets is the use of int[] and ArrayList<Integer> respectively, but one works and the other doesn't. I will like to know why, thanks.
Link to Youtube explanation of bestSum()
It's easy to get caught up with memoization and dynamic programming and forget that about pass by reference and pass by value. The key difference here to remember is that ArrayList is pass by reference.
If you debug and look at your hashmap memo, you see that the sizes of the int[] only reaches up to 3, whereas in the arraylist hashmap most of the values has a size of 7
I had a similar problem: casting does not work on nested list object type and returns empty lists (List<List<Integer>>)

Putting Strings in Lexicographic Order

This is my assignment, and I am not sure how to proceed. The output only prints my first four teachers, and I don't know why it isn't printing my last three teachers as well. Thanks!
Create an ArrayList called teachers. Fill the ArrayList with your teacher’s LAST NAMES ONLY in the order that you see them during the day (Period 1: Jensen, Period 2: Houge, Period 3: …, etc.) You only need to put the teacher’s last name in the ArrayList, so it would print [Jensen, Houge, etc…].) Print the ArrayList using a print method.
Write a method that takes your teachers ArrayList, and from it makes a new ArrayList called ordered, whererin your teacher’s names are now in lexicographic order. Print the resulting ArrayList. (DO NOT CHANGE YOUR ORIGINAL ARRAYLIST, MAKE A NEW ONE!)
import java.util.ArrayList;
public class LexicographicOrdering
{
public static void main (String [] args){
ArrayList<String> teachers = new ArrayList<String>();
teachers.add("Turnbow");
teachers.add("Dyvig");
teachers.add("Williams");
teachers.add("Houge");
teachers.add("Allaire");
teachers.add("Violette");
teachers.add("Dorgan");
System.out.println(teachers);
order(teachers);
}
public static void order(ArrayList<String> teachers ){
ArrayList<String> ordered = new ArrayList<String>();
for(int i = 0; i < teachers.size(); i++){
String str = teachers.get(i);
for(int j = 1; j < teachers.size(); j++){
if(str.compareTo(teachers.get(j)) > 0){
str = teachers.get(j);
}
}
ordered.add(str);
teachers.remove(str);
}
System.out.print(ordered);
}
}
So the issue here is with your static order method. As Karl suggests above, you want to break the method into two separate parts. The first will create an ArrayList named 'ordered' and then fill it with the data contained in the 'teachers' array.
ArrayList<String> ordered = new ArrayList(); //the second <String> is not required
for(int i = 0; i < teachers.size(); i++){
String str = teachers.get(i);
ordered.add(str);
}
The next objective is to sort the array in alphabetical order, which can be achieved using the Collections.sort(ArrayList) method which is contained in the java.util package.
Collections.sort(ordered);
And now you need to print the ArrayList.
System.out.println(ordered);
As this is a homework assignment, I would recommend reading up on the Collections.sort() method, along with an example of it. A quick google search pulled up the following website: http://beginnersbook.com/2013/12/how-to-sort-arraylist-in-java/
Also, I would recommend reading the API for the Collection class. https://docs.oracle.com/javase/8/docs/api/java/util/Collections.html#sort-java.util.List-
Edit:
At a quick glance, I would assume the reason that your string is cutting out the last 3 names is due to the fact that you are removing items from the list as you are looking at each position in the list. Essentially, you are looking at every other item in the list because of this.
So I figured it out! I only needed to set the first for loop back to zero. Here is the new code:
import java.util.ArrayList;
public class LexicographicOrdering
{
public static void main (String [] args){
ArrayList<String> teachers = new ArrayList<String>();
teachers.add("Turnbow");
teachers.add("Dyvig");
teachers.add("Williams");
teachers.add("Houge");
teachers.add("Allaire");
teachers.add("Violette");
teachers.add("Dorgan");
System.out.println(teachers);
order(teachers);
}
public static void order(ArrayList<String> teachers ){
ArrayList<String> ordered = new ArrayList<String>();
for(int i = 0; i < teachers.size(); i++){
String str = teachers.get(i);
for(int j = 1; j < teachers.size(); j++){
if(str.compareTo(teachers.get(j)) > 0){
str = teachers.get(j);
}
}
i =- 1;
ordered.add(str);
teachers.remove(str);
}
System.out.print(ordered);
}
}

ArrayList Collection API

I have an ArrayList (listOfNumbers) which contains a number. I have written a Predicate (guava) which gives me a list of EVEN numbers (evenNumberList) from listOfNumbers. I now want all the ODD numbers copied to a new ArrayList. Wondering if there is a quick way of doing this?
Inside your class, have two instance variables: ArrayList<Integer> oddNumbers and ArrayList<Integer> evenNumbers. Then, your method should look like the following:
public void setEvenOdd(ArrayList<Integer> listOfNumbers) {
ArrayList<Integer> even = new ArrayList<Integer>();
for(Integer i : listOfNumbers) {
if(i % 2 == 0) even.add(listOfNumbers.remove(i));
}
this.evenNumbers = even;
this.oddNumbers = listOfNumbers; // since we removed all even numbers
}
Is this what you were asking for?

Can you create an array of linked lists in Java?

Is it possible to create an array of linked lists? Or an arraylist of linked lists? I've been searching everywhere and seem to be getting contradicting answers. I've seen "no" answers that state that it can't be done because you can't make an array of things that can be dereferenced. I've seen "yes" answers that state it can be done and they end there.
Thanks in advance.
If I understand you right, you basicly want to make a 2D Array, but with the second half being a linked list.
import java.util.ArrayList;
import java.util.LinkedList;
public class Test
{
public static void main(String[] args)
{
LinkedList one = new LinkedList();
LinkedList two = new LinkedList();
LinkedList three = new LinkedList();
ArrayList<LinkedList> array = new ArrayList<LinkedList>();
array.add(one);
array.add(two);
array.add(three);
// .. do stuff
}
}
Java doesn't care what the Objects in Arrays or Lists are, so there's nothing against putting another Array or List in.
The worst way: creating an array of raw List:
List[] lstString = new List[10];
for(int i = 0; i < lstString.length; i++) {
lstString[i] = new LinkedList<String>();
lstString[i].add(Integer.toString(i));
}
for(int i = 0; i < lstString.length; i++) {
for(Iterator it = lstString[i].iterator(); it.hasNext(); ) {
System.out.println(it.next());
}
}
A slightly better way: use a wrapper class that holds your List and create an array of it:
public class Holder {
List list = new LinkedList();
}
//...
Holder[] holders = new Holder[10];
for(int i = 0; i < holders; i++) {
holders[i] = new Holder();
}
Better approach: use a List<List<Data>>:
List<List<Data>> lstOfListOfData = new ArrayList<List<Data>>();
for(int i = 0; i < 10; i++) {
lstOfListOfData.add(new LinkedList<Data>());
}
I've seen "no" answers that state that it can't be done because you can't make an array of things that can be dereferenced
Doesn't matter if the array's member value is null, if you still can "access" that member, and instantiate it, it's not dereferenced.
So yes, you can.

The best way to transform int[] to List<Integer> in Java? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How to create ArrayList (ArrayList<T>) from array (T[]) in Java
How to implement this method:
List<Integer> toList(int[] integers) {
???
//return Arrays.asList(integers); doesn't work
}
There's probably a built-in method to do it somewhere* (as you note, Arrays.asList won't work as it expects an Integer[] rather than an int[]).
I don't know the Java libraries well enough to tell you where that is. But writing your own is quite simple:
public static List<Integer> createList(int[] array) {
List<Integer> list = new ArrayList<Integer>(array.length);
for (int i = 0; i < array.length; ++i) {
list.add(array[i]);
}
return list;
}
Obviously one downside of this is that you can't do it generically. You'll have to write a separate createList method for each autoboxed primitive type you want.
*And if there isn't, I really wonder why not.
Use commons-lang3 org.apache.commons.lang3.ArrayUtils.toObject(<yout int array>) and then java.util.Arrays.asList(<>)
ArrayUtils.toObject() will copy the array, and Array.asList() will simply create list that is backed by new array.
int[] a = {1, 2, 3};
List<Integer> aI = Arrays.asList(ArrayUtils.toObject(a));
EDIT: This wont work if you want to add() new elements (resize) though the list interface, if you want to be able to add new elements, you can use new ArrayList(), but this will create one more copy.
List<Integer> asList(final int[] integers) {
return new AbstractList<Integer>() {
public Integer get(int index) {
return integers[index];
}
public int size() {
return integers.length;
}
};
}
List<Integer> toList(int[] integers) {
// Initialize result's size to length of the incoming array
// this way it will not require reallocations
ArrayList<Integer> result = new ArrayList<Integer>( integers.length );
for ( int cur: integers )
{
result.add( Integer.valueOf( cur ) );
}
return result;
}
I do not think there is a quick way to do it unfortunately. I believe you will have to iterate the array and add it one by one.
import java.util.Arrays;
import java.util.ArrayList;
import java.util.List;
public class Listing {
public static void main(String[] args) {
int[] integers = {1,2,3,4};
java.util.List<Integer> list = new ArrayList<Integer>();
for (int i=0; i< integers.length; i++)
{
list.add(integers[i]);
}
System.out.println(list);
}
}
Tested and working as expected!

Categories