Choose function for objects in ArrayList? - java

I have an ArrayList of x number of objects and wish to have a method that takes that ArrayList and produces new ArrayLists of size x-2 that represent all combinations of the objects in the original ArrayList.
For example, if I have an ArrayList of size 7 I would call this method and it would create ArrayLists that contain all possible combinations of the methods in the original ArrayList given the new size constraint.
I know a loop is needed but I'm having trouble with the logic. thanks
Here is what I have so far:
for (Card playerCard: playerHand) {
ArrayList<Card> FiveCHand = new ArrayList<Card>();
FiveCHand.add(playerCard);
for (Card communityCard: communityHand) {
FiveCHand.add(communityCard);
}
Collections.sort(FiveCHand, CardDomainModel.CardRank);
Hand hand = new Hand(FiveCHand);
FiveCardHands.add(hand);
}

Thanks for the code; it makes for a much better question.
If you permit me, I'd like to offer some feedback in order to get you to post the solution yourself. For that, we'll need all relevant code.
If you could add enough of the code we need to make a complete verifiable example then we know exactly what to change. Knowing what part of the code to post can be hard if you don't know how to solve the problem.
Your code could use some refactoring; this is pointed out by the fact that you never use the iteration variable playerHand. So, here are some questions and suggestions, inlined as comments:
// This is enough to make into a separate function. What would it's signature be?
// Also, what Class is this in?
for (Card playerCard: playerHand) { // playerhand not used!
ArrayList<Card> FiveCHand = new ArrayList<Card>(); // better: fiveCHand
FiveCHand.add(playerCard); // playerCard? where from?
for (Card communityCard: communityHand) { // there is Collections.addAll()
FiveCHand.add(communityCard);
}
Collections.sort(FiveCHand, CardDomainModel.CardRank);
Hand hand = new Hand(FiveCHand); // Why doesn't Hand take care of card list?
FiveCardHands.add(hand);
}

Related

Re/Create an immutable object that contains an immutable object list

Background
I am trying to create an immutable object that contains a list of immutable objects, as well as object type totals within the list.
I created a slightly sudo gist to try and show what I mean.
Gist - Adjusting an immutable object that contains an immutable object list.
Explanation
My example shows how I'm currently doing it, it does work. However not for all cases.
My VeggieCartView will have a recyclerview that gets filled with a new/saved VeggieCart.
Each VeggieCart has a list of veggies. Veggie totals etc...
I then have a helper class VeggieChanger, it contains an rx.Consumer<Veggie[]> that gets set and accepts any 1:1 veggie changes from the veggie views.
The VeggieCartView sets the consumer so when any one veggie changes, it creates an updated cart using the changes' corresponding cart factory method. The adapter is used to change/retrieve its list.
Working and not
This works well for changing one at a time, however batching changes is throwing concurrency exceptions.
I realize my gist is not runnable and doesn't show most boilerplate, and that I may be fundamentally wrong with some or all of my approaches. With that said I still hope someone can give me advice on how to better implement what I'm trying to do.
If more information is needed to understand, please ask. Thank you for anybody who does have help to offer,
Jon.
I ended up figuring out my main issue.
By adding this to my VeggieCartView:
public void bagAllCanned() {
final Veggie[] canned = new Veggie[cart.canTotal()];
final Veggie[] bagged = new Veggie[canned.length];
int t = 0;
final List<Veggie> veggies = cart.veggies();
for (int i = 0; i < veggies.size(); i++) {
final Veggie veggie = veggies.get(i);
if (veggie.canned()) {
canned[t] = veggie;
if (veggie instanceof Potato)
bagged[t] = Potato.can(veggie);
else if (veggie instanceof Tomato)
bagged[t] = Tomato.can(veggie);
t++;
}
}
for (int i = 0; i < canned.length; i++) {
veggieChange(canned[i], bagged[i]);
}
}
It fixes the concurrency errors.
I'm still unsure if my approach is correct or not. So even though the question is mostly answered, opinions are still VERY welcome.

Including new elements in for:each

Before I start my question, i'd like to mention that i DID read up some other topics and i tried around a bit but im just really confused atm so i figured i'd just ask.
So what i wanna do is use for each through a Set and within that for each, add elements to that set and also iterate through those.
The solution I found elsewhere was the following:
for(Object obj : new HashSet<Object>(oldSet))
I tried that, however I keep missing some of the last elements i'd like to match so im not really sure if this is the right approach in the first place?
To be specific, this is basically what my code looks like:
for(Position pos : new HashSet<Position>(oldSet){
for(Delta delta : deltas){
if(board.getTokenAt(pos.plus(delta).equals(initial){
hitList.add(pos.plus(delta);
oldSet.add(pos.plus(delta);
}
}
oldSet.remove(pos);
}
Again, I'd just like to know if my approach is wrong or there must be an error elsewhere in my code so i know what to look at.
Thanks beforehand!
You can't really add to a data structure while iterating over it, that is almost guaranteed to have unexpected results.
However, there is a simple enough solution to your issue. Just process each item recursively when you find that it needs to be added, and add it to a separate List. At the end of iteration, add everything in the List to the main Set. This avoids the issue of adding during iteration while still allowing you to to process the newly added items.
It would look something like this:
List<Position> toAdd = new LinkedList<>();
for(Position pos : oldSet){
for(Delta delta : deltas){
addIfGoodAndRecurse(pos, delta, toAdd);
}
}
And then you can use this helper method to add the item if it meets your conditions and also recursively process added items. Note you will need to change the method signature to pass in your board, initial, and hitList if they are local variables. I didn't know their types or whether they were global variables or fields, so I couldn't really add them in the example.
private void addIfGoodAndRecurse(Position pos, Delta delta, List<Position> toAdd) {
Position toCheck = pos.plus(delta);
if(board.getTokenAt(toCheck.equals(initial))) {
hitList.add(toCheck);
toAdd.add(toCheck);
for (Delta recursionDelta : deltas) {
addIfGoodAndRecurse(toCheck, recursionDelta, toAdd);
}
}
}
I don't have your code, so I can't test this. The idea should work fine, but you may need to make slight modifications.
You can iterate through new elements added to a list that you're iterating if you add them to the end of the list and iterate through it using an index and the get() method, not through an Iterator. You can also use the Set as you are doing now, but only to make sure you only add unique items to your collection.
List<Position> list = new ArrayList<>(oldSet);
for (int i = 0; i < list.length; ++i) { // NB list.length could be different each time
Position pos = list.get(i);
for(Delta delta : deltas){
if(board.getTokenAt(pos.plus(delta).equals(initial){
hitList.add(pos.plus(delta));
if (oldSet.add(pos.plus(delta))) // Check if it already exists in the list
list.add(pos.plus(delta));
}
}
oldSet.remove(pos);
}

How to Determine If a Collection Is Empty

I have a 3 dimensional ArrayList and I want to determine if it is empty or not. There is an exception called EmptyCollectionException which is not part of java standard library and hence I'm not allowed to use it.
Is there a way to accomplish that using a native java exception or function?
The 3D List is constructed as follow:
public void makeRandomCardListForLearning (Course courseToBeMadeRandom) {
List<List<List<Card>>> course = new ArrayList<List<List<Card>>>();
for(Chapter chptr: courseToBeMadeRandom.getChapterList()) {
List<List<Card>> chapter = new ArrayList<List<Card>>();
course.add(chapter);
for(Deck dck: chptr.getDeckList()) {
List<Card> deck = new LinkedList<Card>();
chapter.add(deck);
for(Card crd: dck.getCardList()) {
if(dck.isTheCardDueToday(crd.getLastDate())) {
deck.add(crd);
}
}
Collections.shuffle(deck);
}
}
}
As I go through course, chapter and deck I create a List for each one. There is only one course, many chapters, many decks and of course many cards which are saved under deck doublyLinkedList if they pass the pre-condition. If no card passes the condition, I have a 3D list which exists but has no cards. And I want to determine that If no card exists in the list, then the user receives an error message.
In fact I only need the cards. But I also need to know in which deck each card resides at the moment. If I just make a list and go through all chapters and decks and put cards in that list based on the condition then I have no clue in which chapter and deck each card resides. That can be solved by maybe adding two attributes to the card class. But that was a mistake as we designed the system and adding them now costs a lot of change in other parts of the program. Each index in course List represents the chapter number and each index in chapter list represents the deck number. I solved the problem that way.
This should do it:
public static boolean isEmpty(List<List<List<Card>>> list3d) {
return list3d.stream().flatMap(llc -> llc.stream()).flatMap(lc -> lc.stream()).count() == 0;
}
It takes into account that the outer lists may contain empty inner lists. It deems the entire 3D list empty if there are no cards in it.
you can do something like this
List<List<List<Card>>> course = new ArrayList<List<List<Card>>>();
// some possible codes
boolean check = course.isEmpty()
// other possible codes
if (check) {
// do something
}
or any arraylist you want to check or any way you want to reach your goal

Assigning New Object to a Generic Array Index

I'm POSITIVE that my title for this topic is not appropriate. Let me explain. The purpose of this is to duplicate a "Profile" application, where I have a profile and so would you. We both have our own followers and in this example, we both follow each other. What this method is needed to return is a cross reference based on whom you follow that I do not. I need this method to return to me a recommended Profile object that I do not already have in my array. Right now I'm having a difficult time with one line of code within a particular method.
One of my classes is a Set class that implements a SetInterface (provided by my professor) and also my Profile class that implements a ProfileInterface which was also provided. In my code for the Profile class, I have the following object: private Set<ProfileInterface> followBag = new Set<ProfileInterface>(); which utilizes the Array bag methods from my Set class with the ProfileInterface methods I've made.
Here is the method (not complete but can't move further without my problem being explained):
public ProfileInterface recommend(){
Set<ProfileInterface> recommended;
ProfileInterface thisProfile = new Profile();
for(int index = 0; index < followBag.getCurrentSize(); index++){
Set<ProfileInterface> follows = followBag[index].toArray();
for(int followedFollowers = 0; followedFollowers < follows.getCurrentSize(); followedFollowers++) {
if()
//if Profile's do not match, set recommended == the Profile
}
}
return recommended;
}
The purpose of this method is to parse through an array (Profile as this example) and then take each of those sub-Profiles and do a similar action. The reason for this much like "Twitter", "Facebook", or "LinkedIn"; where each Profile has followers. This method is meant to look through the highest Profiles follows and see if those subProfiles have any followers that aren't being followed by the highest one. This method is then meant to return that Profile as a recommended one to be followed. This is my first dealing with Array Bag data structures, as well as with generics. Through "IntelliJ", I'm receiving errors with the line Set<ProfileInterface> follows = followBag[index].toArray();. Let me explain the reason for this line. What I'm trying to do is take "my" profile (in this example), and see who I'm following. For each followed profile (or followBag[index]) I wish to see if followBag[index][index] == followBag[index] and continue to parse the array to see if it matches. But, due to my confusion with generics and array bag data structures, I'm having major difficulties figuring this out.
I'd like to do the following:
//for all of my followers
//look at a particular followed profile
//look at all of that profile's followers
//if they match one of my followers, do nothing
//else
//if they don't match, recommend that profile
//return that profile or null
My problem is that I do not know how to appropriately create an object of a Profile type that will allow me to return this object
(in my method above, the line Set<ProfileInterface> follows = followBag[index].toArray();)
I'm trying to make an index of my Profile set to an object that can later be compared where my difficulties are. I'd really appreciate any insight into how this should be done.
Much appreciated for all help and Cheers!
When you do:
Set<ProfileInterface> follows = followBag[index].toArray();
you're trying to use Set as Array. But you can't.
Java will not allow, because Set and Array are different classes, and Set does not support [] syntax.
That is why you get error. For usefollowBag as Array you have to convert it:
ProfileInterface[] profileArray = followBag.toArray(new ProfileInterface[followBag.size()]);
for(int i=0; i<profileArray.length; i++){
ProfileInterface profile = profileArray[i];
//do what you would like to do with array item
}
I believe, in your case, you don't need assign Set object to generic Array at all. Because you can enumerate Set as is.
public class Profile {
private Set<ProfileInterface> followBag = new HashSet<Profile>();
...
public Set<ProfileInterface> recommended(){
Set<ProfileInterface> recommendSet = new HashSet<ProfileInterface>();
for(Profile follower : followBag){
for(Profile subfollower : follower.followBag){
if(!this.followBag.contains(subfollower)){
recommendSet.add(subfollower);
}
}
}
return recommendSet;
}
}
I also added possibility of returning list of recommended profiles, because there is may be several.

Only one instance of object from ListIterator moves

I am working on a game project. So far so good, but i just stuck on ome basic thing and i cant find a solution and make it work properly. I decided to come here and ask you ppl of suggestions.
PROBLEM:
First, I had 2 levels with one bot in each of them. Later i noticed, that only the bot in the first level updates its behavior. If i only load the next level, the bots update method is not called and i dotn know why.
I printed the ListIterator in to the console and the bot is there. But when i iterate trough the list in the main update method it seem it doesnt call the objects update method in it. I can still move with player and take diamonds from the map which both of them are also the part of the list so those methods are called. I can provide you with some smaller code blocks if you need to get some info on some specific things if i have them or not, just leave it in the comment. Here are some major blocks which in my opinion arent working proper.
If only the bot in the first level moves, i made another 4 bots to it. Only the first instance of Bot moves. All other items of the same class do nothing.
0.Declaration:
private ArrayList<AbstractObject> supp = new ArrayList<AbstractObject>();
private ListIterator<AbstractObject> objects=supp.listIterator();
1.Main update method:
public void update() {
resetList(); //sets the cursor at begining
if(menu.getChoice()==-1){
menu.update();
}
else if(menu.getChoice()==2)
System.exit(0);
else if(menu.getChoice()==0){
if(currentLevel>lvlm.getLevel() || currentLevel<lvlm.getLevel()){
clearList(); //remove all items in the list
init(lvlm.getLevelPath());
currentLevel=lvlm.getLevel();
}
while(objects.hasNext()){
objects.next().update(); //calls all updates from each object in the list
}
}
}
Update method in the Bot Class:
public void update() {
movingCount++;
switch(getFacing()){
case 2:
moved=true;
setFacing(2);
setVectorX(-0.5);
break;
case 3:
moved=true;
setFacing(3);
setVectorX(0.5);
break;
case 0:
case 1:
setVectorX(0);
moved=false;
}
if(movingCount>=200){
setFacing(randInt(0,3));
movingCount=0;
}
moveOnX(); //updates pos
moveOnY(); //updates pos
getAnimationL().runAnimation();
getAnimationR().runAnimation();
}
EDIT_1:
Ok so the bots only in the first line in the file move.
LEVEL 1
P-player
B-bots
D-diamonds
1-walls
1111111 B B
1P D 1
11111 1
1F 1 B
1111111
B B B
Any ideas why only first line bots move? Other line objects works properly.
Iterators only work once. You seem to be initialising the iterator once and then expecting it to work each time update is called.
Three options:
(Bad) reinitialise the iterator in update:
objects = supp.iterator();
(Better) don't use an iterator; use a for loop:
for (AbstractObject obj: supp) {
obj.update();
}
(Best) use a stream:
supp.stream().forEach(AbstractObject::update);
If the update could potentially remove an item then your best option is to remove them after you've processed the list. For example, create a boolean method in AbstractObject called shouldBeRemoved. Then you can use the following:
supp.removeIf(AbstractObject::shouldBeRemoved);
After you have used one of the three methods above to process the list.

Categories