Say I have an arraylist a with the values:
a[0] = G
a[1] = B
a[2] = D
I was wondering, how can I create a new arraylist in java, that joins index values at random places and puts it into a new arraylist b
So like:
b[0] = GB
b[1] = D
or
b[0] = G
b[1] = BD
or
b[0] = GBD
The order of the values is kept the same, it's just the different combinations of the joins, and at different places over different amounts.
Something like (pseudocode)
newA = new ArrayList<String>();
for (b : a) {
if (Math.random() > 0.5) newA.add(b);
else newA.set(previous, newA.get(previous) + b);
}
Assuming you can get the "random position" yourself, my thought would be to use something like the following:
import org.apache.commons.lang.StringUtils;
public List<String> mergeAt(ArrayList<String> input, int offset) {
List<String> result = new ArrayList<String>();
result.add(StringUtils.join(input.subList(0, offset), '');
result.add(StringUtils.join(input.subList(offset, input.size()), '');
return result;
}
First merge element at index i with index j:
yourList.set(i, yourList.get(i) + yourList.get(j));
Then remove element at index j:
yourList.remove(j);
This satisfies all the conditions you listed above. you can adjust joinIndex and joinSize to whatever you want and it will start at the joinIndex position and concatenate joinSize characters.
Fixed the issue with the exceeding bounds. Now it will just concat as many characters at the end as exist.
import java.util.ArrayList;
import java.util.List;
public class TestJoiner
{
public static void main(String[] args){
List<String> list = new ArrayList<String>();
list.add("G");
list.add("B");
list.add("D");
list.add("L");
list.add("G");
list.add("A");
//Get Random Int
int joinIndex=3;
int joinSize=2;
//check join size, make sure it doesn't exceed bounds.
joinSize=(joinIndex+joinSize+1)>list.size()?list.size()-joinIndex-1:joinSize;
//join
for(int a=joinIndex;a<joinIndex+joinSize;a++){
list.set(joinIndex,list.get(joinIndex)+list.get(a+1));
}
//shift
for(int c=joinIndex+1;c<list.size()-joinSize;c++){
list.set(c,list.get(c+joinSize));
}
//Truncate
list=list.subList(0,list.size()-joinSize);
System.out.println(list);
}
}
badger. Here is task solution. Just use List<String> Shaker.shake(List<String>) method.
Shaker class:
import java.util.List;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Random;
public class Shaker {
public static List<String> shake(List<String> sourceList) {
Random random = new Random();
// We'll use cloned original list
LinkedList<String> itemsList = new LinkedList<String>(sourceList);
// Count how much items need shaking
int itemsToMerge = itemsList.size();
// New generated list
List<String> newList = new ArrayList<String>();
// Temporary values, used in cycle
int firstGroupItemIndex = 0;
while (0 < itemsToMerge) {
// Select random number of merged items
int groupLength = random.nextInt(itemsToMerge) + 1;
// Create inserted string value
StringBuilder insertedValue = new StringBuilder();
int lastGroupItemIndex = firstGroupItemIndex + groupLength;
for (int i = firstGroupItemIndex; i < lastGroupItemIndex; i++) {
insertedValue.append(itemsList.removeFirst());
}
// Add merged string value
newList.add(insertedValue.toString());
firstGroupItemIndex = lastGroupItemIndex;
itemsToMerge -= groupLength;
}
return newList;
}
}
And Test class:
import java.util.List;
import java.util.ArrayList;
public class Test {
public static void main(String[] args) {
List<String> originalList = new ArrayList<String>();
originalList.add("G");
originalList.add("B");
originalList.add("C");
originalList.add("L");
originalList.add("G");
originalList.add("A");
List<String> newList = Shaker.shake(originalList);
System.out.println("Original list: " + originalList);
System.out.println("Shaked list: " + newList);
}
}
Look at the result:
Original list: [G, B, C, L, G, A]
Shaked list: [GBC, LG, A]
If you have questions about the code, I'll answer you with pleasure.
You can always find solution sources at github.com.
Related
I want to change that List number to int so I can use it as part of an if statement
I tried almost every way I can
import java.util.*;
public class HelloWorld {
public static void main(String[] args) {
List number = new ArrayList();
number.add(100);
number.add(1000);
number.add(10000);
int[] changedNumber = number.stream();
int A = chagedNumber.get[2];
int B = chagedNumber.get[0];
if (A > B) {
System.out.println(number.get(2) + " is bigger than " + number.get(0));
} else {
System.out.println(number.get(2) + " is smaller than" + number.get(0));
}
}
}
Arrays nor streams have a get method.
Try only using the list index
List<Integer> number = new ArrayList<>();
number.add(100);
number.add(1000);
number.add(10000);
int a = number.get(2);
int b = number.get(0);
if (a > b) {
} else {
}
Note: You can also use Arrays.asList(10, 1000, 10000)
You can simply use:
List<Integer> number = new ArrayList<>();
Then, in your if statement:
if (number.get(2) > number.get(0)) { ...
Using List<Integer> will use autoboxing to convert from Integer to int automatically.
So the issue I'm having is after copying the 2d arraylist, changing the element from one 2d arraylist affects the other 2d arraylist. I want them to be completely separate in memory.
First example shows how it works correctly with 1d arraylists...
import java.util.ArrayList;
public class QuickTest {
public static void main(String[] args) {
ArrayList<Integer> firstList = new ArrayList<>();
ArrayList<Integer> secondList = new ArrayList<>();
Integer counter = 2;
for(int arrI = 0; arrI < 4; arrI++, counter+=2){
firstList.add(counter);
}
secondList = new ArrayList<>(firstList);
System.out.println("firstList.get(2) = " + firstList.get(2));
System.out.println("secondList.get(2) = " + secondList.get(2));
firstList.set(2, 7);
System.out.println("firstList.get(2) = " + firstList.get(2));
System.out.println("secondList.get(2) = " + secondList.get(2));
}
}
Expected output:
Notice how the element from the first arraylist is changed but not the second arraylist element is not changed. This is good and what we want.
Now to try and copy the 2d arraylists...
import java.util.ArrayList;
public class QuickTest {
public static void main(String[] args) {
ArrayList<ArrayList<Integer>> firstTwoDimList = new ArrayList<>();
ArrayList<ArrayList<Integer>> secondTwoDimList = new ArrayList<>();
firstTwoDimList.add(new ArrayList<Integer>());
firstTwoDimList.add(new ArrayList<Integer>());
firstTwoDimList.add(new ArrayList<Integer>());
Integer counter = 2;
for(int arrI = 0; arrI < firstTwoDimList.size(); arrI++, counter+=2){
firstTwoDimList.get(arrI).add(counter);
counter+=2;
firstTwoDimList.get(arrI).add(counter);
}
secondTwoDimList = new ArrayList<>(firstTwoDimList);
System.out.println("firstTwoDimList.get(1).get(0) = " + firstTwoDimList.get(1).get(0));
System.out.println("secondTwoDimList.get(1).get(0) = " + secondTwoDimList.get(1).get(0));
firstTwoDimList.get(1).set(0, 7);
System.out.println("firstTwoDimList.get(1).get(0) = " + firstTwoDimList.get(1).get(0));
System.out.println("secondTwoDimList.get(1).get(0) = " + secondTwoDimList.get(1).get(0));
}
}
Unexpected output:
Anyone have any idea what the reason for this is, and what the best solution would be?
This is what is happening in the 1D array list case, in terms of references:
This is what is happening in the 2D array list case:
This means that when you copy an array list using this:
new ArrayList<>(someOldArrayList)
the items themselves don't get copied, only a new array list object is created, referring to all the items in the old array list.
In the second case, you are only changing what array list 2's items are, but index 1 of first list and second list refers to the same array list 2.
To fix this, you need to copy the array lists inside first list and second list as well. One way to do this:
secondList = new ArrayList<>(firstList.stream().map(x -> new ArrayList<>(x)).collect(Collectors.toList()));
You should iterate through the size of the first dimension of the firstTwoDimArray and add new reference of each second dimension to the secondTwoDimArray. i.e.
for(int index = 0; index < firstTwoDimList.size(); index++) {
secondTwoDimList.add(new ArrayList<Integer>(firstTwoDimList.get(index)));
}
The difference between your first and second example is that in the second one you use get(). This get() returns a new variable, so you assign the integers to it and not to the original ArrayList.
If you want to assign a value:
firstTwoDimList.set(1, new ArrayList<Integer>(Arrays.asList(0, 7)));
I guess I was looking for something like this...
import java.util.ArrayList;
public class QuickTest {
public static ArrayList<ArrayList<Integer>> getTwoDimArrListCopy(ArrayList<ArrayList<Integer>> original){
ArrayList<ArrayList<Integer>> copy = new ArrayList<>();
for (ArrayList<Integer> arr: original){
copy.add(new ArrayList<Integer>(arr));
}
return copy;
}
public static void main(String[] args) {
ArrayList<ArrayList<Integer>> firstTwoDimList = new ArrayList<>();
ArrayList<ArrayList<Integer>> secondTwoDimList = new ArrayList<>();
firstTwoDimList.add(new ArrayList<Integer>());
firstTwoDimList.add(new ArrayList<Integer>());
firstTwoDimList.add(new ArrayList<Integer>());
Integer counter = 2;
for(int arrI = 0; arrI < firstTwoDimList.size(); arrI++, counter+=2){
firstTwoDimList.get(arrI).add(counter);
counter+=2;
firstTwoDimList.get(arrI).add(counter);
}
secondTwoDimList = getTwoDimArrListCopy(firstTwoDimList);
System.out.println("firstTwoDimList.get(1).get(0) = " + firstTwoDimList.get(1).get(0));
System.out.println("secondTwoDimList.get(1).get(0) = " + secondTwoDimList.get(1).get(0));
firstTwoDimList.get(1).set(0, 7);
System.out.println("firstTwoDimList.get(1).get(0) = " + firstTwoDimList.get(1).get(0));
System.out.println("secondTwoDimList.get(1).get(0) = " + secondTwoDimList.get(1).get(0));
}
}
I was just hoping there was a built in library that would do that getTwoDimArrListCopy() function for me...
I am pretty new to Java and had a question. This is homework, so I would not like any outright answers. Thanks!
I'm working on a genetic algorithm for playing poker. I wanted to create an arrayList of string arrays. The string arrays would hold moves for each possible hand during a round. What I want to do right now to make sure it is working is run my method and print out the results. Here are my practice classes (this is only a small part of the assignment):::
import java.util.ArrayList;
import java.util.Arrays;
public class Play
{
GeneticAlg start;
ArrayList<Object> pop;
public static void main(String[] args)
{
GeneticAlg start = new GeneticAlg();
ArrayList<String[]> pop = start.initializePopulation();
for(String[] arr: pop)
{
System.out.println(Arrays.toString(arr));
}
}
}
import java.util.ArrayList;
import java.util.Random;
public class GeneticAlg
{
ArrayList<String[]> population;
int[] populationScores;
String[] chromosome;
int generation;
int index;
public GeneticAlg()
{
}
public ArrayList<String[]> initializePopulation()
{
ArrayList<String[]> population = new ArrayList<String[]>();
for (int i = 0; i < 20; i++)
{
Random generator = new Random();
String[] choices = {"bet","raise","call","check"};
chromosome = new String[33];
for (int j = 0; j < 33; j++)
{
if (j < 6) //first and second round possible hands)
{
index = generator.nextInt((choices.length)-1);
chromosome[j] += choices[index];
}
else //third, fourth, and fifth round possible hands)
{
index = generator.nextInt(choices.length);
chromosome[j] += choices[index];
}
}
population.add(chromosome);
}
return population;
}
}
Right now, it's printing out the array, but each entry looks like this:
[nullcall, nullraise, nullbet, nullraise, nullcall, nullraise,....
I want it to just return the move without null on the front. Any advice is appreciated. Thanks!
ETA: I fixed the two lines with the concatenation error, but it is still printing "null" in front of each command. Any advice?
Code after repairing the error:
import java.util.ArrayList;
import java.util.Arrays;
public class Play
{
GeneticAlg start;
ArrayList<Object> pop;
public static void main(String[] args)
{
GeneticAlg start = new GeneticAlg();
ArrayList<String[]> pop = start.initializePopulation();
for(String[] arr: pop)
{
System.out.println(Arrays.toString(arr));
}
}
}
import java.util.ArrayList;
import java.util.Random;
public class GeneticAlg
{
ArrayList<Object> population;
String[] choices;
int[] populationScores;
String[] chromosome;
int generation;
int index;
public GeneticAlg()
{
}
public ArrayList<Object> initializePopulation()
{
population = new ArrayList<Object>();
for (int i = 0; i < 20; i++)
{
Random generator = new Random();
for (int j = 0; j < 24; j++)
{
if (j < 6) //first and second round possible hands)
{
choices[0]= "bet";
choices[1]= "raise";
choices[3]= "call";
index = generator.nextInt(choices.length);
chromosome[j] = choices[index];
}
else //third, fourth, and fifth round possible hands)
{
choices[4] = "check";
index = generator.nextInt(choices.length);
chromosome[j] = choices[index];
}
}
population.add(chromosome);
}
return population;
}
}
Arrays of objects (like Stirngs) are filled at start with null values, so doing
chromosome[j] += choices[index];
is the same as
chromosome[j] = chromosome[j] + choices[index];
which is the same as
chromosome[j] = null + choices[index];
So you are concatenating null with choices[index]; which gives you nullbet for instance.
To solve it just use = instead of +=.
Since you don't want an outright answer, look at the code that populates your String[]'s. Your printing's doing the right thing, but the Strings in the array actually are "nullbet," "nullraise," etc.
The error comes from this line here:
chromosome[j] += choices[index];
The += operator, when used with a Strings, will concatenate the right-hand string to the end of the left-hand string. In this case, it tacks on choices[index] to the existing contents of chromosome[j], which will null by default if chromosome is declared as an array of Objects.
You probably meant
chromosome[j] = choices[index];
And accidentally inserted the + because you use population.add() with your list below.
Your "fixed" code looks like it doesn't compile - you're probably still running the previous version. You don't initialize choices ("choices = new String[4]") and you're confusing its indices (0, 1, 3 and 4). Also, if you're trying to add a fourth element to the array later, don't, you can't do that with arrays. And you're assigning an ArrayList to an ArrayList without a cast. You only needed to swap += with = in your original code, it seemed fine otherwise.
I am confused with passing ARRAYLIST values from one class to another.
I used the ARRAY in these classes before. I am changed those with ARRAYLISTS.
I have 2 classes. this class has an ARRAYLIST called "locationcells". This programs get 3 random digits from another class and get uses inputs and check if their inputs match the 3 digits. it's more like a guessing game.
import java.util.ArrayList;
class SimpleDotCom {
private ArrayList<String> locationcells;
public void setLocationcells(ArrayList<String> Locs)
{
locationcells = Locs;
}
public String CheckYourself(String StringGuess)
{
String result = " Miss";
int index = locationcells.indexOf(StringGuess);
if (index >= 0)
{
locationcells.remove(index);
if (locationcells.isEmpty())
{
result = "Kill";
}
else
{
result = "Hit";
}
}
return result;
}
}
this looks right.
Now the class with the main method:
import java.util.ArrayList;
class SimpleDotComGame {
public static void main(String[] args)
{
int numOfGuesses = 0;
GameHelper helper = new GameHelper();
SimpleDotCom theDotCom = new SimpleDotCom();
/*
this is the part I don't understand. I used to have the int array and generated random numbers and it worked well.
int randomNum = (int) (Math.random() * 5);
ArrayList<String> locations = new ArrayList<String>();
*/
theDotCom.setLocationcells(locations);
boolean isAlive = true;
while (isAlive == true)
{
String guess = helper.getUserInput("Enter a number");
String result = theDotCom.CheckYourself(guess);
numOfGuesses++;
if (result.equals("Kill"))
{
isAlive = false;
System.out.println("You took " + numOfGuesses + "guesses");
}
}
}
}
If you see the comments section above. That's the part I am getting confused. I used to have an array there. INT array. So I was able to pass the INT random numbers to the "simpledotcom" class. Now it is an arraylist with string type, I am not sure how to move forward.
Thank you all in advance,
int numericGuess = Integer.parseInt(helper.getUserInput("Enter a number"));
Also you can use a list of Integers too:
ArrayList<Integer> locations = new ArrayList<Integer>();
while(//condition){
int randomNum = (int) (Math.random() * 5);
locations.add(randomNum)
}
this way you can perform
locations.indexOf(numericGuess) or locations.contains(numericGuess)
OR
Conversely you can do,
String guess = helper.getUserInput("Enter a number");
ArrayList<String> locations = new ArrayList<String>();
while(//condition){
int randomNum = (int) (Math.random() * 5);
locations.add(String.valueOf(randomNum))
}
and check by
locations.indexOf(guess) or locations.contains(guess)
You can always transform the random int to a string by using Integer.toString() before inserting into your array list.
You can convert the String back to int using Integer.parseInt()
E.g.
for (int i = 0 ; i < 3 ; i++)
{
locations.add(Integer.toString((int)(Math.random() * 5));
}
If I understand well: add 3 Strings to the ArrayList:
ArrayList<String> locations = new ArrayList<String>();
for (i=0; i<3; i++)
{ locations.add(String.valueOf((int) (Math.random() * 5))); }
Anyway, you might refactor a little as well, starting with the extracting the above lines from the main method.
Another way might be to store your integer in a list, and convert the guesses to integers. Looks more logic to me anyway. In that case, you'll have an ArrayList. To convert a string to an integer:
int guessNumber = Integer.parseInt(guess);
or
Integer guessNumber = Integer.valueOf(guess);
Both will throw a NumberFormatException if 'guess' does not contain a parseble integer (see javadoc )
Why are you not using arrays like (apparently) you did before, by the way?
i have an arrayList ( named error_dub ) i want to print the duplicates only one time here is my code
for(x=0 ; x<=error_dub.size()-1 ; x++){
for(int h=x+0 ; h<=error_dub.size() ; h++){
if(error_dub.get(x).equals(error_dub.get(h) && x!=h){
System.out.println(error_dub.get(x)+" is duplicated ");
}
}
}
here the line is printed more than once so how can i printed only once ?
Use two sets (this assumes X is the class of your object):
// Returns a set of all duplicates in a list
public Set<X> getDuplicates(final List<X> list)
{
final Set<X> dups = new HashSet<X>();
final Set<X> set = new HashSet<X>();
/*
* Cycle through all elements in the original list. Add it to "set":
*
* - if the .add() method returns true, this is the first time the element is seen;
* - if it returns false, then this is not the first time, it is a duplicate:
* add it to "dups".
*/
for (final X element: list)
if (!set.add(element))
dups.add(element);
return dups;
}
Set's .add() will return false if the set is not modified as a result of the operation, which means if the element was already there.
Copy/paste that function into your existing code and replace the snippet above with:
for (final X dup: getDuplicates(error_dub))
System.out.println(dup + " is duplicated");
Important note: the getDuplicates() function as it is written will NOT respect element order. If order matters to you, replace dups with a LinkedHashSet instead of a HashSet.
you can use .add() method of set to check for duplicates. Method posted below adds list elements to set1. If element is a duplicate (.add() returns true), then element is adde to setToReturn
public Set<Integer> findDuplicates(List<Integer> listContainingDuplicates)
{
final Set<Integer> setToReturn = new HashSet();
final Set<Integer> set1 = new HashSet();
for (Integer yourInt : listContainingDuplicates)
{
if (!set1.add(yourInt))
{
setToReturn.add(yourInt);
}
}
return setToReturn;
}
ArrayList<String> ar=new ArrayList<String>();
ArrayList<String> ar2=new ArrayList<String>();
ar.add("1");
ar.add("2");
ar.add("3");
ar.add("4");
ar.add("5");
ar.add("1");
ar.add("2");
ar.add("1");
for(int x=0;x<ar.size();x++)
{
if(!ar2.contains(ar.get(x)))
{
for(int y=x+1;y<ar.size()-1;y++)
{
if((ar.get(y).equals(ar.get(x))))
{
System.out.print("repeating "+ar.get(x));
ar2.add(ar.get(x));
break;
}
}
}
}
you can do like this.
//method to identify the duplicate elements in array list
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Scanner;
public class Dup
{
public static void main(String[] args)
{
ArrayList<Integer> a=new ArrayList<Integer>();
System.out.println("enter elements");
int g;
Scanner b= new Scanner(System.in);
for(int i=0;i<10;i++)
{
g=b.nextInt();
a.add(g);
}
HashSet<Integer> c=new HashSet<Integer>();
ArrayList<Integer> d=new ArrayList<Integer>();
for (Integer y : a)
{
if (c.contains(y))
{
d.add(y);
}
else
c.add(y);
}
System.out.println("original elements are:"+c);
System.out.println("duplicate elements are:");
for(Integer h:d)
{
System.out.println(h);
}
}
}