【工作记录】java方法返回多个值(用法思考、比较)

       用java写业务逻辑的时候,有时候一个方法可能需要返回多个出参,当中可能有List,String,Map等不同类型的数据结构,针对这种情况,我的解决策略一般是使用Map的形式来解决,具体分析请浏览下文。


1.直接返回map
      如下是我最近写的直接用Map来返回多个出参的code piece:
public Result<Map<String,Object>>  queryProductListBWNew(ProductParamDTO dto) {
    Result<Map<String,Object>> result = new Result<Map<String,Object>>();
    List<ProductResultDTO> resultList=new LinkedList<ProductResultDTO>();
    Double amtRangeMax = Double.MIN_VALUE;
    Double amtRangeMin = Double.MAX_VALUE;
    try {
	    Map<String,Object> resultMap = new HashMap<String,Object>();
        /**
		* todo logic code   
		*/
		resultMap.put("resultList",resultList);
		resultMap.put("amtRangeMax",amtRangeMax);
		resultMap.put("amtRangeMin",amtRangeMin);
		result.setRe(resultMap);
		result.setStatus(0);		
     }catch(Exception e){
        logger.error("筛选产品异常!异常信息: " + e.getStackTrace());
        result.setStatus(-1);
        result.setMsg("系统异常");
        return result;
     } 
    
    logger.error("获取可贷款产品列表()出参:" + JSON.toJSONString(resultMap));
    return result;
}

   summary:
    优点:
    1 .解决了出参不能返回多个值的问题。
    
    缺点:
    1.需要通过javadoc等方式,获知该方法返回的"key"的名称。
    2.不知道Map<>中有多少对<key,value>映射,给人的感觉就像是dos系统下的黑窗口,反参有什么,不清楚,不明确。只能通过文档。


2.封装tuple
 (0)Util示例:
public class Tuple<T1 extends Serializable, T2 extends Serializable> implements Serializable {
    public final T1 a;
    public final T2 b;

    public Tuple(T1 a, T2 b) {
        this.a = a;
        this.b = b;
    }
}
public class TwoTuple<A, B> {
    private final A first;
    private final B second;

    public TwoTuple(A a, B b) {
        this.first = a;
        this.second = b;
    }

    public A getFirst() {
        return this.first;
    }

    public B getSecond() {
        return this.second;
    }
}
public class ThreeTuple<A, B, C> extends TwoTuple<A, B> {
    private final C third;

    public ThreeTuple(A a, B b, C c) {
        super(a, b);
        this.third = c;
    }

    public C getThird() {
        return this.third;
    }
}
public class FourTuple<A, B, C, D> extends ThreeTuple<A, B, C> {
    private final D fourth;

    public FourTuple(A a, B b, C c, D d) {
        super(a, b, c);
        this.fourth = d;
    }

    public D getFourth() {
        return this.fourth;
    }
}
public final class TupleUtil {
    private TupleUtil() {
    }

    public static <A, B> TwoTuple<A, B> tuple(A a, B b) {
        return new TwoTuple(a, b);
    }

    public static <A, B, C> ThreeTuple<A, B, C> tuple(A a, B b, C c) {
        return new ThreeTuple(a, b, c);
    }

    public static <A, B, C, D> FourTuple<A, B, C, D> tuple(A a, B b, C c, D d) {
        return new FourTuple(a, b, c, d);
    }
}

(1)调用示例:

   1.tuple设置出参:

private static TwoTuple<List<Image>, Rectangle> getImages(List<String> urls) throws Exception {
	List<Image> list = new ArrayList<Image>();
	float urx = 1191; 
	float ury = 1684;
	for (String url : urls) {
		Image image = Image.getInstance(url);
		image.scalePercent(100);
		image.setBorder(1);
		image.setBorderWidth(10);
		image.setBorderColor(Color.WHITE);
		if(urx < image.getWidth() || ury < image.getHeight()) {
			image.scalePercent(getPercent(image.getHeight(), image.getWidth()));
		}
		list.add(image);
	}
	return TupleUtil.tuple(list, new Rectangle(urx, ury));
}

   2.接口调用方

public static Tuple<DealerCreditInfoDTO,DealerCreditInfoRecordDTO> queryDisInfo(String disId) {
	final Object logsId = LogUtils.initLogsId();
	final String desc = "远程获取分销商信息queryDisInfo方法:";
	LogUtils.error(logger, logsId, desc + "入参:", disId);
	Tuple<DealerCreditInfoDTO,DealerCreditInfoRecordDTO> dis = null;
	try {
		Result<Tuple<DealerCreditInfoDTO,DealerCreditInfoRecordDTO>>
		 result = (Result<Tuple<DealerCreditInfoDTO,DealerCreditInfoRecordDTO>>)RemoteClientUtils.getDefaultClient().executeToObject(QUERY_DIS_INFO,disId);
		if(result.getStatus()== RemoteCommConstant.REMOTE_SUCCES_STATUS){
			dis= result.getRe();
		}else{
			LogUtils.error(logger, logsId, desc + "失败原因:", result.getMsg());
		}
	} catch (Exception e) {
		LogUtils.error(logger, logsId, desc + "异常信息:", e);
	}
	return dis;
}
 summary:(我的公司目前使用的是这种形式)
      优点:
      1.封装了tuple工具,通过出参个数选用不同的tuple工具,接口方和调用方都通过tuple建立起了规范。
      2.对Map形式出参进行了优化,出参的数量确定了。

      缺点:
      1.没能明确地指出,出参中的key的内容是什么,没有文档,这个服务的调用方是不敢往下写的。


3.Enum
      这种方式是我无意间在网上看到的,结合对上述2种形式的思考,发现正好可以解决上述优化前后仍然存在的缺陷。
     小哥哥的文章地址:https://www.cnblogs.com/beiyeren/p/3835548.html 

    EnumMap作为返回值类型,自己定义一个enum,将可能返回的属性名定义为enum取值即可
    -----------------------------------start--此代码块来自上述网址--start------------------------------------------
    接口:
public interface TestService {

    enum UserInfoProperty {
        ROOM,CELLPHONE,Name
    }
    public EnumMap<UserInfoProperty,Object> getUserInfoByName(String name);
}
   实现:
public class TestServiceImpl implements TestService {

    @Override
    public EnumMap<UserInfoProperty, Object> getUserInfoByName(String name) {
        EnumMap<UserInfoProperty,Object> retMap = new EnumMap<UserInfoProperty, Object>(UserInfoProperty.class);
        retMap.put(UserInfoProperty.ROOM,"0003");
        retMap.put(UserInfoProperty.CELLPHONE,"00004");
        retMap.put(UserInfoProperty.Name,name);
        return retMap;
    }
}

 调用:

public class App 
{
    public static void main( String[] args )
    {
        TestService testService = new TestServiceImpl();
        String name = "testName";
        EnumMap<TestService.UserInfoProperty,Object> userInfo = testService.getUserInfoByName(name);
         userInfo.entrySet().iterator();
        System.out.println(userInfo.get(TestService.UserInfoProperty.Name));
        System.out.println(userInfo.get(TestService.UserInfoProperty.ROOM));
        System.out.println(userInfo.get(TestService.UserInfoProperty.CELLPHONE));
    }
}
------------------------------------end--此代码块来自上述网址--end--------------------------------------------

    summary:
    优点:
    1.反参可以是多个值。
    2.通过枚举(最好定义在base中),同一家公司内部,以此方式作为返回值的服务,基本不用看javadoc或者api文档,就知道出参有哪些了。


    总之,自己敲过的代码,多反思怎么能写的更好,再去看看别人怎么写,这样成长的很快。

猜你喜欢

转载自blog.csdn.net/u013047584/article/details/80462379