Jump to content
View in the app

A better way to browse. Learn more.

OSBot :: 2007 OSRS Botting

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Java 8 - Predicates

Featured Replies

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>

  • Author

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. 

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...

Thanks for posting this... predicates are so useful.

Create an account or sign in to comment

Recently Browsing 0

  • No registered users viewing this page.

Account

Navigation

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.