Jump to content

Java 8 - Predicates


Recommended Posts

Posted

Introduction To Predicates

 

What is a Predicate in Java 8?

A predicate is a boolean-valued function. In Java 8, it's used primarily for it's functional properties as well as it's ability to result in a true or false statement. This is really useful when you need to filter collections without having to loop over a collection manually as the stream api allows you to also chain predicates.

P: X→ {true, false}

P being the predicate (value or reference passed in) and X represents the following truth statement resulting in true or false. This might be confusing at first, but I'll show examples later on how this makes sense and why you should use this over the commonly used Filter<T> in OSBot.

 

How is this any better than OSBot's Filter<T> api?

We can use predicates to chain logic expressions and filter as many conditions as me need to while keeping our logic nice and clean. We can combine two pedicates where we filter a collection where both condition are met or return the second if the first predicate returns false. 

 

 

Collection of Loaded NPS

 

List<NPC> where we'll be performing our filter

final List<NPC> loaded = getNpcs().getAll();

create a list of all loaded npcs in the area

 

 

Simple Predicate Filtering

 

A Predicate

final Predicate<NPC> exists = npc -> npc.exists();

This creates a predicate with the truth statement P(npc) : return true if npc exist

 

Using it inside a stream to filter a collection

final NPC getNpcWhere = loaded.stream().filter(exists).findFirst().orElse(null)

This will return the first match in the collection that matches the predicate truth statement that returned true or else returns a null NPC object.

 

 

 

Chaining Predicates

 

Two Predicates we're going to chain

final Predicate<NPC> exists = npc -> npc.exists();
final Predicate<NPC> isAttackable = npc -> npc.exists() && npc.hasAction("Attack") && !npc.isUnderAttack();

Predicate Chain were 2 Predicates return true

final NPC getNpcWhere = loaded.stream().filter(exists.and(isAttackable)).findFirst().orElse(null);

Here, we're simply chaining preidicates. We're filtering the collection where the the npc exists and it's attackable and if both 

 

This or That Predicates

 

Three Predicates we're going to chain

final Predicate<NPC> exists = npc -> npc.exists();
final Predicate<NPC> isInteractingLocally = npc -> npc.isInteracting(getPlayers().myPlayer());
final Predicate<NPC> isAttackable = npc -> npc.exists() && npc.hasAction("Attack") && !npc.isUnderAttack();

Alright, this is where the magic happens in a combat script! We can create 1 predicate query that should always return true then either return the second one or the third depending on the second returns true or not.

 

The logic behind this one is that in a combat script, you'd obviously want to return npcs attacking you before you attack a random npc right? So you can achieve this by doing a predicate or function.

 final NPC getNpcWhere = loaded.stream().filter(exists.and(isInteractingLocally.or(isAttackable))).findFirst().orElse(null);

We just made a really advanced logic filter in 1 line of code!

 

That's the power of using Predicates over a generic Filter<T>

  • Like 9
Posted

You didn't mention anything about execution time, you think it will be faster then a regular Filter? smile.png

 

Khaleesi

 

You're right, but we're talking about nano seconds here :P

 

It's not going to make a difference when it comes to RuneScape scripting. However, streams are a little bit slower than iterating over a collection using an iterator, but I'd rather have functionality and clarity of minimal performance when it comes to writing scripts. Some value speed over quality of life. Nice point out though. 

  • Like 1
Posted

You're right, but we're talking about nano seconds here tongue.png

 

It's not going to make a difference when it comes to RuneScape scripting. However, streams are a little bit slower than iterating over a collection using an iterator, but I'd rather have functionality and clarity of minimal performance when it comes to writing scripts. Some value speed over quality of life. Nice point out though. 

 

Was just wondering myself ^^

Whenever I wrote my scripts that are currently on the SDN, Predicates didn't exist yet... I could rewrite some points, but I doubt if it has any pros over then just iterating :D

 

I personally still like to loop through them, maybe I should start using them more and more :)

 

Khaleesi

  • 1 month later...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...