通用数据类型转换方法 [英] Generic data type conversion method

查看:106
本文介绍了通用数据类型转换方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题是针对 opensas 的另一个问题:在java中建立一个通用的初始化函数

从他的问题变得清楚,他需要从任何数据类型 T1 转换为另一种类型 T2 。当我在这里说数据类型时,我的意思是限于那些通常用于表示原始数据的类型: Integer String Date 等等。为了这个问题的目的,我们可以考虑将原始元素装箱。



m想知道是否有任何支持在输入和输出都推广到一组支持的数据类型的类型之间进行转换的API。我查看了 Apache Commons' beanutils.converters包,但每个已知输入都有一个单独的转换器类。我正在寻找任何实现如下签名的功能:

  static< IN,OUT> OUT转换(IN值,Class< OUT> targetType); 

或其他

  static< IN,OUT> OUT转换(IN值,OUT默认值); 

实现这种映射真的不会太困难,要么使用一堆 else if 指向各种Commons Converters的块,或者 Map< Class<>,Converter> for相同的目的。但是我想知道这种功能是否支持某个地方。



另外,如果这样做是重复的,我很抱歉。我试图找到类似的问题,当我发现没有匹配这种情况时感到惊讶。



编辑:

 整数i = GenericConverter.convert(123,Integer.class); //返回123 
日期d = GenericConverter.convert(1313381772316L,Date.class); //返回今天的日期
Boolean b = GenericConverter.convert(0,Boolean.class); //返回false
Long l = GenericConverter.convert(asdf,Long.class); // RuntimeException

更新:链接的BalusC代码接近mark,Bohemian的答案是一个不错的轻量级解决方案(尽管它不适用于布尔转换)。如果我们想推广这些其他数据类型的转换,那么日期应该单独处理也是正确的。我仍然希望能得到更多的答案 - 尤其是如果有更多的可用的API可用的话。

JDK 8 ,这可以通过新的 java.util.functions.Mapper 接口和 lambda表达式

  Mapper< String,Integer> atoi = s  - > Integer.valueOf(一个或多个); 
Integer r = atoi.map(10);

使用方法引用可以更简单:

  Mapper< String,Integer> atoi = Integer :: new; 
Integer r = atoi.map(10);

或类似的东西:

 列表与LT;长>日期= asList(1344754620310L,1344754854877L); 
列表<日期> asDates = dates.map(Date :: new).into(new ArrayList< Date>());

或者酷酷的转换:

 列表与LT;整数> myInts =5,4,3,2,1,0,6,7,8,9
.splitAsStream(,)
.map(Integer :: new)
.into(new ArrayList< Integer>());

在JDK8 API的当前实现中,已经定义了一些默认映射器(即 LongMapper IntMapper DoubleMapper ),还有一个工具类叫做code> Mappers ,它定义了其他一些类似于字符串映射器,身份映射器,常量映射器等的元素。



我不确定如果这是你以后的事情,但它肯定是实现它的一个好方法。



像你所建议的例子:

  static< IN,OUT> OUT转换(IN值,Class< OUT> targetType); 

可以使用 Mappers 实用程序类实现:

  Mapper< String,Integer> atoi = Mappers.instantiate(String.class,Integer.class); 
Integer r = atoi.map(10);

您的签名:

  static< IN,OUT> OUT转换(IN值,OUT默认); 

可以用类似的方式实现:

  Mapper< String,Integer> atoi = chain(substitute(null,0),Integer :: new); 
Integer r = atoi.map(null); //产生0

同样,这样的代码...

 列表< String> data = asList(0,null,2,null,4,null,6); 
列表<整数> (new ArrayList< Integer>()); myInts = data.map(chain(substitute(null,0),Integer :: new)
System.out.println(myInts);

会产生: [0,0,2,0,4,0 ,6]


This question is in response to another question by opensas: building a generic initializer function in java

From his question it became clear that he needs to convert from any data type T1 to another type T2. When I say "data type" here, I mean types limited to those commonly used to represent raw data: Integer, String, Date, etc. For the purpose of this question we can consider primitives to be boxed.

I'm wondering if there is any API that supports conversion between types where both the input and output are generalized to a set of supported data types. I had a look at Apache Commons' beanutils.converters package, but there's a separate converter class for each known input. I'm looking for any functionality that implements something like the following signature:

static <IN, OUT> OUT convert(IN value, Class<OUT> targetType);

or else

static <IN, OUT> OUT convert(IN value, OUT defaultValue);

It really wouldn't be too hard to implement this kind of mapping oneself, either using a bunch of else if blocks pointing to the various Commons Converters, or else a Map<Class<?>, Converter> for the same purpose. But I'm wondering if this kind of functionality is supported somewhere.

Also, if this winds up being a duplicate I apologize. I tried finding similar questions and was surprised when I found none matching this situation.

EDIT: so an example of this code in action would be:

Integer i = GenericConverter.convert("123", Integer.class);    //returns 123
Date d = GenericConverter.convert(1313381772316L, Date.class); //returns today's date
Boolean b = GenericConverter.convert(0, Boolean.class);        //returns false
Long l = GenericConverter.convert("asdf", Long.class);         //RuntimeException

UPDATE: The BalusC code I linked falls close to the mark, and Bohemian's answer is a nice lightweight solution (although it doesn't work for Boolean conversions). He's also right that Dates should be probably be handled separately if we want to generalize conversion of these other data types. I'm still hoping for additional answers though - especially if there is more of a hands-off API available somewhere.

解决方案

In JDK 8 this can be easily implemented with the new java.util.functions.Mapper interface and a lambda expression.

Mapper<String,Integer> atoi = s -> Integer.valueOf(s);
Integer r = atoi.map("10");

Using method references it can be even simpler:

Mapper<String, Integer> atoi = Integer::new;
Integer r = atoi.map("10");

Or things like:

List<Long> dates = asList(1344754620310L,1344754854877L);
List<Date> asDates = dates.map(Date::new).into(new ArrayList<Date>());

Or cool conversions like:

List<Integer> myInts = "5,4,3,2,1,0,6,7,8,9"
  .splitAsStream(",")
  .map(Integer::new)
  .into(new ArrayList<Integer>());

In the current implementation of the JDK8 API, a few default mappers have been defined (i.e. LongMapper, IntMapper, DoubleMapper) and there's a utility class called Mappers that defines some others like a string mapper, and identity mapper, a constant mapper, etc.

I am not sure if this is what you are after, but certainly it must be a nice way to implement it.

Cases like the one you suggest for:

static <IN, OUT> OUT convert(IN value, Class<OUT> targetType);

Can be implemented with the Mappers utility class:

Mapper<String, Integer> atoi = Mappers.instantiate(String.class, Integer.class);
Integer r = atoi.map("10");

And your signature:

static <IN, OUT> OUT convert(IN value, OUT default);

Could be implemented with something like:

Mapper<String, Integer> atoi = chain(substitute(null, "0"), Integer::new);
Integer r = atoi.map(null); //produces 0

As such, a code like this...

List<String> data = asList("0", null, "2", null, "4", null, "6");
List<Integer> myInts = data.map(chain(substitute(null, "0"), Integer::new)).into(new ArrayList<Integer>());
System.out.println(myInts);

Would yield: [0, 0, 2, 0, 4, 0, 6]

这篇关于通用数据类型转换方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆