Jump to content

Java 8 - Predicates


Purple

Recommended Posts

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
Link to comment
Share on other sites

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
Link to comment
Share on other sites

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

Link to comment
Share on other sites

  • 1 month later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

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