zebiri djallil
zebiri djallil

Reputation: 334

how i can optimize this code to look more performant?

I have this Java code that splits the age of users into 8 groups:

private int[] A0, A1, A2, A3, A4, A5, A6, A7, A8;

    public Grouping() {
        super();

        for (int i = 5; i < 10; i++)
            A0[i] = i;

        for (int i = 10; i < 20; i++)
            A1[i] = i;

        for (int i = 20; i < 30; i++)
            A2[i] = i;

        for (int i = 30; i < 40; i++)
            A3[i] = i;

        for (int i = 40; i < 50; i++)
            A4[i] = i;

        for (int i = 50; i < 60; i++)
            A5[i] = i;

        for (int i = 60; i < 70; i++)
            A6[i] = i;

        for (int i = 70; i < 80; i++)
            A7[i] = i;

        for (int i = 10; i < 20; i++)
            A8[i] = i;

    }

Now I would like to optimize this code. Are there any ideas?

Upvotes: 0

Views: 95

Answers (3)

slartidan
slartidan

Reputation: 21608

I'd use java8 streams. See my example code:

import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class Grouping {
    public static void main(String[] args) {

        // create a stream from 5 (inclusive) to 80 (exclusive)
        IntStream.range(5, 80)

        // convert it to Integer objects
        .boxed()

        // group it by tens
        .collect(Collectors.groupingBy(i -> i / 10))

        // iterate over each group
        .entrySet().stream()

        // pretty format
        .map(entry -> "A"+entry.getKey()+"="+entry.getValue())

        // print to console
        .forEach(System.out::println);
    }
}

it outputs:

A0=[5, 6, 7, 8, 9]
A1=[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
A2=[20, 21, 22, 23, 24, 25, 26, 27, 28, 29]
A3=[30, 31, 32, 33, 34, 35, 36, 37, 38, 39]
A4=[40, 41, 42, 43, 44, 45, 46, 47, 48, 49]
A5=[50, 51, 52, 53, 54, 55, 56, 57, 58, 59]
A6=[60, 61, 62, 63, 64, 65, 66, 67, 68, 69]
A7=[70, 71, 72, 73, 74, 75, 76, 77, 78, 79]

Upvotes: 0

T.J. Crowder
T.J. Crowder

Reputation: 1075447

You've said you want it "shorter." Here's a shorter version, except I had no idea what you were trying to do with A8, which is redundant with A1, and so have left that off:

private int[][] groups; // I assume you initialize `A0` and so on somewhere you haven't shown; initialize this there

public Grouping() {
    int i, groupIndex, group;

    super();

    groupIndex = 0;
    group = groups[0];
    for (i = 5; i < 80; ++i) {
        if (i % 10 == 0) {
            ++groupIndex;
            group = groups[groupIndex];
        }
        group[i] = i;
    }
}

Note though that this is still fairly weird code because it does what your original code does and leaves all sorts of entries in the arrays at their default value (0). For instance, in your code, A0's indexes 0 through 4 never get assigned to, and that's true of groups[0]'s 0 through 4 above as well. (And the subsequent ones have larger gaps.)

Your title, though, says you want it more "performant." "performant" != "shorter" Your code probably performs just fine, likely an imperceptibly amount better than mine above as it doesn't need the % operation and the if inside the loop.

Or here's a version implementing Seelenvirtuose's suggestion:

private int[][] groups; // I assume you initialize `A0` and so on somewhere you haven't shown; initialize this there

public Grouping() {
    int i;

    super();

    for (i = 5; i < 80; ++i) {
        groups[i / 10][i] = i;
    }
}

...which works because the i / 10 bit is an integer division.

Upvotes: 4

Rajesh
Rajesh

Reputation: 2155

Create a group class which will hold age range and a counter to hold matches for that group. Add group objects to a list and play around.

public static void main(String[] args) {

    List<Group> lists = new ArrayList<Group>(10);

    lists.add(new Group(5, 10));
    lists.add(new Group(10, 20));
    lists.add(new Group(20, 30));
    lists.add(new Group(30, 40));

    int age[] = { 5, 10, 20, 30, 11, 22, 33 };

    for (int i = 0; i < age.length; i++)
        grouper: for (Group group : lists)
            if (group.validateAgeGroup(age[i]))
                break grouper;

    for (Group group : lists)
        System.out.println(group);
}

Group Class : age range and a counter:

public class Group {

    int startAge, endAge, counter;

    public Group(int startAge, int endAge) {
        this.startAge = startAge;
        this.endAge = endAge;
    }

    public boolean validateAgeGroup(int age) {
        if (age >= startAge && age < endAge) {
            this.setCounter(1);
            return true;
        }
        return false;
    }

    public int getCounter() {
        return counter;
    }

    public int getEndAge() {
        return endAge;
    }

    public int getStartAge() {
        return startAge;
    }

    public void setCounter(int counter) {
        this.counter += counter;
    }

    public void setEndAge(int endAge) {
        this.endAge = endAge;
    }

    public void setStartAge(int startAge) {
        this.startAge = startAge;
    }

    @Override
    public String toString() {
        return "Group [startAge=" + getStartAge() + ", endAge=" + getEndAge()
                + ", counter=" + getCounter() + "]";
    }
}

Upvotes: 0

Related Questions