Last active
April 26, 2018 13:19
-
-
Save visakha/8ac7f823e02192beb23a3f869fc4a196 to your computer and use it in GitHub Desktop.
Java 8 streams : How to surface the comparator winning rule to the domain object
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* We have a list of cars identified by Make, | |
* other attributes are name, rating, mileage | |
* The idea is to pick 1 car from each make by applying the below rules in sequence | |
* | |
* Rule 1 : if there is only one car per make: then mark it for Pick: pick = 'onlyOneItem' | |
* Rule 2 : if not Rule 1 then Pick the car with better rating: pick = 'higerRating' | |
* Rule 3 : if not Rule 2 then Pick the car with least mileage: pick= 'lowerMileage' | |
* | |
* acceptence criteria: Rules are to be applied in order and if one rule applies then the rest can be skipped | |
*/ | |
val _none = "none" | |
val _onlyOneItem = "onlyOneItem"; | |
val _higherRating = "higherRating"; | |
val _lowerMiles = "lowerMiles" | |
data class Car(val make: String, val name: String, val rating: Int, val mileage: Int, var reason4pick: String = "none", val expectedReason: String = "none"){ | |
fun negMileage() = mileage * -1 | |
} | |
val cars = listOf<Car>( | |
Car("Honda", "AnaKat's new SUV", 5, 2000, expectedReason = _higherRating) | |
, Car("Honda", "AnaKat's sedan", 3, 3000) | |
// ------------// ------------// ------------// ------------// ------------// ------------ | |
, Car("Toyota", "AnaKat's HighLander", 5, 1000, expectedReason = _lowerMiles) | |
, Car("Toyota", "AnaKat's 4 runner", 5, 2000) | |
, Car("Toyota", "AnaKat's Camry", 3, 100) | |
// ------------// ------------// ------------// ------------// ------------// ------------ | |
, Car("Mazda", "Ravi's SUV", 1, 7000, expectedReason = _onlyOneItem) | |
// ------------// ------------// ------------// ------------// ------------// ------------ | |
, Car("Nissan", "Kondal's Nissan Van", 5, 2000, expectedReason = _onlyOneItem) | |
// ------------// ------------// ------------// ------------// ------------// ------------ | |
, Car("LandRover", "Jims old LandRV", 4, 1000) | |
, Car("LandRover", "Jims crusr", 5, 1000, expectedReason = _higherRating) | |
// ------------// ------------// ------------// ------------// ------------// ------------ | |
) | |
@Test | |
fun strmGroupByMarkPrimary() { | |
fun applyRules(vl: List<Car>): List<Car> { | |
if (vl.size == 1) {vl.get(0).reason4pick = _onlyOneItem; return vl} // ----> marker 1 | |
val maxRatingOrLowerMileageCar = vl.stream() | |
.max ( Comparator.comparingInt(Car::rating) | |
.thenComparingInt(Car::negMileage)).get() | |
// How to update the reason for pick just like we it 5 lines above (marker 1) ??? | |
return listOf(maxRatingOrLowerMileageCar) | |
} | |
val grpdBy: MutableMap<String, MutableList<Car>> = cars.stream().collect(Collectors.groupingBy({ e -> e.make }, Collectors.toList<Car>())) | |
val f1 = grpdBy.flatMap { (k, vl) -> applyRules(vl) } | |
f1.forEach { assertEquals(it.reason4pick, it.expectedReason) } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment