---
marp: true
title: 30 March 2021
theme: default
paginate: true
---
# <!-- fit --> CS 199 EMP

### Hosted by Jackie Chan and Akhila Ashokan

**Topics:** MORE on Anonymous Classes and Interfaces, MORE on Lambda Expressions, MORE on Algorithm Analysis

---

# Today's Learning Objectives

- MORE on Anonymous Classes and Interfaces

- MORE on Lambda Expressions

- MORE on Algorithm Analysis 

Write code on the homepage or any playground on the site!
https://cs125.cs.illinois.edu/

Slides are on the course site!
https://cs199emp.netlify.app/

---

# Back By Popular Demand: Anonymous Classes and Interfaces

**Interfaces**
- interface methods do not have a body; the body is provided in the class it implements 
- the implementation must override all the methods provided in the interface

**Anonymous Class** 
- no name 
- must extend another class or implement an interface 
- created immediately
- can capture variables outside the scope of the anonymous class 

---

# Interfaces and Anonymous Class Example 

```java
public class Camera {
  public String type;
  public Camera(String setType) {
    type = setType; 
  }
}

interface Input {
  String getInputType();
};

Camera cam = new Camera("Nikon");

//anonymous class that implements an interface 
Input in = new Input() {
  @Override 
  public String getInputType() {
    return cam.type;
  }
};
System.out.println(in.getInputType());
```

---

# Practice Problem 1 (10 minutes)

1. Create a construtor for Athlete 
2. Create an anonymous class to implement the Competitor interface 

```java
interface Competitor {
  boolean getIsPrepared(); 
}
public class Athlete {
  private String name;
  private String sport; 
  public boolean isPrepared; 
}

Athlete serena = new Athlete("Serena Williams", "tennis", true);
System.out.println(sw.getIsPrepared());
```

---

# Quick Review on Lambda Expressions 

Lambda expressions are a neat way to write functions as variables. They were introduced in Java 8, but other programming languages have them too. 

```java
(parameter1, parameter2) -> {code block} 
```

They are a good alternative when you have to implement single-method class more compactly. 

---

# Practice Problem 2 (20 minutes)

Scenario: Suppose that you are the new VP of Marketing Research at AvatarTechCo. Your first task is to improve the company's ability to target ads by analyzing user data shared on the company's social media platform. The first company that approaches you for targetted ads is Fire Nation LLC.  

---
# Practice Problem 2 (cont.)

Tasks: 
1. Create a class called `UserProfile` that stores these user variables: name, gender, age, politicalAffiliation
2. Create a constructor for `UserProfile` 
3. Create a static method called `filterByAge` that searches for users in an ArrayList who are above a certain age and returns a filtered list with only those users above a certain age. *Hint: You did something similar in MP 1*
4. Use a lambda expression to  print out the name of each user in the filtered ArrayList. *Hint: Check out the forEach method in the Array List documentation*

--- 

# Practice Problem 2 (cont.)

5. Create a static method called `isSimilarUser` that takes two Object arguments and returns true if the users have the same gender or political affiliation. 
6. Create a functional interface called `AvatarFinder` that had one method called `isAvatar` which returns whether a user is the Avatar. The Fire Nation has two clues about the Avatar: he is from the Air Nation and his age is greater than 100. Use this information to implement the functional interface with a lambda expression that prints out whether a user in an ArrayList of users is the Avatar.

---

# Practice Problem 2 Starter Code

```java
import java.util.ArrayList;

public class UserProfile {
  public String name; 
  public int age; 
  public String gender; 
  public String politicalAffliation; 

  // write your constructor here 
  
  // create your filterByAge method here 
  
  // create your isSimilarUser method here 
}

ArrayList<UserProfile> users = new ArrayList<>();
users.add(new UserProfile("Katara", 14, "female", "Water Nation"));
users.add(new UserProfile("Aang", 112, "male", "Air Nation"));
users.add(new UserProfile("Sokka", 14, "male", "Water Nation"));
users.add(new UserProfile("Toph", 12, "female", "Earth Nation"));
users.add(new UserProfile("Zuko", 16, "male", "Fire Tribe"));

ArrayList<UserProfile> filteredUsers = UserProfile.filterByAge(users, 18);
// create lambda expression to print names of users in ArrayList 


// should print true if you implemented isSimilarUser correctly
System.out.println(UserProfile.isSimilarUser(new UserProfile("Katara", 14, "female",
    "Water Nation"), new UserProfile("Toph", 12, "female", "Earth Nation")));

// create your AvatarFinder functional interface here 
// criteria: Air Nation, 112 
```

---

# Food for Thought 

Awesome. You just took a stab at creating targetted ads for users. Large tech companies like Facebook and Google aim to accomplish the same thing but on a much larger scale. In this case, Fire Nation LLC was able to target ads to certain users and track down the Avatar. What are some ethical and legal dilemmas that may arise out of this technology?  

---

# Quick Review on Algorithm Analysis 

We analyze the computational complexity of algorithms based on the amount of time, storage, and other resources used to execute them. Why? Because we're nerds.

Jk, in all seriousness, this is a great skills to have for tech interviews. Big-O notation is frequently asked in tech interviews and they also help us understand how an algorithm behaves as the number of inputs increase 

- O(1): constant time; array accesses are a good example 
- O(n) : linear time; one for-loop; iterating through an object of size n 
- O(n^2): nested for-loops; iterating through an object n*n times 

---

# Practice Problem 3 (10 minutes)

Create a method called `isSorted` that takes in an integer array and returns a boolean representing whether the array is sorted from least to greatest. Analyze the runtime complexity. Answers may vary depending on the implementation. What is the best case, worst case, and average case? 

---

# Woohoo! That's it for today!  

Great job. You've learned alot today. Let us know if you have any questions!

Fill out the [feedback form](https://forms.gle/54tRoxwNM79J7nAu5) if you have anything to say! Good luck on the midterm today. You're gonna kill it. 

---

# Solution Section

---

# Practice Problem 1 

```java 
interface Competitor {
  boolean getIsPrepared(); 
}
public class Athlete {
  private String name;
  private String sport; 
  public boolean isPrepared; 
  public Athlete(String setName, String setSport, boolean setIsPrepared) {
    name = setName;
    sport = setSport;
    isPrepared = setIsPrepared; 
  }
}

Athlete serena = new Athlete("Serena Williams", "tennis", true);
Competitor sw = new Competitor() {
  public boolean getIsPrepared() {
    return serena.isPrepared;
  }
};

System.out.println(sw.getIsPrepared()); // should print true 

```

---

# Practice Problem 2 - Tasks 1,2,3,5

```java 
import java.util.ArrayList;

public class UserProfile {
  public String name; 
  public int age; 
  public String gender; 
  public String politicalAffliation; 

  public UserProfile(String setName, int setAge, String setGender, String setPoliticalAffliation) {
    name = setName;
    age = setAge;
    gender = setGender;
    politicalAffliation = setPoliticalAffliation;
  }
  
  public static ArrayList filterByAge(ArrayList<UserProfile> users, int age) {
    ArrayList<UserProfile> filteredUsers = new ArrayList<>();
    for (UserProfile i : users) {
      if (i.age >= age) {
        filteredUsers.add(i);
      }
    }
    return filteredUsers;
    
  }
  
  public static boolean isSimilarUser(Object o1, Object o2) {
    assert o1 instanceof UserProfile;
    assert o2 instanceof UserProfile;
    
    UserProfile user1 = (UserProfile) o1;
    UserProfile user2 = (UserProfile) o2;
    
    if (user1.gender.equals(user2.gender) 
        || user1.politicalAffliation.equals(user2.politicalAffliation)) {
      return true;
    } else {
      return false;
    }
  }
}
```

---

# Practice Problem 2 - Task 4

```java
ArrayList<UserProfile> users = new ArrayList<>();
users.add(new UserProfile("Katara", 14, "female", "Water Nation"));
users.add(new UserProfile("Aang", 112, "male", "Air Nation"));
users.add(new UserProfile("Sokka", 14, "male", "Water Nation"));
users.add(new UserProfile("Toph", 12, "female", "Earth Nation"));
users.add(new UserProfile("Zuko", 16, "male", "Fire Tribe"));

ArrayList<UserProfile> filteredUsers = UserProfile.filterByAge(users, 18);
// should print Aang 
filteredUsers.forEach((n) -> {
  System.out.println(n.name); });
```
---

# Practice Problem 2 - Task 6 

```java
// should print true 
System.out.println(UserProfile.isSimilarUser(new UserProfile("Katara", 14, "female",
    "Water Nation"), new UserProfile("Toph", 12, "female", "Earth Nation")));

// find the avatar 
// criteria: Air Nation, 112 
interface AvatarFinder {
  boolean isAvatar(UserProfile profile);
}

//prints out one isAvatar is true
users.forEach((n) -> {
  System.out.println("isAvatar is " + (n.politicalAffliation.equals("Air Nation") 
      && n.age > 100)); });

```
---
# Practice Problem 3 

This implementation is O(n^2). Worst case is when the array is sorted. Best case is when the unsorted element is at the beginning. Average case is a bit vague but generally will be O(n^2).

```java
boolean isSorted(int[] array) {
  for (int i = 0; i < array.length; i++) {
    for (int j = i; j < array.length; j++) {
      if (array[j] < array[i]) {
        return false; 
      }
    }
  }
  return true;
}

int[] arr = {9, 8, 7, 6};
System.out.println(isSorted(arr));
```