Recursive Java List Complement

I have a benchMarkActual variable that will have a double value between 1.0 and 100.0.

I have range control values โ€‹โ€‹like 10,20,30,50,70 and 90.

For example, if benchMarkActual is 65.5 , I need the list of crossed ranges to have 10,20,30,40 and 50.

Similarly, if benchMarkActual 40.0 I need a list of cross ranges to have 10,20 and 30

I do it as follows

 double benchMarkActual = getActual(val); Set<String> crossedRange = new HashSet<>(); if (benchMarkActual > 0) { if (benchMarkActual >= 10) { crossedRange.add("10"); } if (benchMarkActual >= 20) { crossedRange.add("20"); } if (benchMarkActual >= 30) { crossedRange.add("30"); } if (benchMarkActual >= 50) { crossedRange.add("50"); } if (benchMarkActual >= 70) { crossedRange.add("70"); } if (benchMarkActual >= 90) { crossedRange.add("90"); } } 

It works as expected, but there is a better way to do this.

+5
source share
6 answers

You can also use the Java 8 thread API.

 final double benchMarkActual = getActual(val); Set<String> crossedRange = Stream .of(10, 20, 30, 50, 70, 90) .filter(e -> e <= benchMarkActual) .map(String::valueOf) .collect(Collectors.toSet()); 
0
source

To minimize the number of duplicate code, you can do the following:

Create a method to summarize all if statements

  private static void addMarktoCocssedRange(double benchMarkActual, Set<String> crossedRange, int comparaeWith) { if (benchMarkActual >= comparaeWith) { crossedRange.add(String.valueOf(comparaeWith)); } } 

and then use it in a for loop

  double benchMarkActual = getActual(val); Set<String> crossedRange = new HashSet<>(); for (int i = 10; i <= 90; i += 10) { addMarktoCocssedRange(benchMarkActual, crossedRange, i); } 
+1
source

I tried to make all the necessary explanations as comments in the code. Feel free to explain further if something is unclear to you:

 public class Test { public static Set<String> addToCrossedRange(List<Integer> sourceList, double benchMarkActual, Set<String> crossedRange) { // If you have chosen incorrect benchMarkActual value ( < 1.0 or > 100.0) it throws an appropriate exception: if(benchMarkActual < 1.0 || benchMarkActual > 100.0) { throw new IllegalArgumentException("Incorrect benchMarkActual value!"); } // If benchMarkActual was correct, it iterates over sourceList and add String representation of matching values to crossedRange Set: for(Integer i : sourceList) { if(benchMarkActual >= i) { crossedRange.add(String.valueOf(i)); } } return crossedRange; } public static void main(String[] args) { double benchMarkActual = 40; // just an example value, you can change it to getActual(val) for your use List<Integer> benchMarkValues = new ArrayList<>(); benchMarkValues.addAll(Arrays.asList(10,20,30,50,70,90)); // adds all of these range benchmark values to the list Set<String> crossedRange = new HashSet<>(); // to store a result of invoking addToCrossedRange() method crossedRange = addToCrossedRange(benchMarkValues, benchMarkActual, crossedRange); // This loop is just to check if addToCrossedRange() method works correctly: for(String s : crossedRange) { System.out.print(s + " "); } } } /* This code prints to the console the following line: 30 20 10 */ 

Change If you are not satisfied that you benchMarkActual exception when the incorrect benchMarkActual value was used, you can change this part inside the curly brackets to whatever you need, maybe you just need to show the error message:

 if(benchMarkActual < 1.0 || benchMarkActual > 100.0) { System.out.println("Incorrect benchMarkActual value!"); } 
+1
source

You can use the switch statement as follows:

 //round to the closest 10th int rounded = ((int)(benchMarkActual/10))*10 switch (rounded) { case 90: crossedRange.add("90"); case 80: crossedRange.add("80"); case 70: crossedRange.add("70"); etc... } 

Since you will not break it, it will receive all the values โ€‹โ€‹as soon as it finds a match.

You can also use a loop

 for(int i=10; i<100; i+=10){ if (benchMarkActual >= i) { crossedRange.add(i); } } 
0
source

You can determine the "limit" values โ€‹โ€‹in the order in the integer array that you repeat and during each iteration check whether the limit has been crossed. The following will return a set of crossed intersections or an empty set if the actual result does not cross any constraints.

 final int[] limits = new int[]{10,20,30,50,70,90}; double benchMarkActual = getActual(val); Set<Integer> crossedLimits = new LinkedHashSet<>(); for (int limit: limits) { if (benchMarkActual > (double) limit) { crossedLimits.add(limit); } } return crossedLimits; 

LinkedHashSet used to store crossed limits so that the iteration order of the set remains in the numerical limit order. Makes printing clearer, but I'm not sure if this matters in your use case.

0
source
 int benchMakrActual = (int) Math.floor(getActual(val)); int[] values = new int[] { 10 , 20, 30, 50, 70, 90 }; Set<String> crossedRange = new HashSet<>(); for (int i = 0; i < values.length && values[i] <= benchMarkActual; i++) { crossedRange.add("" + values[i]); } 

This code assumes values sorted. If not, you can sort it ( Arrays.sort ) or modify the for loop to process it (the second part of the conditional jump goes to the if , which includes adding a list.

0
source

Source: https://habr.com/ru/post/1274484/


All Articles