/**
* 实现的效果是:
* 同一个service.getProvider()方法
*
* Provider 使用request1参数来调用,得到的返回值是Provider
* Provider2使用request2参数来调用,得到的返回值是Provider2
*/
package a; import java.util.List; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElementWrapper; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlTransient; import javax.xml.bind.annotation.XmlType; /** * * @author bragel * */ @XmlType @XmlAccessorType(XmlAccessType.FIELD) @XmlRootElement(name = "provider") public class Provider { @XmlElement(name = "provider_id") private int id; private Address address; /** * List会转化成一个item数组,item节点是network,包含items的节点是networks */ @XmlElementWrapper(name = "networks") @XmlElement(name = "network") private List<Network> networks; @XmlElement(name = "is_primary_care_physician") private boolean primaryCarePhysician; /** * 不会被输出 */ @XmlTransient private String remark; public int getId() { return id; } public void setId(int id) { this.id = id; } public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; } public List<Network> getNetworks() { return networks; } public void setNetworks(List<Network> networks) { this.networks = networks; } public boolean isPrimaryCarePhysician() { return primaryCarePhysician; } public void setPrimaryCarePhysician(boolean primaryCarePhysician) { this.primaryCarePhysician = primaryCarePhysician; } public String getRemark() { return remark; } public void setRemark(String remark) { this.remark = remark; } public String toString() { return String.format("Provider:id:%s;address:%s;", id, address); } }
package a; import java.util.List; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElementWrapper; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlTransient; import javax.xml.bind.annotation.XmlType; /** * * @author bragel * */ @XmlType @XmlAccessorType(XmlAccessType.FIELD) @XmlRootElement(name = "provider") public class Provider2 { @XmlElement(name = "provider_id") private int id; @XmlElement(name = "address") private Address2 address2 = new Address2(); /** * List会转化成一个item数组,item节点是network,包含items的节点是networks */ @XmlElementWrapper(name = "networks") @XmlElement(name = "network") private List<Network> networks; @XmlElement(name = "is_primary_care_physician") private boolean primaryCarePhysician; /** * 不会被输出 */ @XmlTransient private String remark; public int getId() { return id; } public void setId(int id) { this.id = id; } public Address2 getAddress2() { return address2; } public void setAddress2(Address2 address2) { this.address2 = address2; } public List<Network> getNetworks() { return networks; } public void setNetworks(List<Network> networks) { this.networks = networks; } public boolean isPrimaryCarePhysician() { return primaryCarePhysician; } public void setPrimaryCarePhysician(boolean primaryCarePhysician) { this.primaryCarePhysician = primaryCarePhysician; } public String getRemark() { return remark; } public void setRemark(String remark) { this.remark = remark; } public String toString() { return String.format("Provider2:id:%s;address:%s;", id, address2); } }
package a; public class Request1 { private int providerId; private Integer networkId; private double latitude; private double longitude; @Override public String toString() { return String.format("ProviderIdentifier{providerId=%d, networkId=%d, latitude=%s, longitude=%s}", providerId, networkId, latitude, longitude); } public Integer getNetworkId() { return networkId; } public void setNetworkId(Integer networkId) { this.networkId = networkId; } public double getLatitude() { return latitude; } public void setLatitude(double latitude) { this.latitude = latitude; } public double getLongitude() { return longitude; } public void setLongitude(double longitude) { this.longitude = longitude; } public int getProviderId() { return providerId; } public void setProviderId(int providerId) { this.providerId = providerId; } }
package a; /* * @author Brage */ public class Request2 { private int providerId; private int addressId; @Override public String toString() { return String.format("ProviderIdentifier{providerId=%d, addressId=%d}", providerId, addressId); } public int getProviderId() { return providerId; } public void setProviderId(int providerId) { this.providerId = providerId; } public int getAddressId() { return addressId; } public void setAddressId(int addressId) { this.addressId = addressId; } }
package a; /** * * @author bragel * */ public class RequestCommon { private int providerId; private Integer networkId; private double latitude = 0d; private double longitude = 0d; private int returnAddressId = 1; private int addressId = 0; public int getProviderId() { return providerId; } public void setProviderId(int providerId) { this.providerId = providerId; } public Integer getNetworkId() { return networkId; } public void setNetworkId(Integer networkId) { this.networkId = networkId; } public double getLatitude() { return latitude; } public void setLatitude(double latitude) { this.latitude = latitude; } public double getLongitude() { return longitude; } public void setLongitude(double longitude) { this.longitude = longitude; } public int getAddressId() { return addressId; } public void setAddressId(int addressId) { this.addressId = addressId; } public int getReturnAddressId() { return returnAddressId; } public void setReturnAddressId(int returnAddressId) { this.returnAddressId = returnAddressId; } }
Provider与Provider2的属性大部分是相同的,只是address不同,Provider的address里带经纬度,而Provider2里的address2没经纬度,address2的属性是address的属性的子集。
Request1里包含经纬度来查询Provider,
Request2里包含addressId来查询Provider2,
RequestCommon是Request1和Request2属性的全集。
我们先来看主要类,其他Address, Address2, Network等之后再贴出。
package a; import java.util.Arrays; /** * * @author bragel * */ public class ProviderService { /** * 所有要使用到的泛型都必須在public/private等之後,返回類型void/String等之前用<>定義 * 如<T, V> * 只是類型定義,不是返回類型,返回類型該是String或者T還是不能少 * * @param clientId * @param request * @param t * @return * @throws Exception */ public <T, V> T getProvider(String clientId, V request, Class<T> t) throws Exception { /** * 1.request1, request2 -> RequestCommon(全集) */ RequestCommon common = V2Util.convert(request); /** * 2.用RequestCommon查询数据库,获得Provider(全集) */ Provider p = getProvider(common); /** * 3.Provider -> Provider2或者Provider? */ return V2Util.convert(p, t, common.getReturnAddressId()); } /** * 查询Provider * * @param request * @return */ private Provider getProvider(RequestCommon request) { Provider provider = new Provider(); provider.setId(1); provider.setPrimaryCarePhysician(true); provider.setRemark("hello"); Network n1 = new Network(); n1.setId(1); n1.setCarrierGroupId(1); n1.setCarrierIds(Arrays.asList(new Integer[] { 1, 2 })); Network n2 = new Network(); n1.setId(2); n1.setCarrierGroupId(1); n1.setCarrierIds(Arrays.asList(new Integer[] { 1, 2, 3 })); provider.setNetworks(Arrays.asList(new Network[] { n1, n2 })); /** * 根据这个returnAddressId,区分查询数据库 */ if (request.getReturnAddressId() == 1) { provider.setRemark("world"); } Address address = new Address(); address.setId(1); address.setCity("city"); address.setCounty("country"); address.setStreet("street"); address.setState("state"); address.setZip("zip"); provider.setAddress(address); return provider; } }
package a; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.apache.commons.beanutils.PropertyUtils; /** * * @author bragel * */ public class V2Util { /** * Request1 (providerId,networkId,latitude,longitude) * Request2 (providerId,addressId) * RequestCommon (providerId,networkId,latitude,longitude, returnAddressId,addressId) * RequestCommon有以上两个类的所有属性(全集),并有returnAddressId来区分是哪一个类 * * RequestCommon -> Request1或者Request2 * * @param pi * @param t * @return * @throws Exception */ public static <T> List<T> convert(List<RequestCommon> pi, Class<T> t) throws Exception { List<T> cs = new ArrayList<T>(); for (RequestCommon p : pi) { T c = t.newInstance(); PropertyUtils.copyProperties(c, p); cs.add(c); } return cs; } /** * ProviderIdentifier或者ProviderIdentifier2 -> ProviderIdentifierCommon * * @param pi * @return * @throws Exception */ public static <T> List<RequestCommon> convert(List<T> pi) throws Exception { List<RequestCommon> cs = new ArrayList<RequestCommon>(); for (T p : pi) { cs.add(convert(p)); } return cs; } public static <T> RequestCommon convert(T p) throws Exception { RequestCommon c = RequestCommon.class.newInstance(); PropertyUtils.copyProperties(c, p); if (c.getAddressId() != 0) { c.setReturnAddressId(0); } return c; } /** * Provider -> Provider2, Provider? * 注意Provider和Provider2的address不一样, * Provider2的Address2有更多属性 * 既然Address和Address2是不同类型,所以它们在Provider和Provider2里就不能同名,1个叫address,1个叫address2 * 同名不同类型时,PropertyUtils.copyProperties(c, p);会报错 * 叫address2后,PropertyUtils.copyProperties(c, p);就不能给address2赋值,需要手动进行 * * 在Provider2里给address2默认初始化private Address2 address2 = new Address2();, * 也可手动赋值,PropertyUtils.setProperty(c, "address", new Address2()); * 然后再把Provider的address赋值给它,PropertyUtils.copyProperties(PropertyUtils.getProperty(c, "address2"), PropertyUtils.getProperty(p, "address")); * * @param p * @param t * @return * @throws Exception */ public static <T> T convert(Provider p, Class<T> t, int returnAddressId) throws Exception { T c = t.newInstance(); PropertyUtils.copyProperties(c, p); if (returnAddressId == 0) { PropertyUtils.copyProperties(PropertyUtils.getProperty(c, "address2"), PropertyUtils.getProperty(p, "address")); } return c; } }
package a; import java.util.List; /* * @author bragel * */ public class Test { /** * public <T, V> T getProvider(String clientId, V request, Class<T> t) * * 所有要使用到的泛型都必須在public/private等之後,返回類型void/String等之前用<>定義 * 如<T, V> * <T, V>只是類型定義,不是返回類型,返回類型該是String或者T還是不能少 * @throws Exception * */ public static void main(String[] args) throws Exception { // TODO Auto-generated method stub ProviderService service = new ProviderService(); Request1 request1 = new Request1(); request1.setLatitude(0d); request1.setLongitude(0d); request1.setNetworkId(1); request1.setProviderId(1); Request2 request2 = new Request2(); request2.setProviderId(1); request2.setAddressId(1); /** * 实现的效果是: * 同一个service.getProvider()方法 * * Provider 使用request1参数来调用,得到的返回值是Provider * Provider2使用request2参数来调用,得到的返回值是Provider2 */ Provider provider = service.getProvider("clientId", request1, Provider.class); Provider2 provider2 = service.getProvider("clientId", request2, Provider2.class); System.out.println(JaxbUtil.java2xml(provider, Provider.class)); System.out.println(JaxbUtil.java2xml(provider2, Provider2.class)); } }
---------------------------------------------------------------------------------------
package a; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlType; /** * * @author bragel * */ @XmlType @XmlAccessorType(XmlAccessType.FIELD) public class Address { @XmlElement(name = "address_id") private int id; @XmlElement(name = "street") private String street; @XmlElement(name = "county") private String county; @XmlElement(name = "city") private String city; @XmlElement(name = "state") private String state; @XmlElement(name = "zip") private String zip; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getStreet() { return street; } public void setStreet(String street) { this.street = street; } public String getCounty() { return county; } public void setCounty(String county) { this.county = county; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } public String getState() { return state; } public void setState(String state) { this.state = state; } public String getZip() { return zip; } public void setZip(String zip) { this.zip = zip; } public String toString() { return String.format("Address:id:%s;street:%s;country:%s;city:%s;state:%s;zip:%s;", id, street, county, city, state, zip); } }
package a; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlType; /** * * @author bragel * */ @XmlType @XmlAccessorType(XmlAccessType.FIELD) public class Address2 { @XmlElement(name = "address_id") private int id; @XmlElement(name = "street") private String street; @XmlElement(name = "county") private String county; @XmlElement(name = "city") private String city; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getStreet() { return street; } public void setStreet(String street) { this.street = street; } public String getCounty() { return county; } public void setCounty(String county) { this.county = county; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } public String toString() { return String.format("Address2:id:%s;street:%s;country:%s;city:%s;", id, street, county, city); } }
package a; import javax.xml.bind.annotation.*; import java.util.ArrayList; import java.util.List; @XmlType @XmlAccessorType(XmlAccessType.FIELD) public class Network { @XmlElement(name = "network_id") private int id; @XmlElement(name = "name") private String name; @XmlElementWrapper(name = "carrierIds") @XmlElement(name = "carrier_id") private List<Integer> carrierIds = new ArrayList<Integer>(); @XmlTransient private int carrierGroupId; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public List<Integer> getCarrierIds() { return carrierIds; } public void setCarrierIds(List<Integer> carrierIds) { this.carrierIds = carrierIds; } public int getCarrierGroupId() { return carrierGroupId; } public void setCarrierGroupId(int carrierGroupId) { this.carrierGroupId = carrierGroupId; } }
package a; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.StringReader; import javax.xml.bind.JAXBContext; import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; public class JaxbUtil { /** * java -> xml String * */ public static String java2xml(Object obj, Class beanClass) throws Exception { JAXBContext context = JAXBContext.newInstance(beanClass); // 根据上下文获取marshaller对象 Marshaller marshaller = context.createMarshaller(); // 设置编码字符集 marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8"); // 格式化XML输出,有分行和缩进 marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); // 打印到控制台 //marshaller.marshal(obj, System.out); ByteArrayOutputStream baos = new ByteArrayOutputStream(); marshaller.marshal(obj, baos); String xmlObj = new String(baos.toByteArray()); return xmlObj.replace(" standalone=\"yes\"", ""); } /** * java -> xml file * */ public static void java2xmlFile(Object obj, Class beanClass, File file) throws Exception { JAXBContext context = JAXBContext.newInstance(beanClass); // 根据上下文获取marshaller对象 Marshaller marshaller = context.createMarshaller(); // 设置编码字符集 marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8"); // 格式化XML输出,有分行和缩进 marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); // 打印到控制台 //marshaller.marshal(obj, System.out); marshaller.marshal(obj, file); } /** * xml -> java * */ public static <T> T xml2java(String xml, Class<T> beanClass) throws Exception { T bean = beanClass.newInstance(); JAXBContext context = JAXBContext.newInstance(beanClass); Unmarshaller unmarshaller = context.createUnmarshaller(); bean = (T) unmarshaller.unmarshal(new StringReader(xml)); return bean; } /** * xml file -> java * */ public static <T> T xmlFile2java(File file, Class<T> beanClass) throws Exception { T bean = beanClass.newInstance(); JAXBContext context = JAXBContext.newInstance(beanClass); Unmarshaller unmarshaller = context.createUnmarshaller(); bean = (T) unmarshaller.unmarshal(file); return bean; } }
因为Address2的属性是Address的子集,所以现在这样就可以了。
反之,如果Address2包含Address没有的属性,就需要跟Request一样,加一个AddressCommon了。
输出:
<?xml version="1.0" encoding="UTF-8"?> <provider> <provider_id>1</provider_id> <address> <address_id>1</address_id> <street>street</street> <county>country</county> <city>city</city> <state>state</state> <zip>zip</zip> </address> <networks> <network> <network_id>2</network_id> <carrierIds> <carrier_id>1</carrier_id> <carrier_id>2</carrier_id> <carrier_id>3</carrier_id> </carrierIds> </network> <network> <network_id>0</network_id> <carrierIds/> </network> </networks> <is_primary_care_physician>true</is_primary_care_physician> </provider> <?xml version="1.0" encoding="UTF-8"?> <provider> <provider_id>1</provider_id> <address> <address_id>1</address_id> <street>street</street> <county>country</county> <city>city</city> </address> <networks> <network> <network_id>2</network_id> <carrierIds> <carrier_id>1</carrier_id> <carrier_id>2</carrier_id> <carrier_id>3</carrier_id> </carrierIds> </network> <network> <network_id>0</network_id> <carrierIds/> </network> </networks> <is_primary_care_physician>true</is_primary_care_physician> </provider>
相关推荐
当我们谈论“java带两个类型参数的泛型”时,这意味着我们正在处理一个泛型类或泛型方法,它们接受不止一个类型作为参数。这样的设计可以让我们在不同数据类型之间建立更复杂的关联,同时保持类型安全。 首先,让...
在Java中,<T> T和T的区别是,T是Type的首字母缩写:<T> T表示“返回值”是一个泛型,传入什么类型,就返回什么类型;而单独的“T”表示限制传入的参数类型。<T> T的用法是,表示返回值T的类型是泛型,T是一个占位符...
Java集合框架中的许多类都使用了泛型,如`ArrayList<T>`、`HashMap<K, V>`等。泛型使得我们可以指定容器存储的数据类型,从而避免了不必要的类型转换和可能的ClassCastException。 8. 野指针异常 在泛型中,如果...
例如,可以定义一个泛型方法,使其能接受不同类型的参数并返回不同类型的值。 9. **类型推断** - 自JDK 7起,Java引入了类型推断,允许在某些情况下省略类型参数,编译器会根据上下文自动推断类型。 理解并熟练...
- **泛型类**:如Stack<T>,定义了一个可以接受任何类型T的类,T称为类型参数。类的方法可以操作这些类型参数,使得类的行为可以适应多种类型的数据。 - **泛型方法**:在非泛型类中,可以定义只接受特定类型参数的...
例如,如果一个方法返回`Object`类型,但在实际使用时我们知道它应该是`T`类型,那么就需要使用`(T)`对返回的对象进行强制类型转换。然而,这种转换只有在类型参数的实际类型已知且匹配时才是安全的,否则会导致...
1. 泛型方法的返回类型可以使用类型参数,如`public <T> T max(List<T> list) {...}`。 2. 泛型方法的返回类型可以根据传入参数的类型推断,这是Java 7引入的钻石操作符<>的用途。 六、泛型与数组 1. 泛型与数组...
例如,`printT` 方法中的`<T> void printT(ArrayList<T> al)`,这里的`T`可以在方法内部被当作一个具体的类型来使用。 3. **泛型的实际应用** - 使用泛型集合:`List<T>` 和 `ArrayList<T>` 可以在编译时确保添加...
- **泛型类**:泛型类是在类定义时引入类型参数的,如`Box<T>`中的`T`,它代表一个未指定的具体类型。这种设计使得类能够处理不同类型的对象,而不必为每种类型创建单独的类。例如,`Box<Integer>`、`Box<Double>`...
`get` 方法同样使用泛型,它返回一个 `T` 类型的值,其中 `T` 必须是 `V` 的子类。虽然在获取值时仍需要进行类型转换,但编译器会在编译时检查类型匹配,从而提供类型安全性。 请注意,虽然这个改进提高了类型安全...
- **多个类型参数**:一个泛型可以有多个类型参数,如 `<T, U, V>`。 - **有界类型**:使用`<T extends Superclass>`来限定类型参数必须是某个超类或接口的子类,这被称为有界类型。 - **通配符类型**:通配符类型如...
2. Stack<T>(IEnumerable<T>):接受一个IEnumerable<T>接口实现的集合,根据集合的元素数量初始化堆栈,容量至少能容纳这些元素。 3. Stack<T>(Int32):传入一个整数参数,表示初始容量,如果这个值小于默认容量,将...
泛型类允许我们创建具有类型参数的类,这样我们就可以在不同的上下文中使用相同的基本逻辑,而不需要重复代码。泛型方法则允许我们在不使用泛型类的情况下声明泛型方法,这对于创建通用函数非常有帮助。 #### 总结 ...
23.5<br> 15.9<br><br>SqlMap:20.3<br> 1.48<br><br>1.16<br> <br>查询结果集(平均101行)<br><br>(1循环200次select)<br> 1055.1<br> 666.8<br><br>不定字段:710.1<br> 1.58<br><br>1.50<br> <br><br> <br><br>表...
此外,它也用于接口(如`Comparable<T>`)、枚举(`EnumSet<E>`)、方法返回类型以及匿名类等场景。 总的来说,Java泛型提供了一种强大的工具,使我们能够在编写代码时进行更严格的类型检查,减少运行时错误,提高...
泛型的使用不仅限于类和接口,还可以用于方法参数和返回类型。这允许在创建泛型方法时,不依赖于类的泛型类型,从而提供更灵活的方法实现。 总结来说,泛型是Java语言中一项强大的特性,它通过在编译时期提供类型...
18.0<br>1.23<br><br>1.10<br><br>每秒插入实体<br><br>(20次insert)<br>41<br>21<br>1.95<br><br>更新实体<br><br>(20次单条update)<br>27<br>19<br><br>SqlMap:24<br>1.42<br><br>1.13<br><br>查询结果集(平均101...
18.0<br>1.23<br><br>1.10<br><br>每秒插入实体<br><br>(20次insert)<br>41<br>21<br>1.95<br><br>更新实体<br><br>(20次单条update)<br>27<br>19<br><br>SqlMap:24<br>1.42<br><br>1.13<br><br>查询结果集(平均101...
在示例代码中,我们看到两个使用泛型的类:`Point<T>` 和 `Notepad<K, V>`。 1. `Point<T>` 类定义了一个类型参数 `T`,代表一个未知的数据类型。`T` 只是一个占位符,可以被任何类型替换。类中的成员变量 `var` 和...