MapStruct Mapping List To Individual Fields And Vice Versa

public class Lookup {

	private String name;
	private String description;

	private String param1;
	private String param2;
	private String param3;
	private String param4;

	public int paramsCount() {
		int result = 0;
		
		if (isNotEmpty(param4)) {
			result = 4;
		} else if (isNotEmpty(param3)) {
			result = 3;
		} else if (isNotEmpty(param2)) {
			result = 2;
		} else if (isNotEmpty(param1)) {
			result = 1;
		}		
		return result;
	}

	private boolean isNotEmpty(String param42) {
		return param42 != null && param42.trim().length() > 0;
	}

	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getDescription() {
		return description;
	}
	public void setDescription(String description) {
		this.description = description;
	}
	public String getParam1() {
		return param1;
	}
	public void setParam1(String param1) {
		this.param1 = param1;
	}
	public String getParam2() {
		return param2;
	}
	public void setParam2(String param2) {
		this.param2 = param2;
	}
	public String getParam3() {
		return param3;
	}
	public void setParam3(String param3) {
		this.param3 = param3;
	}
	public String getParam4() {
		return param4;
	}
	public void setParam4(String param4) {
		this.param4 = param4;
	}

	@Override
	public String toString() {
		return "Lookup [name=" + name + ", description=" + description + ", param1=" + param1 + ", param2=" + param2
				+ ", param3=" + param3 + ", param4=" + param4 + "]";
	}
}

import java.util.List;

public class LookupModel {
	
	private String name;
	private String description;
	private List<String> params;

	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getDescription() {
		return description;
	}
	public void setDescription(String description) {
		this.description = description;
	}
	public List<String> getParams() {
		return params;
	}
	public void setParams(List<String> params) {
		this.params = params;
	}
	
	@Override
	public String toString() {
		return "LookupModel [name=" + name + ", description=" + description + ", params=" + params + "]";
	}
}

Approach #1

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Named;
import org.mapstruct.factory.Mappers;

@Mapper
public interface LookupMapper {
	
	LookupMapper INSTANCE = Mappers.getMapper( LookupMapper.class );

	@Mapping(source = "source", target = "param1", qualifiedByName = "param1")
	@Mapping(source = "source", target = "param2", qualifiedByName = "param2")
	@Mapping(source = "source", target = "param3", qualifiedByName = "param3")
	@Mapping(source = "source", target = "param4", qualifiedByName = "param4")
	Lookup toLookup(LookupModel source);

	@Named("param1")
    default String lookupModelToParam1(LookupModel source) {
		return getParam(0, source);
    }

	@Named("param2")
    default String lookupModelToParam2(LookupModel source) {
		return getParam(1, source);
    }

	@Named("param3")
    default String lookupModelToParam3(LookupModel source) {
       return getParam(2, source);
    }

	@Named("param4")
    default String lookupModelToParam4(LookupModel source) {
       return getParam(3, source);
    }

	default String getParam(int index, LookupModel source) {
		if (source.getParams().size() > index) {
			return source.getParams().get(index);
		}
		return null;
	}

	@Mapping(source = "source", target = "params", qualifiedByName = "params")
	LookupModel toLookupModel(Lookup source);

	@Named("params")
	default List<String> lookupToParams(Lookup source) {
		return extractParams(source);
	}

	default List<String> extractParams(Lookup source) {
		List<String> result = new ArrayList<String>();

		int paramsCount = source.paramsCount();
		
		if (paramsCount > 0) {
			result.add(source.getParam1());
		}
		
		if (paramsCount > 1) {
			result.add(source.getParam2());
		}
		
		if (paramsCount > 2) {
			result.add(source.getParam3());
		}
		
		if (paramsCount > 3) {
			result.add(source.getParam4());
		}
		return result;
	}
}

Approach #2

@Mapper
public interface LookupMapper {
	
	LookupMapper INSTANCE = Mappers.getMapper( LookupMapper.class );

	Lookup toLookup(LookupModel source);

	@AfterMapping
	default void populateAdditionalParams(LookupModel source, @MappingTarget Lookup target) {

		int idx = 0;
		for (String param : source.getParams()) {
			idx++;
			if (idx == 1) {
				target.setParam1(param);
			} else if (idx == 2) {
				target.setParam2(param);
			}else if (idx == 3) {
				target.setParam3(param);
			}else if (idx == 4) {
				target.setParam4(param);
			}
		}
	}

	LookupModel toLookupModel(Lookup source);

	@AfterMapping
	default void populateAdditionalParams(Lookup source, @MappingTarget LookupModel target) {
		target.setParams(extractParams(source));
	}

	default List<String> extractParams(Lookup source) {
		List<String> result = new ArrayList<String>();

		int paramsCount = source.paramsCount();
		
		if (paramsCount > 0) {
			result.add(source.getParam1());
		}
		
		if (paramsCount > 1) {
			result.add(source.getParam2());
		}
		
		if (paramsCount > 2) {
			result.add(source.getParam3());
		}
		
		if (paramsCount > 3) {
			result.add(source.getParam4());
		}
		return result;
	}
}