I have an entity that has as children several lists of objects that, although they have different classes, all have the order attribute, in several parts I end up with repeated code, for example in one part I need to order the lists by that attribute and I cannot simplify because they are of different type.
The relevant part of the entity is this:
contenido={
"educaciones":[
{
...
"orden":0
},{
...
"orden":1
}
],
"experiencias":[
{
...
"orden":0
},{
...
"orden":1
}
]
},
...
The code I would like to simplify:
if(tipo.equals("experiencias")){
List<Experiencia> iterable=contenido.getExperiencias();
for(int i = 0; i < iterable.size(); i ){
iterable.get(i).setOrden( orden.get(i) ); //orden = [0,3,5,...]
}
iterable.sort((it1,it2)-> it1.getOrden().compareTo(it2.getOrden()));
}else if(tipo.equals("educaciones")){
List<Educacion> iterable=contenido.getEducaciones();
for(int i = 0; i < iterable.size(); i ){
iterable.get(i).setOrden( orden.get(i) );
}
iterable.sort((it1,it2)-> it1.getOrden().compareTo(it2.getOrden()));
}else if...
Is there a way to create a code that is more generic and supports different objects?
CodePudding user response:
you can try to create a List<?>
- list with a dynamic type outside of your if else
block and move your duplicated code outside too and at the end of the if else
block. In addition, you have to create a common class or some interface for your classes, which holds all the common field you needed
public class Main {
public static class Something {
private Integer sth;
public Integer getSth() {
return sth;
}
public void setSth(Integer sth) {
this.sth = sth;
}
}
public static class ThisClass extends Something {
private Integer num;
public ThisClass(Integer num) {
this.num = num;
}
public Integer getNum() {
return num;
}
public void setNum(Integer num) {
this.num = num;
}
}
public static class ThatClass extends Something {
private String str;
public ThatClass(String str) {
this.str = str;
}
public String getStr() {
return str;
}
public void setNum(String str) {
this.str = str;
}
}
public static List<? extends Something> sortList(Class<?> itemClass, List<? extends Something> list)
throws Exception {
for(int i = 0; i < list.size(); i ){
list.get(i).setSth(i);
}
list.sort((it1,it2)-> it1.getSth().compareTo(it2.getSth()));
return list;
}
public static void main(String[] args) {
System.out.println("Hello World");
List<? extends Something> someList = new ArrayList<>();
boolean check = true;
if(check) {
someList = Arrays.asList(new ThisClass(1),new ThisClass(1),new ThisClass(1),new ThisClass(1));
} else {
someList = Arrays.asList(new ThatClass("a"), new ThatClass("a"),new ThatClass("a"),new ThatClass("a"));
}
try {
someList = sortList(ThisClass.class, someList);
for(int i = 0; i < someList.size(); i ){
System.out.println(someList.get(i).getSth());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
CodePudding user response:
Create an interface for the methods that are common between all you classes:
interface HasOrden {
int getOrden();
void setOrden(int i);
}
Each of your classes needs to implement HasOrden
.
Then you can declare sortOrden
function:
import java.util.ArrayList;
import java.util.List;
interface HasOrden {
int getOrden();
void setOrden(int i);
}
class Experiencia implements HasOrden {
private final String name;
int orden;
public Experiencia(String name) {
this.name = name;
}
@Override
public int getOrden() {
return orden;
}
@Override
public void setOrden(int i) {
orden = i;
}
public String toString() {
return name;
}
}
public class Eg {
static void sortOrden(List<? extends HasOrden> l, List<Integer> order) {
if (l.size() != order.size()) {
throw new RuntimeException("length mismatch");
}
for (int i = 0; i < l.size(); i ) {
l.get(i).setOrden(order.get(i));
}
l.sort((it1,it2)-> Integer.compare(it1.getOrden(), it2.getOrden()));
}
public static void main(String[] args) {
List<Experiencia> items = new ArrayList<>(List.of(new Experiencia("a"), new Experiencia("b")));
List<Integer> order = List.of(2,1);
sortOrden(items, order);
System.out.println(items);
}
}
You can call sortOrden
on any list of HasOrden
instances.