Array are not selecting values randomly and split into two arrays - java

I have got an array list of animals, on click on 'select' button I
would like to randomly select these animals and pass animals into two
arrays (split) called 'teamA and teamB'. Here is my code, but I am getting the same array list always as per screenhot link ? Could someone please
help me to figure out the problem ?
import java.lang.Math;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
public class RandomExample {
private Random random = new Random();
public static void main(String[] args) {
// 'list' array list contains animals
List<String> list = new ArrayList<String>();
list.add("Tiger");
list.add("Crocodile");
list.add("Cat");
list.add("Dog");
list.add("Elephant");
list.add("Lion");
list.add("Deer");
list.add("Eagle");
RandomExample obj = new RandomExample();
for(int i = 0; i < 10; i++){
obj.getRandomList(list);
List<String> teamA = list.subList(0, 4);
List<String> teamB = list.subList(4, 8);
System.out.println(teamA);
System.out.println(teamB);
}
}
public String getRandomList(List<String> list) {
//0-4
int index = random.nextInt(list.size());
System.out.println("\nIndex :" + index );
return list.get(index);
}
}

As I asked I am not sure why you do not capture the returned string from getRandomList()… I am guessing you are thinking that the list gets returned? Another issue is that when you get a random number from the list you could get the same number. Therefore you will possibly get the same animal on both teams or even the same animal twice or more on the same team. When you put an animal on a team… you need to remove them from the list.
Below I create the two teams. Then setup two loops, one for each team. Using your getRandomList method to get a random animal then remove that animal from the list. After we have both lists, print the results. Hope this helps.
Edit: As per OP request to have a different number of animals for the teams.
Example: use 5 total animals for the teams.
Obviously it’s better to look at the amount of available data before you actually set the team sizes. Example: if you want teamB to have 5 and teamA to have 4, then there better be at least 9 animals in the list. So check the team sizes before you start the loops. If totalAnimalsForTeams is greater than the number of animals in the list or totalAnimalsForTeams is less than two , then we need to indicate this to the user and exit. This approach allows you to use only part of the list if needed. In the implementation below, if the totalAnimalsForTeams is an odd number the second loop will have the extra animal member.
public class Main
{
private static Random random = new Random();
public static void main(String[] args)
{
// 'list' array list contains animals
List<String> list = new ArrayList<String>();
list.add("Tiger");
list.add("Crocodile");
list.add("Cat");
list.add("Dog");
list.add("Elephant");
list.add("Lion");
list.add("Deer");
list.add("Eagle");
list.add("Monster");
list.add("Alien");
list.add("Vombie");
list.add("Politician");
list.add("Donkeye");
List<String> teamA = new ArrayList<String>();
List<String> teamB = new ArrayList<String>();
String newAnimal;
int totalAnimalsForTeams = 7; // <- probably get this value from the user?
if (totalAnimalsForTeams > list.size())
{
System.out.println("There are only " + list.size() + " animals in the list. Requested animals was: " + totalAnimalsForTeams);
return;
}
int firstHalf = totalAnimalsForTeams / 2;
if (firstHalf < 1)
{
System.out.println("Requested " + totalAnimalsForTeams + " animals for teams... not enough to make two teams!");
return;
}
for(int i = 0; i < firstHalf; i++)
{
newAnimal = getRandomList(list);
teamA.add(newAnimal);
list.remove(newAnimal);
}
int secondHalf = totalAnimalsForTeams - firstHalf;
for(int i = 0; i < secondHalf; i++)
{
newAnimal = getRandomList(list);
teamB.add(newAnimal);
list.remove(newAnimal);
}
System.out.println(teamA);
System.out.println(teamB);
}
public static String getRandomList(List<String> list) {
//0-4
if (list.size() > 1)
{
int index = random.nextInt(list.size());
//System.out.println("\nIndex :" + index );
return list.get(index);
}
else
{
return list.get(0);
}
}
}

try this .. it should work ..
import java.lang.Math;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Collections;
import java.util.Random;
public class RandomExample {
private Random random = new Random();
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("Tiger");
list.add("Crocodile");
list.add("Cat");
list.add("Dog");
list.add("Elephant");
list.add("Lion");
list.add("Deer");
list.add("Eagle");
RandomExample obj = new RandomExample();
List<String> teamA = list.subList(0,4);
List<String> teamB = list.subList(4,8);
for(int i = 0; i < 10; i++){
obj.getRandomList(list);
teamA = list.subList(0,4);
teamB = list.subList(4,8);
Collections.rotate(teamA, 1);
Collections.rotate(teamB, 1);
System.out.println(teamA);
System.out.println(teamB);
}
}
public String getRandomList(List<String> list) {
//0-4
int index = random.nextInt(list.size());
System.out.println("\nIndex :" + index );
return list.get(index);
}
}

Calling obj.getRandomList(list); returns a String but you donot do anything with it. I know this method is supposed to return a randomly picked item.
To correctly do what you are asking for, You would have to declare a new ArrayList say temp and then assign list to it.
To avoid Repetition of the same object, you need to remove the randomly generated item from the temp ArrayList created.
Then after you are done, remove the temp ArrayList created.
I have made the necessary changes to your main method as per the suggestions I made.
public static void main(String[] args) {
// 'list' array list contains animals
List<String> list = new ArrayList<String>();
list.add("Tiger");
list.add("Crocodile");
list.add("Cat");
list.add("Dog");
list.add("Elephant");
list.add("Lion");
list.add("Deer");
list.add("Eagle");
RandomExample obj = new RandomExample();
List<String> teamA = new ArrayList<String>();
List<String> teamB = new ArrayList<String>();
List<String> temp = list;
String animal;
for(int i = 0; i < 10; i++){
if(temp.isEmpty() == false){
animal = obj.getRandomList(temp);
if(i <= 3){
teamA.add(animal);
}else{
teamB.add(animal);
}
temp.remove(animal);
//System.out.println("temp is "+temp);
}
}
temp.clear();
System.out.println(teamA);
System.out.println(teamB);
}

Related

Initializing 2D ArrayList for for-loop summation (Java)

I am trying to sum N pairs of ints--an Nx2 ArrayList--and return the N summations as an ArrayList. While I understand it is not necessary to set up a class to accomplish this, I would like to do so as practice for future projects.
import java.util.ArrayList;
public class SumsInLoop {
public SumsInLoop(int numberOfPairs, ArrayList<ArrayList<Integer>> numbersList) {}
public ArrayList<Integer> getSums(int numberOfPairs, ArrayList<ArrayList<Integer>> numbersList) {
ArrayList<Integer> pairsOfSums = new ArrayList<Integer>();
for (ArrayList<Integer> Pair : numbersList) {
int x = Pair.get(0);
int y = Pair.get(1);
int sum = x + y;
pairsOfSums.add(sum);
}
System.out.println(pairsOfSums);
return pairsOfSums;
}
The data that I am given is a random assortment of N pairs (numbersOfPairs) of integers, e.g. 612673 108695. I would like to add these pairs of integers to a 2D ArrayList (numbersList) that will be called by getSums.
However, I am having difficulties initializing numbersList. My main function is as follows:
public static void main(String[] args) {
int myNumberOfPairs = 13;
ArrayList[][] myNumbersList = new ArrayList[13][2];
myNumbersList[0][0] = new ArrayList<>();
myNumbersList[0][0].add(612673);
myNumbersList[0][1].add(108695);
myNumbersList[1][0] = new ArrayList<>();
myNumbersList[1][0].add(756875);
myNumbersList[1][1].add(496058);
SumsInLoop mySum = new SumsInLoop(myNumberOfPairs,myNumbersList);
mySum.getSums(myNumberOfPairs, myNumbersList);
The last two lines of code throw errors, asking me to change myNumbersList to type ArrayList<List<Integer>> which throws even more errors, even after changing all 2D ArrayLists to type ArrayList<List<Integer>>.
So, my two questions are as follows:
How can I initialize an NxM ArrayList and populate it correctly?
Is there a faster way of accomplishing this task while still using a class method?
P.S. I'm used to coding in Python and am self-teaching myself Java, so any other information or resources you can provide me with are much appreciated.
You may want to simplify your input by using 2D array of int : int[][] myNumbersList = new int[13][2];
The expected output in that case is a 1D array of int[13] that can be obtained as follows (demonstrated with 2 pairs. See mcve ) :
public class SumsInLoop {
//pairsOfInts should be an [n][2] array
private static int[] sumOfPairs(int[][] pairsOfInts) {
int[] sums = new int[pairsOfInts.length];
for(int pairIndex = 0; pairIndex < pairsOfInts.length; pairIndex++) {
sums[pairIndex]= pairsOfInts[pairIndex][0]+pairsOfInts[pairIndex][1];
}
return sums;
}
public static void main(String[] args) {
int numberOfPairs = 2;
int[][] pairsOfInts = new int[numberOfPairs][2];
pairsOfInts[0] = new int[] {612673,108695 };
pairsOfInts[1] = new int[] {756875,496058 };
int[] sumOfPairs = sumOfPairs(pairsOfInts);
System.out.println(Arrays.toString(sumOfPairs));
}
}
If you want a solution implemented with List you can make use of javafx Pair (or make your own pair class.
The input can be defined as List<Pair<Integer,Integer>> pairsOfInts = new ArrayList<>();
The out put can be an array as above, or a List<Integer>:
import java.util.ArrayList;
import java.util.List;
import javafx.util.Pair;
public class SumsInLoop {
private static List<Integer> sumOfPairs(List<Pair<Integer, Integer>> pairsOfInts) {
List<Integer> sums = new ArrayList<>();
for(Pair<Integer,Integer> pair : pairsOfInts) {
sums.add(pair.getKey()+ pair.getValue());
}
return sums;
}
public static void main(String[] args) {
List<Pair<Integer,Integer>> pairsOfInts = new ArrayList<>();
pairsOfInts.add (new Pair<>(612673,108695 ));
pairsOfInts.add (new Pair<>(756875,496058));
List<Integer> sumOfPairs = sumOfPairs(pairsOfInts);
System.out.println(sumOfPairs);
}
}
The (compile) exception you are getting is due to the fact that you expect a ArrayList<ArrayList<Integer>>, but pass an ArrayList[][]. (which is not the same in Java)
In your case you'd need (in the main method):
ArrayList<ArrayList<Integer>> myNumbersList = new ArrayList</* when java > 6 ;)*/>(13);
this only sets the capacity of the (parent) list (..and the underlying/internal backing array)
to initialize the child lists, you'd not come around looping (somehow...even not in python :):
for (int i = 0; i < 13; i++) {
myNumbersList.add(new ArrayList<Integer>(2));
}
Depends on what means "correctly" ...but I assume with "random data", ideally you would again inner loop:
java.util.Random rnd = new Random(/*seed default current timestamp*/);
//...
for (int i = 0; i < 13; i++) {
ArrayList<Integer> innerList = new ArrayList<>(2);
for (int j = 0; j < 2; j++) {
innerList.add(rnd.netxInt(/*bound default Integer.MAX_VALUE*/) /*+/-/% offset*/);
}
myNumberList.add(innerList);
}
Sorry I am not aware of one (faster way), but much depends on the "input format".
Since you already know the amount of values in a pair, an ArrayList is unnecessary. You can create your own, simpler implementation of a pair.
class Pair {
public final int left;
public final int right;
public Pair(int left, int right){
this.left = left;
this.right = right;
}
}
You can then access the values by creating a pair object and accessing its fields.
Pair p = new Pair(10, 7);
System.out.println(p.left); // 10
System.out.println(p.right); // 7
You can then more easily redefine your getSums method.
public static List<Integer> getSums(List<Pair> pairs){
List<Integer> pairsOfSums = new ArrayList<>();
for(Pair pair : pairs){
int sum = pair.left + pair.right;
pairsOfSums.add(sum);
}
return pairsOfSums;
}
Please also notice the function can be static and you don't need to pass the number of pairs. The for-each loop will cycle through all of them regardless.
Initializing the array is then easier than the method you have described in the question.
List<Pair> pairs = new ArrayList<>();
pairs.add(new Pair(7, 10));
pairs.add(new Pair(18, 3));
pairs.add(new Pair(-6, 0));
pairs.add(new Pair(4, 2));
System.out.println(SumsInLoop.getSums(pairs));

how to Add ArrayList in ArrayList

I got a problem when insert an ArrayList into ArrayList.
My source code:
import java.util.ArrayList;
public class Ask {
public static void main(String[] args) {
ArrayList<String> mentah = new ArrayList<String>();
mentah.add("Reza");
mentah.add("Fata");
mentah.add("Faldy");
mentah.add("Helsan");
mentah.add("Dimas");
mentah.add("Mamun");
mentah.add("Erik");
mentah.add("Babeh");
mentah.add("Tio");
mentah.add("Mamang");
ArrayList<ArrayList<String>> result =new ArrayList<ArrayList<String>>();
result.add(mentah);
}
}
How can I create a list based on that data; that will look like:
[[data1,data2,data3],[data4,data5,data6],[data7,data8,data9,data10]]
10 div 3 is 3 (so 3 elements per sublist)
10 mod 3 is 1 (so last sublist has 4 entries)
10 divide by 3 is
3 3 4
Just upgraded the answer of #Narayana Ganesh:
ArrayList<String> mentah = new ArrayList<String>();
mentah.add("Reza");
mentah.add("Fata");
mentah.add("Faldy");
mentah.add("Helsan");
mentah.add("Dimas");
mentah.add("Mamun");
mentah.add("Erik");
mentah.add("Babeh");
mentah.add("Tio");
mentah.add("Mamang");
List<List<String>> result = new ArrayList<List<String>>();
for (int j= 0; j< mentah.size() ; j+=3) {
int end = mentah.size() <= j+2 ? mentah.size() : j+3;
if(mentah.size() - j == 4) end = end +1;
if(j != 9) result.add(mentah.subList(j, end));
}
System.out.println(result);
}
Result:
[[Reza, Fata, Faldy], [Helsan, Dimas, Mamun], [Erik, Babeh, Tio, Mamang]]
A more generic solution would look like:
List<String> allNames = Arrays.asList("Reza", "Fata", ...
List<List<String>> slicedNames = new ArrayList<>();
List<String> sublist = new ArrayList<>();
int sublistTargetLength = 3;
for (String name : allNames) {
sublist.add(name);
if (sublist.size() == sublistTargetLength) {
slicedNames.add(sublist);
sublist = new ArrayList<>();
}
}
if (sublist.size() > 0) {
slicedNames.get(slicedNames.size()-1).addAll(sublist);
}
Some notes:
The above iterates your initial list of names (which can created using that single call to Arrays.asList()); and puts the entries into same-sized lists; which are then added to the slicedNames list of list.
If there is any "remaining" data; that is simply added to the last element of the list of list.
You should prefer to use the interface type List for your variable types; you only use the specific implementation class (ArrayList) when instantiating the list
When iterating anything, prefer the for-each looping style when possible
Try this. You can achieve this using subList method.
import java.util.ArrayList;
import java.util.List;
public class Ask {
public static void main(String[] args) {
ArrayList<String> mentah = new ArrayList<String>();
mentah.add("Reza");
mentah.add("Fata");
mentah.add("Faldy");
mentah.add("Helsan");
mentah.add("Dimas");
mentah.add("Mamun");
mentah.add("Erik");
mentah.add("Babeh");
mentah.add("Tio");
mentah.add("Mamang");
List<List<String>> result = new ArrayList<List<String>>();
for (int j= 0; j< mentah.size() ; j+=3) {
int end = mentah.size() <= j+2 ? mentah.size() : j+3;
result.add(mentah.subList(j, end));
}
for (List<String> item : result) {
System.out.println(" - -"+item);
}
}
}
First create sublists with a maximal size of 3 which will give you something like this
[[Reza, Fata, Faldy], [Helsan, Dimas, Mamun], [Erik, Babeh, Tio], [Mamang]]
then check if the last sublist size is less than 3 if yes add this to the second last sublist and remove the last one
public class Example {
public static void main(String[] args) {
List<String> mentah = new ArrayList<>();
mentah.add("Reza");
mentah.add("Fata");
mentah.add("Faldy");
mentah.add("Helsan");
mentah.add("Dimas");
mentah.add("Mamun");
mentah.add("Erik");
mentah.add("Babeh");
mentah.add("Tio");
mentah.add("Mamang");
List<List<String>> parts = new ArrayList<>();
int sizeOfOriginalList = mentah.size();
int sizeOfSubLists = 3;
for (int i = 0; i < sizeOfOriginalList; i += sizeOfSubLists) {
parts.add(new ArrayList<>(mentah.subList(i, Math.min(sizeOfOriginalList, i + sizeOfSubLists))));
}
if(parts.get(parts.size()-1).size()<sizeOfSubLists){
parts.get(parts.size()-2).addAll(parts.get(parts.size()-1));
parts.remove(parts.get(parts.size()-1));
}
System.out.println(parts);
}
}

random elements from a list DURING the addition

There are 20 names in my code.
my function has 2 options to add elements to a list I've:
1.
Inserting all the 20 names to the list:
public void addNames() {
list.add("name1");
list.add("name2");
...
list.add("name20");
}
2.
Adding only 5 random names(from the 20 names) to the list. For doing it, I thought about 2 ways. What's the best way to random 5 names from the 20? maybe you have a better way.
A.
Using a random set of indices (each value will be between 0 to 19 because there are 20 names) and before the 'add' I'll check if adding them or not by some counter:
public void addNames() {
// adding 5 random indices between 0 to 19 to the set
Set<Integer> set = new HashSet<Integer>();
Random r = new Random();
Set<Integer> indices = new HashSet<>(numRandomNames); //==5
for (int i = 0; i < numRandomNames; ++i) {
int index = r.nextInt(numNames - 0); //==19
indices.add(index);
}
int counter = 0;
if (indices.contains(counter)) {
list.add("name1");
}
counter++;
if (indices.contains(counter)) {
list.add("name2");
}
counter++;
if (indices.contains(counter)) {
list.add("name3");
}
...
}
B.
RandomList that extends List and overrides the 'add' function to do the same as 'A.' does BUT the override 'add' will decide whether adding the value inside the function so my function will look the same as 1. with the override 'add' function
Do you think about a better solution? if not, then which one is better? (A or B?). I just saw that people recommends not to extend the java collection but I think it's the best solution from these 2 solutions.
NOTE
====
my code can have 10000 names or more even so I don't want to add all the 10,000 names to this\other list and then random 5 of them to other list. I prefer to do it DURING the addition in order to avoid many places of the list while I don't really need them.
EDIT
an answer to ProgrammerTrond:
I'm not sure I'll do it but what I asked me to show is my suggestion of 2.B:
public class RandomList<Integer> implements List<Integer> {
private int addCallsCounter;
private Set<Integer> setIndices = null;
public RandomList(final int numElements, final int maxVal, final int minVal) {
addCallsCounter = 0;
setIndices = new HashSet<Integer>(numElements);
Random r = new Random();
while (setIndices.size() < numElements) {
int index = r.nextInt(maxVal - minVal + 1) + minVal;
if (setIndices.contains(index) == false) {
setIndices.add(index);
}
}
}
#Override
public boolean add(Integer object) {
if (setIndices.contains(addCallsCounter++)) {
this.add(object);
return true;
}
return false;
}
}
and from my code I'll do so:
RandomList randList = new RandomList(5);
randList.add("name1");
randList.add("name2");
randList.add("name3");
...
randList.add("name19");
randList.add("name20");
but my problem is that I need to implement MANY abstract methods of List pfff. RandomList cann't be abstract too because then it won't be able to be instantiated.
try this:
List<Integer> index = new ArrayList<>();
List<String> five_names = new ArrsyList<>();
List<String> allnames = new ArrayList<>();
store five random values
for(int i = 0;i < 5;i++){
int index_no = getrandomNumber();
index.add(index_no);
five_names.add(allnames.get(index_no));
}
getRandomNumber method:
public int getRandomNumber(){
Random rnd = new Random();
int x = rnd.nextInt(20);
if(index.contains(x)){
return getRandomNumber();
}else{
return x
}
}
Why not like this? You don't need the random index list in your list implementation. Didn't you just want a method that would add to a list 5 random names drawn from a set of available names?
import java.util.*;
public class ListAdding {
private static List<String> allNames = Arrays.asList("name1", "name2", "name3", "name4", "name5", "name6", "name7");
public static void main(String[] args) {
new Temp().test();
}
void test() {
List<String> list = new ArrayList<>();
list.add("Bernie");
addFiveRandom(list);
for (int i = 0; i < list.size(); i++) {
System.out.println(i + ": " + list.get(i));
}
// Example: 0: Bernie
// 1: name2
// 2: name3
// 3: name6
// and so on
}
void addFiveRandom(List<String> toBeAddedTo) {
List<Integer> indices = new ArrayList<>();
while (indices.size() < 5) {
int newIndex = new Random().nextInt(5);
if (!indices.contains(newIndex))
indices.add(newIndex);
}
for (Integer index : indices) {
toBeAddedTo.add(allNames.get(index));
}
}
}

ArrayList in reverse order

I need to start with the first occurence of the first element argument and end with the next occurence of the second argument, putting them in reverse order.
I.e.:
ArrayList<String> food
tomato cheese chips fruit pie butter tea buns
and the two arguments are chips and buns
the new ArrayList should be
buns tea butter pie fruit chips
this is what I've got, but when printed the arraylist is empty
public static void main (String[] args){
ArrayList<String> food = new ArrayList<String>();
food.add(new String("tomato"));
food.add(new String("cheese"));
food.add(new String("chips"));
food.add(new String("fruit"));
food.add(new String("pie"));
food.add(new String("butter"));
food.add(new String("tea"));
food.add(new String("buns"));
ArrayList<String> f1 = reverseOrder(food,"chips","buns");
}
public static ArrayList<String> reverseOrder(ArrayList<String> a, String w1, String w2){
ArrayList<String> food = new ArrayList<String>();
int startingPos = 0;
int endingPos = 0;
boolean startAdding = false;
for(int i=0; i<a.size(); i++){
String n = a.get(i);
if(n.equals(w1)){
endingPos = i;
}
if(n.equals(w2)){
startingPos = i;
}
}
for(int j = startingPos; j<=endingPos; j--){
String p = a.get(j);
food.add(p);
}
System.out.print(food);
return food;
}
The problem you are trying to solve is really two. First, you need to identify the range (indices) that you care about. Then perform the reverse in place.
You have the first part. The 2nd part can be done by repeatedly removing and inserting values, but I would recommend swapping instead.
ArrayList l;
int begin, end;
//reverse everything from "begin" to "end".
while(begin<end){
Object tmp = l.get(begin);
l.set(begin, l.get(end));
l.set(end, tmp);
begin++;end--;
}
You should also know that Java Collections already gives you easy ways to reverse a list.
Collections.reverse(list);
Also, if you need different lists and not modify the original as you did, you can grab a sublist like this.
list.subList(fromIndex, toIndex)
With this, you can easily perform your task with a combination of the above.
You can use indexOf and lastIndexOf to get the proper positions of the elements.
Those methods will return -1 if the element cannot be found, though, so just be aware of that.
public static void main(String[] args) throws Exception {
List<String> food = Arrays.asList("tomato", "cheese", "chips", "fruit", "pie", "butter", "tea", "buns");
ArrayList<String> lst = reverseOrder(food, "chips", "buns");
System.out.println(lst);
}
private static ArrayList<String> reverseOrder(List<String> food, String start, String end) throws Exception {
int startIndex = food.indexOf(start);
if (startIndex < 0) {
throw new Exception(start + " not found");
}
int endIndex = food.lastIndexOf(end);
if (endIndex < 0) {
throw new Exception(end + " not found");
}
ArrayList<String> lst = new ArrayList<>();
while (endIndex >= startIndex) {
lst.add(food.get(endIndex--));
}
return lst;
}
Output [buns, tea, butter, pie, fruit, chips]
This part of the code is wrong:
for(int j = startingPos; j<=endingPos; j--){
String p = a.get(j);
food.add(p);
}
Why? Some examples:
Imagine that you pass these arguments ("tomato", "cheese") => the starting position will be 1 and the ending position will be 0. In the validation of your loop you have "starting with j=1 do the loop while j<=0" meaning that it will never enter in the cycle
Imagine that you pass these arguments ("cheese", "tomato") => the starting position will be 0 and the ending position will be 1. In the validation of your loop you have "starting with j=0 do the loop while j<=1 and in each iteration reduce 1 to j" meaning that after the first iteration j=-1 and you will have an an index out of bounds exception
Here's a code, based on yours (for your better understanding), that will give you the result that you want:
//this code is case sensitive
public ArrayList<String> reverseOrder(ArrayList<String> food, String w1, String w2) {
String startingEl = null;
String endingEl = null;
for(int i=0; i<food.size(); i++){
String n = food.get(i);
//verify if it's equal and if it's really the first occurrence
if(n.equals(w1) && endingEl==null){
endingEl = n;
}
//verify if it's equal and if it's really the first occurrence
if(n.equals(w2) && startingEl==null){
startingEl = n;
}
//if both are found, save some time by interrupting the loop
if(startingEl!=null && endingEl!=null) break;
}
//Protect here your code in case of the first or last elements is not found
ArrayList<String> food_reversed = new ArrayList<String>();
food_reversed.add(0, startingEl);
for(int j = (food.size()-1); j>=0; j--){
String p = food.get(j);
if(p==startingEl || p==endingEl) continue;
food_reversed.add(p);
}
food_reversed.add(endingEl);
System.out.println(food_reversed);
return food_reversed;
}
If I understood correctly the challenge, here's a different example of code to solve your problem:
//this code is case sensitive, is not prepared for repeated string elements
//and is not prepared if both arguments are exactly the same string
//is not prepared in cases that the any of the string arguments doesn't exist in the food array
//this code doesn't insert the same element reference on first and last element
//This code is not the perfect solution cause as you see it has a lot of ails, but it's probably a good start for your to learn more about the subject
import java.util.ArrayList;
import java.util.Collections;
public class QuestionOrderChallenge {
ArrayList<String> food = new ArrayList<String>();
public QuestionOrderChallenge() {
food.add(new String("tomato"));
food.add(new String("cheese"));
food.add(new String("chips"));
food.add(new String("fruit"));
food.add(new String("pie"));
food.add(new String("butter"));
food.add(new String("tea"));
food.add(new String("buns"));
ArrayList<String> a1 = reverseOrder(food,"chips","buns");
ArrayList<String> a2 = reverseOrder(food,"pie","tea");
ArrayList<String> a3 = reverseOrder(food,"tomato","cheese");
}
public ArrayList<String> reverseOrder(ArrayList<String> food, String last, String first) {
ArrayList<String> reversed_food = new ArrayList<String>(food);
reversed_food.remove(first);
reversed_food.remove(last);
Collections.reverse(reversed_food);
reversed_food.add(0, first);
reversed_food.add(last);
System.out.println("Array ordered according to challenge: " + reversed_food);
return reversed_food;
}
public static void main(String[] args) {
new QuestionOrderChallenge();
}
}
If you want to have the same base challenge but then order Alphabetically, here's the code:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
public class AlphabeticOrderChallenge {
ArrayList<String> food = new ArrayList<String>();
public AlphabeticOrderChallenge() {
food.add(new String("tomato"));
food.add(new String("cheese"));
food.add(new String("chips"));
food.add(new String("fruit"));
food.add(new String("pie"));
food.add(new String("butter"));
food.add(new String("tea"));
food.add(new String("buns"));
ArrayList<String> f1 = reverseOrder(food,"chips","buns");
System.out.println("Array ordered according to challenge: " + f1);
}
public ArrayList<String> reverseOrder(ArrayList<String> food, String end, String begin) {
Collections.sort(food, new ComparatorChallenge(end, begin));
return food;
}
private class ComparatorChallenge implements Comparator {
String endarg;
String beginarg;
public ComparatorChallenge(String beginarg, String endarg) {
this.beginarg = beginarg.toUpperCase();
this.endarg = endarg.toUpperCase();
}
#Override
public int compare(Object arg0, Object arg1) {
String a = ((String)arg0).toUpperCase();
String b = ((String)arg1).toUpperCase();
if(a.compareTo(endarg)==0 || b.compareTo(beginarg)==0) return -1;
if(b.compareTo(endarg)==0 || a.compareTo(beginarg)==0) return 1;
return b.compareTo(a);
}
}
public static void main(String[] args) {
new AlphabeticOrderChallenge();
}
}
The problem has two parts. First we need to find the sublist that satisfies the condition. Once we have the sublist, we can use Collections.reverse(List<?> list) to reverse it.
First, find the sublist between two elements, inclusive. The main idea is to identify the indices of these two elements using indexOf, then call subList on them. But we need to keep in mind the indices might be in a different order than we thought.
private static <T> List<T> inclusiveSublist(List<T> src, T from, T to) {
int start = src.indexOf(from), stop = src.indexOf(to);
if (start != -1 && stop != -1) {
// Successfully located both! But they could be in the "wrong" order
if (start <= stop)
// Element from could appear before to in the list (Plus one to include the second element)
return src.subList(start, 1 + stop);
else // Or the other way around
return src.sublist(stop, 1 + start);
}
// Return empty list if we cannot find both elements
return Collections.emptyList();
}
Now all we need is to reverse the result of inclusiveSublist:
public static <T> List<T> inclusiveReverseSublist(List<T> src, T from, T to) {
List<T> l = inclusiveSublist(src, from, to);
Collections.reverse(l);
return l;
}
And the test:
public static void main(String [] args) {
List<String> src = new ArrayList<>();
src.addAll(Arrays.asList("tomato cheese chips fruit pie butter tea buns".split("\\s")));
System.out.println(src);
System.out.println(inclusiveReverseSublist(src, "fruit", "buns"));
System.out.println(inclusiveReverseSublist(src, "cheese", "tomato"));
}
About subList()
From the Java API doc, subList
Returns a view of the portion of this list between the specified fromIndex, inclusive, and toIndex, exclusive. (If fromIndex and toIndex are equal, the returned list is empty.) The returned list is backed by this list, so non-structural changes in the returned list are reflected in this list, and vice-versa. The returned list supports all of the optional list operations supported by this list.
So the above code will actually modify the original list, and moving the System.out.println(src); to the bottom will confirm this.

Making distinct selections from the given list

I am trying to make a team of unique members from the given set I have. This is what I have so far.
import java.util.*;
import java.lang.*;
class Main
{
public static void main (String[] args) throws java.lang.Exception
{
/* Putting all team-mates in HashMap */
HashMap<String, Integer> map = new HashMap<String, Integer>();
map.put("a", 1);
map.put("b", 2);
map.put("c", 3);
map.put("d", 4);
/* Printing out the random name and the Unique number with it*/
List<Integer> valuesList = new ArrayList<Integer>(map.values());
List<String> keyList = new ArrayList<String>(map.keySet());
System.out.println("The Team members are :");
for (int i = 0; i < 3; i++)
{
int randomIndex = new Random().nextInt(valuesList.size());
Integer randomValue = valuesList.get(randomIndex);
String randomKey = keyList.get(randomIndex);
System.out.println(randomValue+" "+randomKey);
}
}
}
When I run this, I get duplication in my list, do I use Collections.shuffle(valuesList)?
Thank You.
You can get the same number randomly twice, so Collections.shuffle(...) should do.
If a,b,c,d is all you are after, this is how I would do it:
import java.util.*;
import java.lang.*;
class Main
{
public static void main (String[] args) throws java.lang.Exception
{
/* Putting all team-mates in a List*/
List<String> list = new ArrayList<String>();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
/* Printing out the random name */
System.out.println("The Team members are :");
for(int i = 0; i < 3; i++)
{
int randomIndex = new Random().nextInt(list.size());
//Integer randomValue = valuesList.get(randomIndex);
String randomValue = list.remove(randomIndex);
//String randomKey = keyList.get(randomIndex);
System.out.println(randomValue);
}
}
}
removing chosen elements from the list once chosen will make sure they don't reappear.
Fewer lines too.

Categories