[Solved]Randomize the List from Sponge's GetRegistry

I know these seem like basic questions…but that is the level I’m at…basic. So now all i’m trying to do is get more help

thanks …

Beautiful! ok…so what is the t -> t.get…is that an implmentation of something?

is there something basic that could help with me understanding that part of the code you gave as an example? I’m willing to learn…just having to start :smiley: please and thank you

It is a lamda expression of a FunctionalInterface, specifically a Predicate<EntityType>.

hmm very it seems mighty useful…I’m gonna have to look it up a bit more…
Also Quick question…it seems that the

		 			EntityType listResult = eList.get(rand.nextInt(eList.size()));

isgetting an illegal argument Exception telling me that the bound must be positive…but that list shouldn’t be empty…so how would I make an != to not make it empty? if that makes sense.

Try this.

1 Like

right then, so in Java the -> essentially means do for all in list. so the T (in this case stands for “type” as in entity type. means the current in the list … index is the name for a single part in a list, but oh well. so after the -> is the code that is repeated for each and every one in the list.

so the t.getEntityClass is
EntityType.getEntityClass()

so overall it just filters out all entitytypes that are not monsters.

sorry for all of the issues, I still am really tired, and i personally very rarly deal with EntityTypes.

so that part you just need to have this line before.

if(eList.isEmpty()){
  return;
}

however it should not be returning a empty list.

edit:
just seen your previous issue and where you got the original code from XD use the original code that was provided by a SpongeDev

		List<Class<? extends Entity>> classes = ImmutableList.of(
			Monster.class
		);
		List<EntityType> cet = Sponge.getRegistry().getAllOf(EntityType.class).stream().filter(x -> classes.stream().anyMatch(y -> y.isAssignableFrom(x.getEntityClass()))).collect(Collectors.toList());

if you want to try my slightly neater code (the SpongeDev gave you the option for Monsters and Animals, this will be faster and just for Monsters

		List<EntityType> cet = Sponge.getRegistry().getAllOf(EntityType.class).stream().filter(x -> x.isAssignableFrom(x.getEntityClass()))).collect(Collectors.toList());

YESSSSS This!This is what I was missing!!! OK . Yes soo from

 			//List<String> list = Arrays.asList("blaze","cave_spider","creeper","enderman","endermite","giant","husk","magma_cube","silverfish","skeleton","slime","spider","vex","witch","wither_skeleton","zombie","zombie_pigman","NONE");
 			//Random rand = new Random();
 			//String listResult = list.get(rand.nextInt(list.size()));

To:

 				List<Class<? extends Entity>> classes = ImmutableList.of(
 					Monster.class
 				);
 				List<EntityType> list = Sponge.getRegistry().getAllOf(EntityType.class).stream().filter(x -> classes.stream().anyMatch(y -> y.isAssignableFrom(x.getEntityClass()))).collect(Collectors.toList());
	 			Random rand = new Random();
		 		EntityType listResult = list.get(rand.nextInt(list.size()));
	 			Sponge.getServer().getBroadcastChannel().send(Text.of("This is the list: " + list));

Perfect!!! Thank you so much!!!

glad to help, now if you will excuse me I have about a weeks sleep to catch up on, hopfully after that Ill be able to code properly again.

1 Like

What I would even go as far as suggesting though is that if you want to filter all EntityTypes based on a sub interface of Entity (such as Monster), I’d save the “filter” so to speak in a final field like so:

@Plugin(whatevergoeshere)
public class MyPlugin {

  private final Predicate<EntityType> ENTITY_FILTER = (type) -> {
    return Monster.class.isAssignableFrom(type.getEntityClass());
  } 

  private Collection<EntityType> validEntityTypes;


  @Listener
  public void someListener(ServerStartedEvent e) {
    this.validEntityTypes = Sponge.getRegistry().getAllOf(EntityType.class)
      .stream()
      .filter(ENTITY_FILTER)
      .collect(Collectors.toList());
  }
}

The reasoning for storing this as fields is that ideally, EntityTypes are registration locked at a certain point of the game life cycle (usually by LoadCompleteEvent). Since you can store this list that you’ve filtered yourself at this point, you can base on that list for whatever needs you have afterwards without incurring additional lookups at later points in time (requesting the same list to be filtered the same way over and over again).

I think the overall confusion earlier was that Java Generics are compile time type aware such that the compiler makes the guarantee that you have the correct type of objects within a gentrified method/object/collection/etc. In this case, having the GameRegistry method taking a type Class<T extends CatalogType> which EntityType satisfies, but Entity does not.

I’d recommend reading the Java tutorials on generics here and even the wiki article here since you can read on how to use them and the motivation behind them. There’s a lot in SpongeAPI that uses generics for the benefits they provide, and then sometimes they can get a little hairy

Hope this helps having a clearer understanding on the situation and maybe further explain some of the concepts behind some design decisions.