简体   繁体   中英

Iterating over a subset of a set

I have a set oneHundredInactiveSynapses and I would like to manipulate a random 21 of the 100 inactiveSynapses in that set and then stop. I feel like there should be a easy way to do this, but I just can't think of anything right now.

for (Synapse inactiveSynapse : oneHundredInactiveSynapses) {
    // I want to call a method on the inactiveSynapse like
        inactiveSynapse.setActiveState(true);
        // but I only want to do this to 21 of the synapses. How can I do this?
}

Other points:

  1. making oneHundredInactiveSynapses into an array is not an option
  2. I don't care which 21 become active

You can make a copy of the Set , shuffle and get the sub-list of first 21 elements -

List<Synapse> copy = new ArrayList<Synapse>(original);
Collections.shuffle(copy);
List<Synapse> sub = copy.subList(0, 21);
for(Synapse s : sub) { ... }

Convert the Set to an array, then access 21 random elements of the array. Your question says the set has only 100 elements so that should not be too expensive. Something along those lines is the only option if you can not select the concrete Set implementation or alter the code populating the set.

If you can alter the code populating the set, you could of course just have it stop once it added 21 elements. If you can inject your own Set implementation, you could have an implementation that provides a random ordering, and iterate over only the first 21 elements.

To make it a little random you could randomly choose ones to fire until you reach 21. Note that if you only have enough left to reach 21 you'll have to fire all of those so there is a bit of bias towards the synapses at the end.

    int chosen = 0;
    int left = oneHundredInactiveSynapses.size();
    java.util.Random rand = new java.util.Random();
    for (Synapse inactiveSynapse : oneHundredInactiveSynapses) {
        if(left-chosen>21) inactiveSynapse.setActiveState(true);
        else{
          if(rand.nextBoolean()){
            inactiveSynapse.setActiveState(true);
            chosen++;
            if(chosen==21) break;
          }
        }
        left--;
   }

But if you really don't care about randomness then just pick the first 21 using a count ie

   int count = 0;
   for(Synapse inactiveSynapse : oneHundredInactiveSynapses){
     if(count==21) break;
     inactiveSynapse.setActiveState(true);
     count++;

   }

If you are okay with the first 21 you can do:

int count = 0
for (Synapse inactiveSynapse : oneHundredInactiveSynapses) {
    if(count < 21){
        inactiveSynapse.setActiveState(true);  
        count++;        
    }else{
         break; 
    }

}

If you want random you could do:

java.util.Random rand = new java.util.Random();
    int count = 0
    for (Synapse inactiveSynapse : oneHundredInactiveSynapses) {
        if(rand.nextInt(100) % 2){
            next;
        }
        if(count < 21){
            inactiveSynapse.setActiveState(true); 
             count++;         
        }else{
           break; 
        }

This would go to the next element if the random number is even, until you get to 21, which would break. }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM