Java 8 Features with Examples

Filed Under: Java
Java8 Features

Java 8 was released on 18th March 2014. That’s a long time ago but still many projects are running on Java 8. It’s because it was a major release with a lot of new features. Let’s look at all the exciting and major features of Java 8 with example code.

Quick Overview of Java 8 Features

Some of the important Java 8 features are;

  1. forEach() method in Iterable interface
  2. default and static methods in Interfaces
  3. Functional Interfaces and Lambda Expressions
  4. Java Stream API for Bulk Data Operations on Collections
  5. Java Time API
  6. Collection API improvements
  7. Concurrency API improvements
  8. Java IO improvements

Let’s have a brief look on these Java 8 features. I will provide some code snippets for better understanding the features in a simple way.

1. forEach() method in Iterable interface

Whenever we need to traverse through a Collection, we need to create an Iterator whose whole purpose is to iterate over, and then we have business logic in a loop for each of the elements in the Collection. We might get ConcurrentModificationException if the iterator is not used properly.

Java 8 has introduced forEach method in java.lang.Iterable interface so that while writing code we focus on business logic. The forEach method takes java.util.function.Consumer object as an argument, so it helps in having our business logic at a separate location that we can reuse. Let’s see forEach usage with a simple example.

package com.journaldev.java8.foreach;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.function.Consumer;
import java.lang.Integer;

public class Java8ForEachExample {

	public static void main(String[] args) {
		//creating sample Collection
		List<Integer> myList = new ArrayList<Integer>();
		for(int i=0; i<10; i++) myList.add(i);
		//traversing using Iterator
		Iterator<Integer> it = myList.iterator();
			Integer i =;
			System.out.println("Iterator Value::"+i);
		//traversing through forEach method of Iterable with anonymous class
		myList.forEach(new Consumer<Integer>() {

			public void accept(Integer t) {
				System.out.println("forEach anonymous class Value::"+t);

		//traversing with Consumer interface implementation
		MyConsumer action = new MyConsumer();


//Consumer implementation that can be reused
class MyConsumer implements Consumer<Integer>{

	public void accept(Integer t) {
		System.out.println("Consumer impl Value::"+t);

The number of lines might increase but forEach method helps in having the logic for iteration and business logic at separate place resulting in higher separation of concern and cleaner code.

2. default and static methods in Interfaces

If you read forEach method details carefully, you will notice that it’s defined in Iterable interface but we know that interfaces can’t have a method body. From Java 8, interfaces are enhanced to have a method with implementation. We can use default and static keyword to create interfaces with method implementation. forEach method implementation in Iterable interface is:

default void forEach(Consumer<? super T> action) {
    for (T t : this) {

We know that Java doesn’t provide multiple inheritance in Classes because it leads to Diamond Problem. So how it will be handled with interfaces now since interfaces are now similar to abstract classes?

The solution is that compiler will throw an exception in this scenario and we will have to provide implementation logic in the class implementing the interfaces.

package com.journaldev.java8.defaultmethod;

public interface Interface1 {

	void method1(String str);
	default void log(String str){
		System.out.println("I1 logging::"+str);
	static void print(String str){
		System.out.println("Printing "+str);
	//trying to override Object method gives compile-time error as
	//"A default method cannot override a method from java.lang.Object"
//	default String toString(){
//		return "i1";
//	}
package com.journaldev.java8.defaultmethod;

public interface Interface2 {

	void method2();
	default void log(String str){
		System.out.println("I2 logging::"+str);


Notice that both the interfaces have a common method log() with implementation logic.

package com.journaldev.java8.defaultmethod;

public class MyClass implements Interface1, Interface2 {

	public void method2() {

	public void method1(String str) {

	//MyClass won't compile without having it's own log() implementation
	public void log(String str){
		System.out.println("MyClass logging::"+str);

As you can see that Interface1 has static method implementation that is used in MyClass.log() method implementation. Java 8 uses default and static methods heavily in Collection API and default methods are added so that our code remains backward compatible.

If any class in the hierarchy has a method with the same signature, then default methods become irrelevant. The Object is the base class, so if we have equals(), hashCode() default methods in the interface, it will become irrelevant. That’s why for better clarity, interfaces are not allowed to have Object default methods.

For complete details of interface changes in Java 8, please read Java 8 interface changes.

3. Functional Interfaces and Lambda Expressions

If you notice the above interface code, you will notice @FunctionalInterface annotation. Functional interfaces are a new concept introduced in Java 8. An interface with exactly one abstract method becomes a Functional Interface. We don’t need to use @FunctionalInterface annotation to mark an interface as a Functional Interface.

@FunctionalInterface annotation is a facility to avoid the accidental addition of abstract methods in the functional interfaces. You can think of it like @Override annotation and it’s best practice to use it. java.lang.Runnable with a single abstract method run() is a great example of a functional interface.

One of the major benefits of the functional interface is the possibility to use lambda expressions to instantiate them. We can instantiate an interface with an anonymous class but the code looks bulky.

Runnable r = new Runnable(){
			public void run() {
				System.out.println("My Runnable");

Since functional interfaces have only one method, lambda expressions can easily provide the method implementation. We just need to provide method arguments and business logic. For example, we can write above implementation using lambda expression as:

Runnable r1 = () -> {
			System.out.println("My Runnable");

If you have single statement in method implementation, we don’t need curly braces also. For example above Interface1 anonymous class can be instantiated using lambda as follows:

Interface1 i1 = (s) -> System.out.println(s);

So lambda expressions are a means to create anonymous classes of functional interfaces easily. There are no runtime benefits of using lambda expressions, so I will use it cautiously because I don’t mind writing a few extra lines of code.

A new package java.util.function has been added with bunch of functional interfaces to provide target types for lambda expressions and method references. Lambda expressions are a huge topic, I will write a separate article on that in the future.

You can read complete tutorial at Java 8 Lambda Expressions Tutorial.

4. Java Stream API for Bulk Data Operations on Collections

A new has been added in Java 8 to perform filter/map/reduce like operations with the collection. Stream API will allow sequential as well as parallel execution. This is one of the best features for me because I work a lot with Collections and usually with Big Data, we need to filter out them based on some conditions.

Collection interface has been extended with stream() and parallelStream() default methods to get the Stream for sequential and parallel execution. Let’s see their usage with a simple example.


import java.util.ArrayList;
import java.util.List;

public class StreamExample {

	public static void main(String[] args) {
		List<Integer> myList = new ArrayList<>();
		for(int i=0; i<100; i++) myList.add(i);
		//sequential stream
		Stream<Integer> sequentialStream =;
		//parallel stream
		Stream<Integer> parallelStream = myList.parallelStream();
		//using lambda with Stream API, filter example
		Stream<Integer> highNums = parallelStream.filter(p -> p > 90);
		//using lambda in forEach
		highNums.forEach(p -> System.out.println("High Nums parallel="+p));
		Stream<Integer> highNumsSeq = sequentialStream.filter(p -> p > 90);
		highNumsSeq.forEach(p -> System.out.println("High Nums sequential="+p));



If you will run above example code, you will get output like this:

High Nums parallel=91
High Nums parallel=96
High Nums parallel=93
High Nums parallel=98
High Nums parallel=94
High Nums parallel=95
High Nums parallel=97
High Nums parallel=92
High Nums parallel=99
High Nums sequential=91
High Nums sequential=92
High Nums sequential=93
High Nums sequential=94
High Nums sequential=95
High Nums sequential=96
High Nums sequential=97
High Nums sequential=98
High Nums sequential=99

Notice that parallel processing values are not in order, so parallel processing will be very helpful while working with huge collections.

Covering everything about Stream API is not possible in this post, you can read everything about Stream API at Java 8 Stream API Example Tutorial.

5. Java Time API

It has always been hard to work with Date, Time, and Time Zones in java. There was no standard approach or API in java for date and time in Java. One of the nice addition in Java 8 is the java.time package that will streamline the process of working with time in java.

Just by looking at Java Time API packages, I can sense that they will be very easy to use. It has some sub-packages java.time.format that provides classes to print and parse dates and times and provides support for time zones and their rules.

The new Time API prefers enums over integer constants for months and days of the week. One of the useful classes is DateTimeFormatter for converting DateTime objects to strings. For a complete tutorial, head over to Java Date Time API Example Tutorial.

6. Collection API improvements

We have already seen forEach() method and Stream API for collections. Some new methods added in Collection API are:

  • Iterator default method forEachRemaining(Consumer action) to perform the given action for each remaining element until all elements have been processed or the action throws an exception.
  • Collection default method removeIf(Predicate filter) to remove all of the elements of this collection that satisfy the given predicate.
  • Collection spliterator() method returning Spliterator instance that can be used to traverse elements sequentially or parallel.
  • Map replaceAll()compute()merge() methods.
  • Performance Improvement for HashMap class with Key Collisions

7. Concurrency API improvements

Some important concurrent API enhancements are:

  • ConcurrentHashMap compute(), forEach(), forEachEntry(), forEachKey(), forEachValue(), merge(), reduce() and search() methods.
  • CompletableFuture that may be explicitly completed (setting its value and status).
  • Executors newWorkStealingPool() method to create a work-stealing thread pool using all available processors as its target parallelism level.

8. Java IO improvements

Some IO improvements known to me are:

  • Files.list(Path dir) that returns a lazily populated Stream, the elements of which are the entries in the directory.
  • Files.lines(Path path) that reads all lines from a file as a Stream.
  • Files.find() that returns a Stream that is lazily populated with Path by searching for files in a file tree rooted at a given starting file.
  • BufferedReader.lines() that return a Stream, the elements of which are lines read from this BufferedReader.

Miscellaneous Java 8 Core API improvements

Some miscellaneous API improvements that might come handy are:

  1. ThreadLocal static method withInitial(Supplier supplier) to create instances easily.
  2. The Comparator interface has been extended with a lot of default and static methods for natural ordering, reverse order, etc.
  3. min(), max() and sum() methods in Integer, Long and Double wrapper classes.
  4. logicalAnd(), logicalOr() and logicalXor() methods in Boolean class.
  5. method to get an ordered Stream over the ZIP file entries. Entries appear in the Stream in the order they appear in the central directory of the ZIP file.
  6. Several utility methods in Math class.
  7. jjs command is added to invoke Nashorn Engine.
  8. jdeps command is added to analyze class files
  9. JDBC-ODBC Bridge has been removed.
  10. PermGen memory space has been removed

That’s all for Java 8 features with example programs. If I have missed some important features of Java 8, please let me know through comments.


  1. Anindya Mukherjee says:

    Nice narrative, very well explained, keep it up!

  2. anish says:

    seems JAVA 10 more than JAVA IO in picture at the top of Java 8 features.

    1. Giri says:

      Example for every feature could be helpful

  3. Rajasekhar D says:

    I have tried to display the value of a variable using the forEach loop using sysout, no output is displayed.

    1. Rahul Chaudhary says:

      Paste ur code snippet

  4. Jenifer says:

    Hi Here that is saying

    MyConsumer action = new MyConsumer();

    Error:(9, 8) java: class Java8ForEachExample is public, should be declared in a file named

    1. ANKIT says:

      Here, is no pointers provided on CompletableFuturable introduced in Java 8?

  5. Harish says:

    you could have use highNumsSeq.forEach(System.out::println);
    in one of your example

  6. Kannan says:

    Very clear and nice explaination. Thanks.
    can you please let me know how to invoke the interface1,interface2 log method in implemented class?

  7. Binh Thanh Nguyen says:

    Thanks, nice post

  8. Anusha says:

    Hi Pankaj,

    While I was practicing the forEach() I got concurrent modification exception. As you have explained, before java 8 version we used to get concurrent modification exception if we don’t use iterator properly. One of the Java 8 feature forEach() solves the problem but I got concurrent Exception with forEach().
    Please find the below code which throws the Exception.

    public class ForEachTFeatureTest {
    public static void main(String[] args) {
    List myList = new ArrayList();
    myList.forEach(new Consumer() {

    public void accept(Integer t) {
    if(t == 1){
    System.out.println(“forEach anonymous class Value::”+t);


    Is my understanding bout forEach() is proper?

    1. Pankaj says:

      The forEach() is a convenience method to traverse through the elements. It works in the same way as the iterator. You are getting ConcurrentModificationException because you are modifying the list elements count by calling the remove() method on the list.

      1. Sachin says:

        Hi Pankaj,

        If forEach() also gives ConcurrentModificationException because you are modifying the list elements ,
        What is advantages of use it over Iterator.

        1. Pankaj says:

          It’s a convenience method, reduces the code size.

        2. Rohan says:

          This issue also called as FAIL-FAST

  9. Jeelan Yelidandla says:

    (s) -> System.out.println(s);

    in above statment if its one parameter no () parantasis required. you can write s->System.out.println(s);
    method ref; System.out::println

  10. vinay says:

    hahsmap internal working has been changed from java 8. If number of keys with same hashcode exceeds a value, internally values are stored in binary tree than linked list.

  11. Shanu says:

    Hi Pankaj Ji,

    I am not able to install java version 8 in linux mint for SAP Gui support
    i am try to install but java packeg is not abelable in below commands

    $sudo add-apt-repository ppa:webupd8team/java

    $sudo apt-get update

    $sudo apt-get install oracle-java8-installer
    $ java -version java version “1.8.0_201”
    Java(TM) SE Runtime Environment (build 1.8.0_201-b09) Java HotSpot(TM) 64-Bit Server VM (build 25.201-b09, mixed mode)

  12. kuladeep patil says:

    before Apr 2014 you posted this valuable information about Java8, Really Incredible man ….. thanks Pankaj

  13. Divya Gupta says:

    The new method in Iterator interface is forEachRemaining and not forEach.

  14. Mani Raman says:

    Thanks for the article, clear and easy examples. When migrating my project from Java-7 to Java-8, can you suggest what are the things I should look into ? Some features might be obsolete and some might got removed in Java-8.

    1. Satyajit says:

      As it upgrading nothing worry about existing , it will work as it is without any changes.

      But if u want to upgrade based on JDK 1.8 Features on your project then you need to identify the place where you have big method, lines/statements of code can be replaced easily with JDK 1.8, rebuild , deploy etc.

  15. chsdk says:

    Great article, but the highlighting of sentences is not very user friendly with this dark highlighting over black text.

  16. Krishna Mohapatra says:

    Very useful and Informative article. Thanks for posting it.

  17. UnboxHow says:

    I often visit your website to keep updated. I am java dev as well as a blogger. However, I am a completely new bee in the blogging field.

    I have noticed one thing and also wanted to let you know. Every time I see your highlighted word, I just wanted to see them with some paddings.
    Hope You will understand What I mean.

    1. Pankaj says:

      Did you mean the code tags with some padding in front of them? Or you mean “pre” tags that I use to show lines of codes?

      1. UnboxHow says:

        Yes, code tag with some left, right padding.

      2. JustinTime says:

        I agree with UnboxHow. The black background of the highlighted text has no padding which makes it difficult to read when the white text touches the edges and blends into the white background of the website.

        1. Pankaj says:

          Thanks for the feedback, I have added right and left padding to the code tags. Now reading code should feel easier.

  18. Sangumithra Ashokan says:

    Very interesting article,, Explanation are very good with examples

  19. Snehasish says:

    Nice article! Keep up the good work 🙂

  20. Sudhakar says:

    Thanks for great tutorial

  21. Ravi Gupta says:

    Jcmd for thread dump in java8

    1. Manikanta Sanambatla says:

      u have java 8 dumps ?

  22. vellai varanan says:

    very good to read.good analysis.
    thanks m pankaj

  23. Meghala Devi says:

    Thanks a lot Pankaj for the wonderful article.

  24. Md. Ahsan Kabir says:

    Among them, I think stream, time and lambda expression API are the best features. Thanks to #pankaj for this awesome tutorial.

  25. BALAGURIAH says:

    okk but i think new version

    1. Pankaj says:

      Don’t we all, Balaguriah? Don’t we all….

  26. Ashish Balani says:

    Also, the HashMaps now use a Tree instead of a LinkedList when number of linked nodes cross a threshold. The default TREEIFY threshold is 8, and default UNTREEIFY threshold is 6. This means, when number of nodes cross 8 a tree structure would be formed and if you remove nodes the tree structure would change after it reaches 6.

  27. Rumpee says:

    Static methods in Functional Interface .

    interface MyFunctionalInterface

    public int addMethod(int a, int b);

    static void method1()
    System.out.println(“Static method1 implementation”);

    static void method2()
    System.out.println(“Static method2 implementation”);

    public class StaticMethodDemo implements MyFunctionalInterface{

    * By default static methods are not available to implementation class .
    * So no overriding .
    * */

    static void method2()
    System.out.println(“Static method2 implementation”);

    public void method1()
    System.out.println(“Instance method1 implementation”);

    private static void method3()
    System.out.println(“Static method3 implementation”);

    public static void main(String[] args) {



    public int addMethod(int a, int b) {
    // TODO Auto-generated method stub
    return 0;

    Few points on Static Methods in Interface with Java 1.8

    General utility methods are to be added as static methods in interface which are not related to Object State
    The methods can be called with Interface name not implementation object reference or implementation class name
    Not available by default to implementation class
    Overriding not applicable for interface static method as it is not available by default to implementation class
    Main method can be declared inside interface .
    Can execute main method inside interface .

  28. Mridula says:

    Here are some features of Java 8:
    1. Implementation of Lambda expressions.
    2. Date and Time API.
    3. A lightweight, high performance implementation of JavaScript engine is integrated to JDK.
    4. Improved Security

  29. Jyoti Namdeo says:

    It was a great help.

  30. Ahmad Sayeed says:

    Thank you for sharing . Please keep it up.

  31. Abdulaziz says:

    Nice and easy-to-follow article about main java 8 features. Thank you.

  32. kalpesh soni says:

    Rest of the stuff was REALLY useful but

    lambda was the lamest

    people wrote entire books about why lambda expressions are elegant and useful

    and all you can say is

    I dont mind extra code? really?

    1. Pankaj says:

      Could you show me an example where lambda expressions brings real benefits such as better performance (like StringBuilder brings over StringBuffer)? Ultimately lambda expression reduces the code size and if not used wisely, it could get messy. That’s why I mentioned that if you are not too familiar with it, better go with the basics even if it cause few extra lines of code. I use it in my code but not all the time, I am still not comfortable with “method reference” (::) and still write System.out.println rather than System.out::println.

      1. Rahul kumar says:

        Lambda expression allowed us functional programming rather than reduces the code.
        “System.out.println vs System.out::println.”

      2. Ravi says:

        Because of functional programming when we compile code in java 8, there will be only one .class and no sub-class while in previous versions it creates sub-classes for anonymous classes.

  33. Mithila says:

    Thanks for the consolidate information and even links for elaborations 🙂

  34. Thirupathi says:

    wonderful information , And easy to understand

  35. hashem yousefi says:

    tnx. very nice

  36. Gaurav Jain says:

    Thanxxxxxxxxxxx Pankaj ,

    You saved my day , All information at one place … Thnxxx again 🙂

  37. Ajeet Patel says:

    Thanks a lot Pankaj. A very concise and self explanatory info and that too at a one place. 🙂

    1. Pankaj says:

      You are welcome Ajeet, appreciate the kind words.

  38. Nitin says:

    You can also discuss about method reference in this tutorial. Method reference is also a very important feature in Java 8

    1. Pankaj says:

      It’s good to know but it’s just to reduce number of lines of code.

  39. Tomasz Krzysztof says:

    Thank you!

  40. Valentino says:

    Pankaj, I guess when you say “Make sure your projects build patch is using Java 8 library.” you mean build path, right?

    1. Pankaj says:

      Yes, build path. corrected it.

  41. Rama says:

    In forEach example, MyConsumer should be static inner class not just inner class if we want to use that in main().

  42. Arvind says:

    You can override default interface. It wont complain.

  43. Harry S. Green says:

    Very helpful. I’m very grateful to see such topics discussed here.

  44. Krishnan K says:

    Good Article, Thanks a lot…

  45. Narendra b says:

    Simply superb

  46. Raj Rusia says:

    It’s very useful to know overview of new features of Java 8 in less time.

  47. jdk1.7 says:

    Is it me or these new features are turning the language into unreadable mess

  48. Mayur Patel says:

    Hello Sir,

    Could you please justify the statement “Performance Improvement for HashMap class with Key Collisions”.?

    How they have improved the HashMap class with Key Collisions?

    1. Dileep says:

      In Java 8 we have below changes,
      in case of collision till Java 7 it used to store values in linked list and the search order for link list is O(n), but in java 8 it forms binary tree (O(log(n))) instead of linked list. This makes search faster, this would be useful in case of billions of records getting collide for same hash key.

      1. Anand says:

        Prior to Java 8 collision results in a list structure at the bucket where as java 8 changes that implemention to tree

  49. BASAVARAJ says:

    Guys Functional programing are Already there in SCALA Language

  50. krishna says:

    interface MyInt1{
    default void log()
    System.out.println(“this is log file interface”);

    interface MyInt2{
    default int log()
    System.out.println(“hai this is another interface”);
    return 10;

    public class FunctInterface implements MyInt1,MyInt2{
    public static void main(String[] args) {
    FunctInterface f=new FunctInterface();
    //throws error please tell me how to solve
    public void log() {
    // TODO Auto-generated method stub

    1. kammiti krishna says:

      In the both interfaces method return type should be same.

  51. Bharath says:

    Good explanation

  52. Pradeep Kumar says:

    Hi Pankaj,

    very good article on Java8 and please provide me more information on the following topic of Java8.

    *******Collection API improvements**** if you provide more information it would be great help for all those whose are reading this article.

    thanks in advance Pankaj. Sr. Software Engineer @ Tech Mahindra.

  53. Dhanya says:

    Very clear explanation with samples.
    But contrary to you – there is benefit when using Lambda. In normal anonymous class implementation, new .Class files are created where as with Lambda no new .Class files are generated.

  54. Ranga says:

    Nice explanation of Java8 features.

  55. Deepak Shah says:

    Nice article.Brief and to the point.

    1. Debendra Dhinda says:

      A beautiful Updation

  56. neha says:

    great tutorial

  57. Jayhind Rajpoot says:

    Nice explanation for new features added in Java 8

  58. Venkat says:

    Simply superb!!!

  59. hitesh says:

    Thanks for this valuable Article

  60. Manoj says:

    Good Article

  61. ganesan says:

    very nice

  62. Chintan Kansara says:

    Nice article

  63. AMIT BANSAL says:

    Your understanding of java technologies are helping lot of people….Thanks a lot.

  64. Kailash CH Das says:

    New features explanation is very nice. Thanks a lot. Keep it up

  65. Ravi says:

    Nice article keep it up

  66. prabhath says:

    Nice article on java 8 new features.
    Thanks a lot.

  67. dhrumil says:

    // forEach example to print each element of list
    // in this case we are using method reference becasue
    // we are not doing anything with each element of collection
    // and just passing ito println method
    System.out.println(“Printing elements of list using forEach method : “);;

    // let’s do something to each element before printing
    // we will add comma after each element
    System.out.println(“Printing elements after adding comma: “); i -> System.out.print( i + “,”));

    // you can also use forEach with parallel stream
    // order will not be guaranteed
    System.out.println(“\nPrinting elements of list using parallel stream: “);

    listOfPrimes.parallelStream().forEach( i-> System.out.println(i*2));

  68. Prabu says:

    can you explain little more about FuctionalInterface and functional programming
    1.what is functional programming ?why .explain with real time scenario
    2.what is functional Interface and what purpose it has been introduced in java and what we can achieve with functional Interface
    3.without functional interface what we cant achieve in java 8?

  69. babita says:

    Good explanation. I would like to know the differences between Future and CompletableFuture

  70. Nobi Y says:

    Thanks a lot…Really beneficial

  71. Tayyab says:

    Very good stuff man, really helping and to the point!

  72. Nakul Shinde says:

    Nice article.. You explained really well.. Thanks and keep it up..

  73. Nari Chinni says:

    Really Nice & very useful stuff, But need to provide the examples for the 6 and 7th features.

    1. Pankaj says:

      I have already listed the important new methods in the Collection and Concurrency APIs with brief explanation, just use them and it should be easy to go.

  74. Rajiv says:

    Awesome contents !! please keep helping us the same way !

  75. Sathy\narayanan says:

    Very good stuff man, really i’m very happy that i gained many things in java from you!!!

    1. sifun nanda says:

      Stream parallelStream = (Stream) myList.parallelStream();

      In integer place i am getting error like: change project compliance and jre to 1.5. this erroe is coming in every integer place in code.

      p –> p > 90)—-here showing create local variable,create field ,parameter wht i should do?

      for(int i=0; i<100; i++) myList.add(i);—here in add its error lke chang to AddAll()…wht should i do?

  76. chandan kumar says:

    thanks a ton man, awesom tutorial 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *

Generic selectors
Exact matches only
Search in title
Search in content