Java 如何同时返回多个不同类型

目录
  • Java 同时返回多个不同类型
    • 前言
    • 首先我们创建一个2维元组
    • 我们可以利用继承机制实现长度更长的元组
    • 实例
  • java return返回多个值或多种类型的值方法(list;Map)
    • 1、在写方法的时候
    • 2、具体思路都在代码注释里了

Java 同时返回多个不同类型

前言

虽然对于这种需求不常用,且比较冷门,但是还是有其存在的价值,再次做一下整理。我们常用的return语句只允许返回单个对象,相对的解决办法就是创建一个对象,用它来持有想要返回的多个对象。

实现这种功能,还要归功于Java1.5的新特性-泛型,我们利用泛型,可以一次性地解决该问题,以后再也不用在这个问题上浪费时间了,并且,我们可以再编译期就能够确保类型安全。

你也许已经想到使用集合可以实现我们的需求,但是虽然一次可以返回多个值,但是其类型都是相同的,并不完全符合我们的需求。

我们需要引入一个概念:元组(tuple),元组也称为数据传送对象或信使。元组是将一组对象直接打包存储于其中的一个单一对象,这个容器对象允许读取其中元素,但是不允许向其中存放新的对象。

通常,元组可以具有任意长度,同时元组中的对象可以是任意不同的类型。我们能够为每一个对象指明其类型,并且可以正确读取到数据,这就是元组可以提供的功能。我们要处理不同长度的问题,需要创建多个不同的元组。

首先我们创建一个2维元组

//: net/mindview/util/TwoTuple.java(Java编程思想_代码_目录)
package net.mindview.util;
public class TwoTuple<A, B> {
 public final A first;
 public final B second;
 public TwoTuple(A a, B b) {
  first = a;
  second = b;
 }
 public String toString() {
  return "(" + first + ", " + second + ")";
 }
}

构造器捕获了要存储的对象,而toString()方法是一个便利函数,用来显示列表中的值。

注意:元组隐含地保持了其中元素的次序。

阅读上面的代码,以及根据元组的定义,你一定会感到诧异,设计思路不是应该将first和second声明为private,然后生成这两个变量的get方法吗?

以上是我们大多数人的思维,但是我们仔细分析上面的代码,可以发现完全符合我们的要求。首先我们可以读取first和second,并且因为使用了final声明,我们就无法在修改其值。我们对比这两种写法,很显然,上面给出的代码更加合理,更加简洁明了。

还有另一种设计考虑,即你确实希望允许客户端程序员改变first或second所引用的对象。然而,采用上面的形式无疑是更安全的做法,这样的话,如果程序员想要使用具有不同元素的元组,就强制要求他们另外创建一个新的TwoTuple对象。

我们可以利用继承机制实现长度更长的元组

//: net/mindview/util/ThreeTuple.java
package net.mindview.util;

public class ThreeTuple<A,B,C> extends TwoTuple<A,B> {
  public final C third;
  public ThreeTuple(A a, B b, C c) {
    super(a, b);
    third = c;
  }
  public String toString() {
    return "(" + first + ", " + second + ", " + third +")";
  }
}
//: net/mindview/util/FourTuple.java
package net.mindview.util;

public class FourTuple<A,B,C,D> extends ThreeTuple<A,B,C> {
  public final D fourth;
  public FourTuple(A a, B b, C c, D d) {
    super(a, b, c);
    fourth = d;
  }
  public String toString() {
    return "(" + first + ", " + second + ", " +
      third + ", " + fourth + ")";
  }
}
//: net/mindview/util/FiveTuple.java
package net.mindview.util;

public class FiveTuple<A,B,C,D,E>
extends FourTuple<A,B,C,D> {
  public final E fifth;
  public FiveTuple(A a, B b, C c, D d, E e) {
    super(a, b, c, d);
    fifth = e;
  }
  public String toString() {
    return "(" + first + ", " + second + ", " +
      third + ", " + fourth + ", " + fifth + ")";
  }
}

为了使用元组,你只需定义一个长度适合的元组,将其作为方法的返回值,然后在return语句中创建该元组,并返回即可。

实例

//: generics/TupleTest.java
import net.mindview.util.*;
class Amphibian {
}
class Vehicle {
}

public class TupleTest {
 static TwoTuple<String, Integer> f() {
  // Autoboxing converts the int to Integer:
  return new TwoTuple<String, Integer>("hi", 47);
 }
 static ThreeTuple<Amphibian, String, Integer> g() {
  return new ThreeTuple<Amphibian, String, Integer>(new Amphibian(), "hi",
    47);
 }
 static FourTuple<Vehicle, Amphibian, String, Integer> h() {
  return new FourTuple<Vehicle, Amphibian, String, Integer>(new Vehicle(),
    new Amphibian(), "hi", 47);
 }
 static FiveTuple<Vehicle, Amphibian, String, Integer, Double> k() {
  return new FiveTuple<Vehicle, Amphibian, String, Integer, Double>(
    new Vehicle(), new Amphibian(), "hi", 47, 11.1);
 }
 public static void main(String[] args) {
  TwoTuple<String, Integer> ttsi = f();
  System.out.println(ttsi);
  // ttsi.first = "there"; // Compile error: final
  System.out.println(g());
  System.out.println(h());
  System.out.println(k());
 }
}

输出结果:

(hi, 47)

(Amphibian@15db9742, hi, 47)

(Vehicle@6d06d69c, Amphibian@7852e922, hi, 47)

(Vehicle@4e25154f, Amphibian@70dea4e, hi, 47, 11.1)

由于有了泛型,你可以很容易地创建元组,令其返回一组任意类型的对象。而你所要做的,只是编写表达式而已。

通过ttsi.first = "there";语句的错误,我们可以看出,final声明确实能够保护public元素,在对象被构造出来之后,声明为final的元素便不能被再赋予其他值了。

java return返回多个值或多种类型的值方法(list;Map)

1、在写方法的时候

有时候需要返回多个值,有时候返回的多个值的类型还不同,依据不同情况以下提供了三种方法返回多个值。

2、具体思路都在代码注释里了

如果返回的多个值类型相同,可以用方法一和方法二;如果返回的多个值类型不同,可以用方法三。

import java.util.*;
public class Demo {
    //方法1:返回list
    public static List<int[]> returnList(){
        List<int[]> list=new ArrayList<>();
        list.add(new int[]{1});
        list.add(new int[]{1, 2});
        list.add(new int[]{1, 2, 3});
        return list;
    }

    //方法2:返回Map,一个Map只能有一种数据类型
    public static Map<String, Integer> returnMap(){
        Map<String,Integer> map = new HashMap<>();
        map.put("age",1);  //”age“是key,类似于索引,1是索引对应的int值
        map.put("high",30);
        //System.out.println(map.get("age"));
        Map<String,int[]> map1 = new HashMap<>();
        map1.put("array", new int[]{1, 2, 3});
        //System.out.println(Arrays.toString(  map1.get("array") ));
        return map;
    }

    //方法3:一次性返回两种类型的数据,结合了Map和list
    public static List<Map> returnMapList(){
        Map<String,Integer> map = new HashMap<>();
        map.put("age",1);
        map.put("high",30);
        Map<String,int[]> map1 = new HashMap<>();
        map1.put("array", new int[]{1, 2});
        List<Map> listMap = new ArrayList<Map>();
        listMap.add(map);
        listMap.add(map1);
        return listMap;
    } 

//测试代码
    public static void main(String[] args){
        //返回list
        List<int[]> list1 = returnList();
        System.out.println(Arrays.toString(list1.get(0)) + Arrays.toString(list1.get(1)) + Arrays.toString(list1.get(2)) + "\nreturnlist结束\n");

        //返回Map,一个Map只能有一种数据类型
        Map<String,Integer> mapTest = returnMap();
        System.out.println("age = " + mapTest.get("age") +",   high = " + mapTest.get("high") +  "\nreturnMap结束\n");

        //一次性返回两种类型的数据,结合了Map和list
        List<Map> list2 = returnMapList();
        System.out.println(list2.get(0)  +" , " + list2.get(1)  + "\nreturnMapList结束");//list2.get(1)是数组的地址
        System.out.print("调用返回的int和int[]:");
        Map map0 = list2.get(0);
        Map map1 = list2.get(1);
        System.out.println( "age = " + map0.get("age") );
        System.out.println("array = " + Arrays.toString((int[]) map1.get("array")));
//      System.out.println(Arrays.toString((int[]) list2.get(1).get("array")));   //调用过程也可以这样写
    }
}
 

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • 浅谈Java泛型让声明方法返回子类型的方法

    泛型典型的使用场景是集合.考虑到大多数情况下集合是同质的(同一类型),通过声明参数类型,可免去类型转换的麻烦.本文将讨论本人阅读Spring Security源码时遇到的一个关于泛型递归模式的问题. 声明方法返回子类型 在Spring Security的源码里有一个ProviderManagerBuilder接口,声明如下 public interface ProviderManagerBuilder<B extends ProviderManagerBuilder<B>> ext

  • JAVA利用泛型返回类型不同的对象方法

    有时需要在方法末尾返回类型不同的对象,而return 语句只能返回一个或一组类型一样的对象.此时就需要用到泛型. 首先先解释个概念, 元组:它是将一组对象直接打包存储于其中的一个单一对象,这个容器对象允许读取其中元素,但不能修改. 利用泛型创建元组 public class ReturnTwo<A,B> { public final A first; public final B second; public ReturnTwo(A a,B b) { first = a; second = b

  • java协变返回类型使用示例

    Java 5.0添加了对协变返回类型的支持,即子类覆盖(即重写)基类方法时,返回的类型可以是基类方法返回类型的子类.协变返回类型允许返回更为具体的类型.示例程序如下: 复制代码 代码如下: import java.io.ByteArrayInputStream;import java.io.InputStream; class Base{    //子类Derive将重写此方法,将返回类型设置为InputStream的子类   public InputStream getInput()   { 

  • Java方法签名为何不包含返回值类型

    看下官方说明: 意思是java方法签名包含两个要素:方法名称和参数列表.即不包括返回值类型. 那为什么不能包含返回值类型呢? 看一下如下两段代码示例. 示例一: public String m123(int i) { return "456"; } public int m123(int i) { return 123; } // 为什么不能包含返回值的原因:编译器无法从所有的上下文中确定重载版本 // 因此为了避免"模棱两可"的局面, java方法签名中不包含返回

  • Java 如何同时返回多个不同类型

    目录 Java 同时返回多个不同类型 前言 首先我们创建一个2维元组 我们可以利用继承机制实现长度更长的元组 实例 java return返回多个值或多种类型的值方法(list:Map) 1.在写方法的时候 2.具体思路都在代码注释里了 Java 同时返回多个不同类型 前言 虽然对于这种需求不常用,且比较冷门,但是还是有其存在的价值,再次做一下整理.我们常用的return语句只允许返回单个对象,相对的解决办法就是创建一个对象,用它来持有想要返回的多个对象. 实现这种功能,还要归功于Java1.5

  • 详解springmvc之json数据交互controller方法返回值为简单类型

    当controller方法的返回值为简单类型比如String时,该如何与json交互呢? 使用@RequestBody 比如代码如下: @RequestMapping(value="/ceshijson",produces="application/json;charset=UTF-8") @ResponseBody public String ceshijson(@RequestBody String channelId) throws IOException{

  • java反射遍历实体类属性和类型,并赋值和获取值的简单方法

    实例如下: import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Date; /** * 获取实体类型的属性名和类型 * @param model 为实体类 * @author kou 为传入参数 */ public class GetModelNameAndType { public

  • Java List集合返回值去掉中括号(''[ ]'')的操作

    如下所示: 调用StringUtils工具类的strip()方法去掉中括号"[ ]": StringUtils.strip(word.toString(),"[]") //第一个参数放集合,第二个参数去掉中括号"[]" StringUtils工具类代码: package com.ktamr.common.utils; import com.ktamr.common.core.text.StrFormatter; import java.util.

  • Java Map.get()返回指定键所映射的值

    Java 集合类中的 Map.get() 方法返回指定键所映射的值.如果此映射不包含该键的映射关系,则返回 null. 语法: get(Object key)) 参数说明: key:是指定的 Map 集合中的键名. 典型应用 本示例使用 HashMap 类创建 Map 集合对象,并向集合中添加指定的内容,然后使用 get 方法获取指定键名的键值对象.代码如下: public static void main(String[] args){ Map map = new HashMap(); //定

  • Mybatis查找返回Map,List集合类型的数据方式

    Mybatis查找返回Map,List集合类型的数据 一.查找返回Bean对象的List集合 基本与返回Bean对象没什么区别,resultType依然为Bean对象的全类名,只是接口中的方法类型要进行修改 public List<Employee> getEmpListByEmail(String email); 二.查询返回Bean对象的Map集合 同样,resultType依然为Bean对象的全类名,只是接口中的方法类型要进行修改,添加注解. @MapKey("Bean对象属性

  • java高级用法之JNA中使用类型映射

    目录 简介 类型映射的本质 TypeMapper NativeMapped 总结 简介 JNA中有很多种映射,library的映射,函数的映射还有函数参数和返回值的映射,libary和函数的映射比较简单,我们在之前的文章中已经讲解过了,对于类型映射来说,因为JAVA中的类型种类比较多,所以这里我们将JNA的类型映射提取出来单独讲解. 类型映射的本质 我们之前提到在JNA中有两种方法来映射JAVA中的方法和native libary中的方法,一种方法叫做interface mapping,一种方式

  • mybatis查询返回Map<String,Object>类型的讲解

    目录 查询返回Map<String,Object>类型 mybatis返回结果为Map问题 查询返回Map<String,Object>类型 mybatis 查询返回Map<String,Object> 类型,平时没太注意怎么用,今天又遇到了总结记录一下,方便以后处理此类问题. Mapper.java中的方法: @MapKey("userId") Map<String,UserInfo> personalInfoByUserIds(Lis

  • JS返回只包含数字类型的数组实例分析

    本文实例分析了JS返回只包含数字类型的数组实现方法.分享给大家供大家参考,具体如下: 实现效果如:js123ldka78sdasfgr653 => [123,78,653] 一般做法 分析: 1.循环字符串每个字符,是数字的挑出来拼接在一起,不是数字的,就给他空的拼个逗号 2.将新字符串每一位转换为数组,再次遍历,存在的挑出来,即得到结果 var str="js123ldka78sdasfgr653"; var new_str=""; var arr=[];

随机推荐