Problems with returning ArrayList - java

I added Strings "Hello", "Cat", "Dog" into the arraylist called values passed it to the method doubleIt() which should return a list of everything doubled, i.e.
"Hello", "Hello", "Cat", "Cat", "Dog", "Dog"
But all Im getting is []. What could I do wrong here ?
import java.util.*;
public class Addition
{
public static void main(String [] args)
{
List<String> values = new ArrayList<String>();
values.add("Hello");
values.add("Cat");
values.add("Dog");
values = doubleIt(values);
System.out.println(values);
}
public static List<String> doubleIt(List<String> values)
{
List<String> temp = new ArrayList<>();
for(int i = 0; i < temp.size(); i++)
{
temp.add(values.get(i*2));
}
return temp;
}
}

Your first mistake is here...
for(int i = 0; i < temp.size(); i++)
temp.size() will be 0 when it's called the first time, you really should be using a values, but this will cause an IndexOutOfBoundsException
So you could use something like...
for (int i = 0; i < values.size(); i++) {
temp.add(values.get(i));
temp.add(values.get(i));
}
instead

First change your for loop condition from
for(int i = 0; i < temp.size(); i++)
to
for(int i = 0; i < values.size(); i++)
and then add values 2 times each.

Your for loop in doubleIt() was looping up to the wrong list size. And you were trying to multiply a string by 2, instead of adding it twice.
public static List<String> doubleIt(List<String> values)
{
List<String> temp = new ArrayList<>();
for(int i = 0; i < values.size(); i++) // <-- you needed to loop up to the size of the values list, not the temp list
{
temp.add(values.get(i));
temp.add(values.get(i));
}
return temp;
}

Related

Why am I unable to create a new String Array inside a for loop to place output of array index?

I am coding a program to output common elements of an array. I've got it working, but not to the standard it should be. Currently I have a function getCommonElements that prints each string index of where the string arrays have a commonality, but I have to return an empty string. I want to only return that string (array3) as a list of all the common elements. Thank you.
--The commented out part is the part that I have working, but want to replace. Currently this runs and gives an out of bounds error and I understand why, just want to change that.--
public class GetCommonElement {
public static String[] getCommonElements(String[] array1, String[] array2){
String[] array3 = {""};
for(int i =0; i < array1.length; i++){
for(int j = 0; j < array2.length; j++){
if (array1[i] == array2[j]){
/*System.out.print(array1[i]);
System.out.printf("\n");*/
String temp = array1[i];
for(int k = 0; k < array2.length; k++){
array3[k] = temp;
}
}
}
}
return array3;
}
TLDR: How do I compare two arrays and output the common elements into the new array.
First of all, you should't be using the == operator to compare objects like String. String objects are cached for short ones, but in general there may be String objects that have the same content but doesn't have the same memory address, so == will give you a false. You should be using the String.equals(Object o) method, or the null safe java.util.Objects.equals(Object o1, Object o2).
In addition, you don't know how many items match in the two arrays, so you don't know the length of your array3 result before the execution of the method. I recomend you to use a Set, or if you want, a List object for the result.
The code of the method might be something like the following:
public static String[] getCommonElements(String[] array1, String[] array2) {
List<String> coincidences = new ArrayList<>(
Math.min(array1.length, array2.length)
);
for (int i = 0; i < array1.length; i++) {
for (int j = 0; j < array2.length; j++) {
if (Objects.equals(array1[i], array2[j])
&& !coincidences.contains(array1[i])) {
coincidences.add(array1[i]);
}
}
}
return coincidences.stream().toArray(String[]::new);
}
You can see here how to append an array. so you could start with an empty array String[] array3 = {}; and instead of array3[k] = temp; you would do something like
array3 = Arrays.copyOf(array3, array3.length + 1);
array3[array3.length - 1] =temp;
Alternatively you could count the matches then initialize an array of appropriate size. One problem I see with your code is that it will do strange things if multiples exist in each array. For example if the string "blah" existed twice in each array it would match 4 times. So for this reason I would probably do something like this which checks for redundancy:
public class matching{
public static String[] getCommonElements(String[] array1, String[] array2){
boolean[] matches = new boolean[array1.length];
boolean hasAMatch = false;
boolean isRedundant = false;
int nMatches = 0;
for(int i =0; i < array1.length; i++){
isRedundant = false;
for(int i2=0;i2<i;i2++){
if(array1[i]==array1[i2]){
isRedundant = true;
break;
}
}
if(!isRedundant){
hasAMatch = false;
for(int j=0; j < array2.length; j++){
if (array1[i] == array2[j]){
hasAMatch = true;
nMatches++;
break;
}
}
if(hasAMatch){
matches[i] = true;
}
}
}
String[] array3 = new String[nMatches];
nMatches = 0;
for(int i =0; i < array1.length; i++){
if(matches[i]){
array3[nMatches] = array1[i];
nMatches ++;
}
}
return(array3);
}
public static void main(String []args){
String[] a = {"blah","blah","didy","blah blah"};
String[] b = {"blah","ditty","blagh blah"};
String[] c = getCommonElements(a,b);
for(int i =0; i < c.length; i++){
System.out.println(c[i]);
}
}
}

Finding length of all values in an ArrayList

For a program I'm attempting to have a nested for loop repeat along the lines of this:
for(int i = 0;i < ArrayList.size();i++){
for(int x = 0;x <ArrayList.get(i).length();x++){
//stuff
}
}
Essentially I want to repeat a for loop for every character in every index of an ArrayList but this solution doesn't seem to work. Any help appreciated!
Edit: the arraylist will only contain strings in my case
Try using a For Each Loop such that:
int sumLength = 0;
ArrayList<String> r = new ArrayList<String>();
for(String s : r)
{
sumLength += s.length();
}
return sumLength;
That will give you the sum of all the lengths in your ArrayList
Updated code:
You can use java8 streams to tackle this issue and not to mention is is null-safe. Here is an example.
import java.util.ArrayList;
import java.util.List;
public class NestedList {
public static void main(String[] args) {
List<String> list1 = new ArrayList<>();
list1.add("JOHN");
list1.add("JACK");
list1.add("CYTHIA");
list1.add("DANNY");
list1.stream().forEach( str -> {
char x;
for (int i = 0; i < str.toCharArray().length; i++) {
x = str.charAt(i);
//do your struff
System.out.println(x);
}
});
}
}
The stream method by Java8 will handle the list where as you can use the toCharArray which will convert the string to arrays of character to handle each character.
You can try this this way,
List<String> arrayList = new ArrayList();
arrayList.add("strings1");
arrayList.add("strings2");
for(int i = 0;i < arrayList.size();i++){
for(int x = 0;x <arrayList.get(i).length();x++){
//stuff
}
}
all your logic is correct but there is mistake with the syntax,
you use Class name instead of object reference,
ie, change ArrayList to the ArrayList reference variable in your code.
(ArrayList.size() to list.size())
change
for(int i = 0;i < ArrayList.size();i++){
for(int x = 0;x <ArrayList.get(i).length();x++){
//stuff
}
}
to
ArrayList<String> list = new ArrayList<>();
list.add("apple");
list.add("mango");
list.add("orange");
for(int i = 0;i < list.size();i++){
for(int x = 0;x <list.get(i).length();x++){
//stuff
}
}

TestNG DataProvider - How to produce all permutations in a List

Supposed I have a list of string, I want a DataProvider to produce permutation of 2 of that list to use as 2 parameter in one of the test function. What I have so far is:
#DataProvider(name = "Permutation")
public static Object[][] permutations() {
List <String> permutations = getPermutationList();
Object[][] dataList = new Object[permutations.size()][permutations.size()];
for (int i = 0; i < permutations.size(); i++) {
dataList[i] = new Object[permutations.size()];
for (int j = 0; j < permutations.size(); j++) {
dataList[i][j] = permutations.get(i);
}
}
return dataList;
}
My DataProvider doesn't work as expected, every row is just null.
Any hint please? Thank you
The getPermutationList is the issue with your code. Ensure it's returning the data you are expecting. Below is the same code as above, only with a hardcoded array being initialized. When it runs, there is data in the dataList object.
public static Object[][] permutations() {
List <String> permutations = new ArrayList<String>(Arrays.asList("foo", "bar"));
Object[][] dataList = new Object[permutations.size()][permutations.size()];
for (int i = 0; i < permutations.size(); i++) {
dataList[i] = new Object[permutations.size()];
for (int j = 0; j < permutations.size(); j++) {
dataList[i][j] = permutations.get(i);
}
}
return dataList;
}

Adding Integers to ArrayList<Integer>

I have an ArrayList of LinkedLists (an array of linked lists). The LinkedLists contains integers (Integer).
private List<LinkedList> buckets;
buckets = new ArrayList<LinkedList>();
for (int i = 0; i < 10; i++) {
LinkedList<Integer> temp = new LinkedList<Integer>();
buckets.add(temp);
}
I later want to remove the items from the linked list (in the order they were added) and add them to an array list. When I try this:
ArrayList<Integer> sorted = new ArrayList<Integer>(unsorted.size());
for (int i = 0; i < buckets.size(); i++) {
for (int j = 0; j < buckets.get(i).size(); j++) {
sorted.add(buckets.get(j).removeLast());
// sorted.add((Integer)buckets.get(j).removeLast());
}
}
I get an error saying:
add(java.lang.Integer) in ArrayList cannot be applied to (java.lang.Object)
But when I cast it to an Integer (the commented out line), the array is full of null values. Anyone see what I am doing wrong?
Here is where I am adding items to bucket:
for (int i = 0; i < unsorted.size(); i++) {
int digit = (unsorted.get(i) / position) % 10;
buckets.get(digit).add(unsorted.get(i));
}
Note that sorted is an ArrayList<Integer>. When I trace it in debug mode, I can see that the LinkedLists have Integer objects with the correct values.
Screenshot of buckets contents:
Working Example:
class Ideone {
private static List<LinkedList<Integer>> buckets;
public static void main (String[] args) throws Exception {
ArrayList<Integer> arr = new ArrayList<Integer>();
arr.add(6);
arr.add(8);
arr.add(1);
arr.add(3);
arr.add(9);
System.out.println(arr);
arr = sort(arr);
System.out.println(arr);
}
public static ArrayList<Integer> sort(ArrayList<Integer> unsorted) {
buckets = new ArrayList<LinkedList<Integer>>();
for (int i = 0; i < 10; i++) {
LinkedList<Integer> temp = new LinkedList<Integer>();
buckets.add(temp);
}
ArrayList<Integer> sorted = new ArrayList<Integer>(unsorted.size());
for (int i = 0; i < unsorted.size(); i++) {
int digit = unsorted.get(i) % 10;
buckets.get(digit).add(unsorted.get(i));
}
for (int i = 0; i < buckets.size(); i++) {
for (int j = 0; j < buckets.get(i).size(); j++) {
sorted.add(buckets.get(j).poll());
// sorted.add((Integer)buckets.get(j).removeLast());
}
}
return sorted;
}
}
You are using the raw form of LinkedList here:
private List<LinkedList> buckets;
Because of this, removeLast will return Object, not Integer. Try
private List<LinkedList<Integer>> buckets;
and
buckets = new ArrayList<LinkedList<Integer>>();
Casting the return of removeLast to Integer was the pre-generics way of getting this to work. However, you never inserted any items into each LinkedList, so removeLast returns null. If you want something returned, first insert something into each LinkedList that gets inserted into buckets.
Casting to Integer would still work, but supplying Integer as the type argument to LinkedList is preferred, especially since you are using generics by supplying LinkedList as the type parameter to List already.
In your nested loop,
for (int i = 0; i < buckets.size(); i++) {
for (int j = 0; j < buckets.get(i).size(); j++) {
// ***** here *****
sorted.add(buckets.get(j).poll());
}
}
You look to be polling the wrong List.
Try changing
sorted.add(buckets.get(j).poll());
to:
sorted.add(buckets.get(i).poll());
Perhaps a cleaner more intuitive way to code this would be something like:
for (int i = 0; i < buckets.size(); i++) {
LinkedList<Integer> innerList = buckets.get(i);
for (int j = 0; j < innerList.size(); j++) {
sorted.add(innerList.poll());
}
}
Although this may not work if the innerList has multiple items. Why not instead remove items safely with an iterator?
for (int i = 0; i < buckets.size(); i++) {
LinkedList<Integer> innerList = buckets.get(i);
for (Iterator<Integer> iterator = innerList.iterator(); iterator.hasNext();) {
sorted.add(iterator.next());
iterator.remove(); // this guy is optional
}
}
Either that or simply use get(j)
for (int i = 0; i < buckets.size(); i++) {
LinkedList<Integer> innerList = buckets.get(i);
for (int j = 0; j < innerList.size(); j++) {
sorted.add(innerList.get(j));
}
}
Although this isn't efficient use of a LinkedList
The item that you inserted into the ArrayList "sorted" is the item you took from the link list LinkedList.
But you never actually add any item to it. You simply just created a LinkedList and added it to your bucket list.
You need to add something into the temp list.
for (int i = 0; i < 10; i++) {
LinkedList<Integer> temp = new LinkedList<Integer>();
// Add something to the temp LinkedList
buckets.add(temp);
}

compare two array of string and store the result in another array

I want to compare two arrays and store the difference in another array
For example the two arrays might be
String[] a1 = { "cat" , "dog" };
String[] a2 = { "cat" , "rabbit" };
The resultant array would be like this
{ "rabbit" }
I use this code, but it does not work
int n = 0;
for (int k = 0; k <= temp.length; k++)
{
for (int u = 0; u <= origenal.length; u++)
{
if (temp[k] != origenal[u] && origenal[u] != temp[k])
{
temp2[n] = temp[k];
System.out.println(temp[u]);
n++;
}
}
}
This should do the trick.
String[] result = new String[100];
Int k = 0;
Boolean test = true;
for(i=0; i < a1.length; i++){
for(j=0; j < a2.length; j++){
if(a2[i].equals(a1[i])) continue;
test = false
}
if(test == false) result[k++] = a1[i];
}
I think that this may be what you are looking for. Note that it will only add to the third 'array' if the value exist in second array but not in first. In your example only rabbit will be stored, not dog (even though dog does not exist in both). This example could possibly be shortened but I wanted to keep it like this so it is easier to see what is going on.
First import:
import java.util.ArrayList;
import java.util.List;
Then do the following to populate and analyze the arrays
String a1[] = new String[]{"cat" , "dog"}; // Initialize array1
String a2[] = new String[]{"cat" , "rabbit"}; // Initialize array2
List<String> tempList = new ArrayList<String>();
for(int i = 0; i < a2.length; i++)
{
boolean foundString = false; // To be able to track if the string was found in both arrays
for(int j = 0; j < a1.length; j++)
{
if(a1[j].equals(a2[i]))
{
foundString = true;
break; // If it exist in both arrays there is no need to look further
}
}
if(!foundString) // If the same is not found in both..
tempList.add(a2[i]); // .. add to temporary list
}
tempList will now contain 'rabbit' as according to the specification. If you necessary need it to be a third array you can convert it to that quite simply by doing the following:
String a3[] = tempList.toArray(new String[0]); // a3 will now contain rabbit
To print the content of either the List or Array do:
// Print the content of List tempList
for(int i = 0; i < tempList.size(); i++)
{
System.out.println(tempList.get(i));
}
// Print the content of Array a3
for(int i = 0; i < a3.length; i++)
{
System.out.println(a3[i]);
}

Categories