To see how effective the method extraction technique can be, we will first try out a simple example on .filter() in the Twitter stream filtering code:
observeTwitterStream(configuration, filterQuery)
.sample(2700, TimeUnit.MILLISECONDS)
.map(StockUpdate::create)
.filter(stockUpdate -> {
for(String keyword : trackingKeywords) {
if (stockUpdate.getTwitterStatus()
.contains(keyword)) {
return true;
}
}
return false;
})
The .filter() block here is responsible for the removal of tweets that do not contain the keywords. Let's make that explicit by extracting a method:
containsAnyOfKeywords()
So, the block before will become this:
observeTwitterStream(configuration, filterQuery)
.sample(2700, TimeUnit.MILLISECONDS)
.map(StockUpdate::create)
.filter(containsAnyOfKeywords(trackingKeywords))
Also, the extracted method contains the following:
@NonNull
private Predicate<StockUpdate> containsAnyOfKeywords(String[] trackingKeywords) {
return stockUpdate -> {
for(String keyword : trackingKeywords) {
if (stockUpdate.getTwitterStatus().contains(keyword)) {
return true;
}
}
return false;
};
}
In the last code block, we can see that it returns a lambda that conforms to the type of Predicate<StockUpdate>, which is required for the .filter() method.
Extracting a method made .filter() more self-descriptive, and now we do not need to analyze the details of the implementation to understand what is happening. Basically, we replaced the lower-detail implementation with a higher-level concept.
This can be done by following a few simple steps:
- Select the block that needs to be extracted:

- Right-click on and select the option of Refactor->Extract->Method...:

- Enter a name for a new method:

Proficient users who know their shortcuts by heart will make this even faster.