0
class Checker{
        
    void CheckingNameFromDeptCode(LinkedList<Employee1> empObj, String deptID) 
    {
            for (int i = 0; i < empObj.size(); i++) {
                if (empObj.get(i).getDeptID().equals(deptID)) {
                    System.out.println(empObj.get(i).getEmpName());
                }
            }
    }
}

This is the method I created to check for the employees for the inputed dept list. But I been told to use streams/lambda in java 8 for the iteration instead of the good old for loop I use.

Below is the main method.

import java.util.*;
public class Manager{

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        LinkedList<Employee1> employeeObj = new LinkedList<Employee1>();
        Checker empBusObj = new Checker();
        
        employeeObj.add(new Employee1("Souvik", "D1", "Development", "L1", "Kolkata"));
        employeeObj.add(new Employee1("Anirban", "D2", "HR", "L2", "Bangalore"));
        employeeObj.add(new Employee1("Joydeep", "D3", "Design", "L3", "Delhi"));
        employeeObj.add(new Employee1("Rakesh", "D2", "HR", "L4", "Pune"));
        System.out.print("Enter the choices : ");
        int ch = sc.nextInt();
        String deptInput; 
        String locInput;
        switch (ch) 
        {
            case 1:
            System.out.print("Enter the department code : ");
            deptInput = sc.next();
            deptInput = deptInput.toUpperCase();
            empBusObj.CheckingNameFromDeptCode(employeeObj, deptInput); 
            break;
tripleee
  • 175,061
  • 34
  • 275
  • 318
Souvik Guha
  • 37
  • 1
  • 7
  • 2
    *"I been told to use streams/lambda in java 8 for the iteration instead of the good old for loop I use."* Why, and by who? The suggestion I would make is use a for-each loop (also known as an "enhanced `for` loop") instead of iterating by index. Not everything needs to use streams just because. – kaya3 Sep 01 '21 at 11:08
  • 1
    Using a `LinkedList` and calling `get(int)` on it in a loop, even twice in a row, is very inefficient and counteracting any benefit you might have thought you gained from using `LinkedList` instead of `ArrayList`. As elaborated in [“When to use LinkedList over ArrayList in Java?”](https://stackoverflow.com/q/322715/2711488), you will almost never get a benefit from `LinkedList` anyway. – Holger Sep 01 '21 at 11:21
  • 1
    So, your method should use `List` as parameter, to not mandate a particular implementation and use `for(Employee1 e: empObj) if(e.getDeptID().equals(deptID)) System.out.println(e.getEmpName());` as suggested by kaya3, as this loop is not only easier to read, it avoids the problems of using random access operations on a `LinkedList`. The caller may still switch to `ArrayList` then, for efficiency, without a change to this method. – Holger Sep 01 '21 at 11:22

3 Answers3

2

If your question simply is "I need to use streams/lambdas", here's an example using streams:

public static void main(String[] args) {
    String deptID = "DPT-01";
    List<Employee> employees = new ArrayList<>();
   //                          UUID      DEPTID    NAME
    employees.add(new Employee("UID-01", "DPT-01", "Foo"));
    employees.add(new Employee("UID-02", "DPT-02", "Bar"));
    employees.add(new Employee("UID-03", "DPT-01", "AnEmployee"));
    employees.add(new Employee("UID-04", "DPT-03", "AnotherEmployee"));

    List<Employee> filtered = employees.stream().filter(emp -> emp.getDeptID().equals(deptID)).collect(Collectors.toList());
    filtered.forEach(System.out::println); // Here you can also use the double colon operator!
}

You can find more info about streams here: https://www.baeldung.com/java-streams

And about the double colon operator over here: https://www.baeldung.com/java-8-double-colon-operator

Edit

There are some comments which recommends using the forEach() method of Stream, so here's an example which doesn't collect the elements:

public static void main(String[] args) {
String deptID = "DPT-01";
    List<Employee> employees = new ArrayList<>();
   //                          UUID      DEPTID    NAME
    employees.add(new Employee("UID-01", "DPT-01", "Foo"));
    employees.add(new Employee("UID-02", "DPT-02", "Bar"));
    employees.add(new Employee("UID-03", "DPT-01", "AnEmployee"));
    employees.add(new Employee("UID-04", "DPT-03", "AnotherEmployee"));
    employees
        .stream()
        .filter(emp -> emp.getDeptID().equals(deptID))
        .forEach(emp -> System.out.println(emp.getEmpName());
}

Here you have it: No double colon operator, no Collectors, no toString(). Remember this is just a mere example.

Btw, here's the Employee class I used:

public class Employee {

private String userID;
private String deptID;
private String empName;

public Employee(String userID, String deptID, String empName) {
    this.userID = userID;
    this.deptID = deptID;
    this.empName= empName;
}

public String getUserID() {
    return userID;
}

public void setUserID(String userID) {
    this.userID = userID;
}

public String getDeptID() {
    return deptID;
}

public void setDeptID(String deptID) {
    this.deptID = deptID;
}

public String getEmpName() {
    return empName;
}

public void setEmpName(String empName) {
    this.empName= empName;
}

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    Employee employee = (Employee) o;
    return Objects.equals(empName, employee.empName) && Objects.equals(deptID, employee.deptID) && Objects.equals(userName, employee.userName);
}

@Override
public int hashCode() {
    return Objects.hash(empName, deptID, userName);
}

@Override
public String toString() {
    return "Employee{" +
            "empName='" + empName+ '\'' +
            ", deptID='" + deptID + '\'' +
            ", userName='" + userName + '\'' +
            '}';
}
}
  • 1
    Your System.out::println will print the toString representation of the Employee class not the getEmpName() return value... – gemorra Sep 01 '21 at 11:23
  • 1
    When getting a `List` result is not demanded, you should not collect one. You can simply chain `forEach` to the stream operation instead of `collect`. – Holger Sep 01 '21 at 11:25
  • @gemorra I know, but i ommited the object I created for testing. That's just a mere example for also introducing the `double colon operator`. Either way, the toString method I made looks like this: `"Employee{userID='UID', deptID='DPTID', userName='Name'}"` – Nakarukatoshi Uzumaki Sep 01 '21 at 11:30
  • @Holger of course you can do that, because both `List` and `Stream` APIs are iterable, but if you are working with the filtered objects, it's better to collect them than to directly print'em. I just made it for the sake of clarity. I don't know which thing will @SouvikGuha do, so I preferred just to collect them. – Nakarukatoshi Uzumaki Sep 01 '21 at 11:37
  • 1
    `Stream` does not implement `Iterable`, it just have a `forEach` method. But anyway, why is it “better to collect them than to directly print'em”? Collecting them first, requires storage for all matching elements. What is the supposed advantage of an unnecessary storage operation? – Holger Sep 01 '21 at 12:06
  • I didn't say "Stream implements Iterable", but rather "Stream is iterable" because, even though `Stream` class doesn't implement Iterable (https://stackoverflow.com/a/20130131/13622993), it is, in fact, iterable. The only "advantages" in this case for collecting them are code clarity and manipulation of elements (if needed), which it isn't the case, but, as I said, is a mere example, just don't overthink it. Edit: iow, I said "iterable" not as an interface of Java, but as its definition. Definition: https://dictionary.cambridge.org/dictionary/english/iteration – Nakarukatoshi Uzumaki Sep 01 '21 at 12:28
1

Using streams code will look like this

empObj.stream().filter(obj -> {
    return obj.getDeptID().equals(deptID);
}).forEach(obj -> {
    System.out.println(obj.getEmpName());
});

Or parallelStream to a concurrent processing:

empObj.parallelStream().filter(obj -> {
    return obj.getDeptID().equals(deptID);
}).forEach(obj -> {
    System.out.println(obj.getEmpName());
});
Francisco Valle
  • 613
  • 10
  • 10
  • Your [lambda expression](https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html) that implements interface `Predicate` can be simpler: `obj -> obj.getDeptID().equals(deptID)` – Abra Sep 01 '21 at 11:19
  • It can be simplified to obj -> obj.getDepID().equals(deptID) but i choose to use brackets for better formatting the code as i think it will be easier to read and understand – Francisco Valle Sep 01 '21 at 11:25
  • 1
    Why should additional `{`, `}`, and `return` make the code easier to read? These artifacts carry no information compared to `empObj.stream() .filter(obj -> obj.getDeptID().equals(deptID)) .forEach(obj -> System.out.println(obj.getEmpName()));` – Holger Sep 01 '21 at 11:27
  • Because it tells the person looking at it that the filter lambda must return a boolean value and receives an object. It also gives the look of a method so human brain will tell user "that looks like a method". Its only a matter of being used to something, i assume by the question that the person asking is not used to lambda expressions or streams (i can be wrong) – Francisco Valle Sep 01 '21 at 11:32
0

you could do it like this with the Stream api:

   void CheckingNameFromDeptCode(LinkedList<Employee1> empObj, String deptID) 
    {
       empObj.stream().filter(employer -> 
           employer.getId().equals(deptID)).forEach(employer -> 
               System.out.println(employer.getEmpName()));
    }
gemorra
  • 142
  • 13