Sorting items in list based on position I wrote code which sorts items, based on parameters (IconConfiguration). I have a map of items which have index and item so basically a predefined list on which index item should be, and maxPositions parameter which is kind of a limit of how big my list can be. I wrote a code but its repetitive and pretty ugly when i check it, but i am unable to get idea on what to refactor.

private List&lt;GWBaseData&gt; applyItemsIndex(List&lt;GWBaseData&gt; gwInputBaseDataList) { //TODO: Refactor repetitive code?
        List&lt;GWBaseData&gt; gwBaseDataList = new ArrayList&lt;&gt;();

        if (iconConfiguration.getMax_positions() != -1) {
            for (int i = 0; i &lt; gwInputBaseDataList.size(); i++) {
                if (gwBaseDataList.size() &lt; iconConfiguration.getMax_positions()) {
                    if (getItemsMap().get(i) != null &amp;&amp; getBaseDataInListById(gwInputBaseDataList, getItemsMap().get(i)) != null) {
                        gwBaseDataList.add(i, getBaseDataInListById(gwInputBaseDataList, getItemsMap().get(i)));
                    } else {
                        for (int j = 0; j &lt; gwInputBaseDataList.size(); j++) {
                            if (!gwBaseDataList.contains(gwInputBaseDataList.get(j))) {
                                gwBaseDataList.add(gwInputBaseDataList.get(j));
                                break;
                            }
                        }
                    }
                }
            }
        } else {
            for (int i = 0; i &lt; gwInputBaseDataList.size(); i++) {
                if (getItemsMap().get(i) != null &amp;&amp; getBaseDataInListById(gwInputBaseDataList, getItemsMap().get(i)) != null) {
                    gwBaseDataList.add(i, getBaseDataInListById(gwInputBaseDataList, getItemsMap().get(i)));
                } else {
                    for (int j = 0; j &lt; gwInputBaseDataList.size(); j++) {
                        if (!gwBaseDataList.contains(gwInputBaseDataList.get(j))) {
                            gwBaseDataList.add(gwInputBaseDataList.get(j));
                            break;
                        }
                    }
                }
            }
        }

        return gwBaseDataList;
    }


So basically the whole difference between both block is only  one additional if (if (gwBaseDataList.size() &lt; iconConfiguration.getMax_positions()))
Add an extra local variable before the first loop:

int maxItems = iconConfiguration.getMax_positions();
if (maxItems == -1) {
    maxItems = gwInputBaseDataList.size();
}


This way if you didn't specify a max in the configuration you just use "all" input items.

You can go a little bit further as well and use this as the condition on the outer for loop:

for (int i = 0; i &lt; maxItems; i++) {
    if (getItemsMap().get(i) != null &amp;&amp; getBaseDataInListById(gwInputBaseDataList, getItemsMap().get(i)) != null) {
        gwBaseDataList.add(i, getBaseDataInListById(gwInputBaseDataList, getItemsMap().get(i)));
    } else {
        for (int j = 0; j &lt; gwInputBaseDataList.size(); j++) {
            if (!gwBaseDataList.contains(gwInputBaseDataList.get(j))) {
                gwBaseDataList.add(gwInputBaseDataList.get(j));
                break;
            }
        }
    }
}
return gwBaseDataList;


I couldn't actually test this code, so make sure it's not off by 1 on the index when you try it yourself. And just to be safe test if this still actually does what you want it to do for all edge cases.



EDIT bugfix:

In case the max from the configuration is larger than the actual size you'll get an index out of bounds. Fixed by changing the if condition to the folowing:

if(maxItems == -1 || maxItems &gt; gwInputBaseDataList.size()){