Skip to content

Instantly share code, notes, and snippets.

@vivekragunathan
Last active July 15, 2016 06:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vivekragunathan/c2a0f5b07b9a17ea89d5b75ce5176fa1 to your computer and use it in GitHub Desktop.
Save vivekragunathan/c2a0f5b07b9a17ea89d5b75ce5176fa1 to your computer and use it in GitHub Desktop.
A sample program demonstrating how JINQ is expressive and succinct.
import jinq.core.Enumerable;
import jodash.Iterables;
import java.util.*;
/**
* A sample program, derived from real-time code, demonstrating how JINQ is expressive and succinct.
*
* While the MundaneCalculator.calculateCostsByDept might appear short (or not too long to read), lot of details
* and relevance to real-time code has been purposely stripped particularly to demonstrate the difference. In
* real time, MundaneXXXX like class/method has so much that it is difficult for the reader to stay in context.
*
* JINQ (JinqCalculator.calculateCostsByDept) is simple expressive and succinct, and helps organize rest of
* the code that feeds the JINQ pipeline
*
**/
public class Jinqle {
private static class Employee implements Comparable<Employee> {
public final int id;
public final String name;
public final String department;
public final boolean intern;
public int hikePercent;
public int hikeAmount;
public Employee(int id,
String name,
String dept,
boolean intern) {
this.id = id;
this.name = name;
this.department = dept;
this.intern = intern;
}
@Override
public String toString() {
return String.format(
"(%s-%s) %s %s (%s, %s)",
intern ? "I" : "E",
id,
name,
department,
hikeAmount,
hikePercent
);
}
@Override
public int compareTo(Employee other) {
return this.name.compareTo(other.name);
}
}
private static class CostInfo {
public final String department;
private int hikePercent;
private int hikeAmount;
private int count = 1;
public CostInfo(Employee employee) {
this.department = employee.department;
this.hikeAmount = employee.hikeAmount;
this.hikePercent = employee.hikePercent;
}
public CostInfo(String dept,
int hikePercent,
int hikeAmount) {
this.department = dept;
this.hikePercent = hikePercent;
this.hikeAmount = hikeAmount;
}
public int update(int hikeAmount, int hikePercent) {
this.hikeAmount += hikeAmount;
this.hikePercent += hikePercent;
this.count++;
return count;
}
@Override
public String toString() {
return String.format(
"%s (%d): %s, %s",
department,
count,
hikeAmount,
hikePercent
);
}
public int getTotalHike() {
return this.hikeAmount;
}
public int getAverageHikePercent() {
return this.hikePercent / this.count;
}
}
public static final String[] departments = {
"System and Infrastructure",
"Application",
"Big Data",
"Operations",
"Production Support",
"Database",
"UX"
};
public static List<Employee> employees() {
final List<Employee> employees = new ArrayList<>();
final Random random = new Random(3333);
for (int index = 0; index < 100; ++index) {
final int id = index + 1;
final String name = "Name" + id;
final int deptIndex = random.nextInt(departments.length);
final String dept = departments[ deptIndex % departments.length ];
final Employee emp = new Employee(id, name, dept, index % 2 == 0);
emp.hikeAmount = random.nextInt(5000);
emp.hikePercent = random.nextInt(10);
employees.add(emp);
}
return employees;
}
interface CostCalculator {
Map<String, CostInfo> calculateCostsByDept();
}
static class JinqCalculator implements CostCalculator {
public final Iterable<Employee> employees;
public JinqCalculator(Iterable<Employee> employees) {
this.employees = employees;
}
@Override
public Map<String, CostInfo> calculateCostsByDept() {
return new Enumerable<>(employees)
.where(e -> !e.intern)
.select(CostInfo::new)
.toMap(
c -> c.department,
(m, v, c) -> v.update(c.hikeAmount, c.hikePercent)
);
}
}
static class MundaneCalculator implements CostCalculator {
private final Iterable<Employee> employees;
public MundaneCalculator(Iterable<Employee> employees) {
this.employees = employees;
}
@Override
public Map<String, CostInfo> calculateCostsByDept() {
final Map<String, CostInfo> costMap = new HashMap<>();
for (Employee employee : employees) {
if (!employee.intern) {
continue;
}
CostInfo costInfo = costMap.get(employee.department);
if (costInfo == null) {
costInfo = new CostInfo(
employee.department,
employee.hikePercent,
employee.hikeAmount
);
costMap.put(employee.department, costInfo);
continue;
}
costInfo.update(employee.hikeAmount, employee.hikePercent);
}
return costMap;
}
}
public static void main(String[] args) {
final List<Employee> employees = employees();
System.out.printf("Employees:%n%n%s%n", employees);
//final CostCalculator calculator = new MundaneCalculator(employees);
final CostCalculator calculator = new JinqCalculator(employees);
final Map<String, CostInfo> costs = calculator.calculateCostsByDept();
final String log = Iterables.toString(costs.values(), "\n");
System.out.printf("Cost Info:%n%n%s%n", log);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment