Java映射
我们直接通过代码来讲解,实用性更强,因为这个经常会用到.
废话不多说!!
例子1:
result.setPrizes(
detailDTO.getPrizeDTOList().stream()
.sorted(Comparator.comparingInt(prizeDTO -> prizeDTO.getTiers().getCode()))
.map(prizeDTO -> {
GetActivityDetailResult.Prize prize = new GetActivityDetailResult.Prize();
prize.setPrizeId(prizeDTO.getPrizeId());
prize.setName(prizeDTO.getName());
prize.setImageUrl(prizeDTO.getImageUrl());
prize.setPrice(prizeDTO.getPrice());
prize.setDescription(prizeDTO.getDescription());
prize.setPrizeTierName(prizeDTO.getTiers().getMessage());
prize.setPrizeAmount(prizeDTO.getPrizeAmount());
prize.setValid(prizeDTO.valid());
return prize;
}).collect(Collectors.toList())
);
这段代码借助 Java 的 Stream API 来处理 detailDTO
里的 prizeDTOList
,对其排序并将每个 PrizeDTO
元素转化成 GetActivityDetailResult.Prize
对象,最后把这些对象收集到一个列表里,再设置到 result
对象中。下面从代码功能、代码优化方面进行分析:
- 排序操作:借助
sorted
方法,按照PrizeDTO
对象的tiers
属性的code
值进行升序排序。 - 映射操作:使用
map
方法,把每个PrizeDTO
对象转化为GetActivityDetailResult.Prize
对象。 - 收集操作:运用
collect
方法,把转化后的GetActivityDetailResult.Prize
对象收集到一个列表里。 - 设置结果:将收集到的列表设置到
result
对象的prizes
属性中。
1. 链式调用起点
detailDTO.getPrizeDTOList().stream()
detailDTO.getPrizeDTOList()
:调用detailDTO
对象的getPrizeDTOList
方法,获取一个PrizeDTO
类型的列表。.stream()
:将这个列表转换为一个流(Stream),以便后续可以使用 Java Stream API 进行各种操作。
2. 排序操作
.sorted(Comparator.comparingInt(prizeDTO -> prizeDTO.getTiers().getCode()))
sorted
是 Stream API 中的一个中间操作,用于对流中的元素进行排序。Comparator.comparingInt(prizeDTO -> prizeDTO.getTiers().getCode())
:创建一个比较器,按照PrizeDTO
对象的tiers
属性中的code
值进行升序排序。comparingInt
是Comparator
类的静态方法,用于根据整数类型的属性进行比较。
3. 映射操作
.map(prizeDTO -> { GetActivityDetailResult.Prize prize = new GetActivityDetailResult.Prize(); prize.setPrizeId(prizeDTO.getPrizeId()); prize.setName(prizeDTO.getName()); prize.setImageUrl(prizeDTO.getImageUrl()); prize.setPrice(prizeDTO.getPrice()); prize.setDescription(prizeDTO.getDescription()); prize.setPrizeTierName(prizeDTO.getTiers().getMessage()); prize.setPrizeAmount(prizeDTO.getPrizeAmount()); prize.setValid(prizeDTO.valid()); return prize; })
map
也是 Stream API 中的一个中间操作,用于将流中的每个元素进行转换。- 这里将每个
PrizeDTO
对象转换为一个GetActivityDetailResult.Prize
对象。具体操作是创建一个新的GetActivityDetailResult.Prize
对象,然后将PrizeDTO
对象的各个属性值复制到新对象中。
4. 收集操作
.collect(Collectors.toList())
collect
是 Stream API 中的一个终止操作,用于将流中的元素收集到一个集合中。Collectors.toList()
是Collectors
类提供的一个工厂方法,用于将流中的元素收集到一个List
集合中。
5. 设置结果
result.setPrizes(...)
- 最后,将转换并排序后的
GetActivityDetailResult.Prize
对象列表设置到result
对象的prizes
属性中。
总结
这段代码通过 Java Stream API 实现了对 PrizeDTO
列表的排序、转换和收集操作,将其转换为 GetActivityDetailResult.Prize
列表并设置到 result
对象中。这种方式代码简洁,并且充分利用了 Stream API 的并行处理能力,提高了代码的可读性和性能。
例子2:
result.setRecords(
activityList.getRecords()
.stream()
.map(activityDTO -> {
FindActivityListResult.ActivityInfo activityInfo = new FindActivityListResult.ActivityInfo();
activityInfo.setActivityId(activityDTO.getActivityId());
activityInfo.setActivityName(activityDTO.getActivityName());
activityInfo.setDescription(activityDTO.getDescription());
activityInfo.setValid(activityDTO.valid());
return activityInfo;
}).collect(Collectors.toList())
);
这段 Java 代码的核心功能是将 activityList
对象中的 records
列表里的每个 ActivityDTO
对象转换为 FindActivityListResult.ActivityInfo
对象,再把这些转换后的对象收集到一个新列表中,最后将这个新列表设置到 result
对象的 records
属性里。
代码主要由以下几个关键步骤构成:获取 ActivityDTO
列表、将列表转换为流、对每个元素进行转换、把转换后的元素收集到列表中、将列表设置到 result
对象的 records
属性。
1. 获取 ActivityDTO
列表
activityList.getRecords()
activityList
是一个对象,它是用来管理活动记录的集合类实例。getRecords()
方法会返回一个存储 ActivityDTO
对象的列表。ActivityDTO
通常是数据传输对象(Data Transfer Object),用于在不同层(如表现层、业务逻辑层、数据访问层)之间传输活动相关的数据。
2. 将列表转换为流
.stream()
stream()
方法把 activityList.getRecords()
返回的列表转换为一个流(Stream
)。流是 Java 8 引入的一种处理集合元素的抽象概念,它允许以声明式的方式对集合元素进行各种操作,比如过滤、映射、排序等。
3. 映射操作
.map(activityDTO -> { FindActivityListResult.ActivityInfo activityInfo = new FindActivityListResult.ActivityInfo(); activityInfo.setActivityId(activityDTO.getActivityId()); activityInfo.setActivityName(activityDTO.getActivityName()); activityInfo.setDescription(activityDTO.getDescription()); activityInfo.setValid(activityDTO.valid()); return activityInfo; })
map
是流的中间操作,其作用是将流中的每个元素按照指定的规则进行转换。- 这里的规则是将每个
ActivityDTO
对象转换为FindActivityListResult.ActivityInfo
对象。具体步骤如下:- 创建一个新的
FindActivityListResult.ActivityInfo
对象activityInfo
。 - 调用
ActivityDTO
对象的getActivityId()
、getActivityName()
、getDescription()
方法获取相应的属性值,并通过activityInfo
对象的setActivityId()
、setActivityName()
、setDescription()
方法将这些值设置到新对象中。 - 调用
ActivityDTO
对象的valid()
方法判断其有效性,并将结果通过activityInfo
对象的setValid()
方法设置到新对象中。 - 最后返回转换后的
activityInfo
对象。
- 创建一个新的
4. 收集操作
.collect(Collectors.toList())
collect
是流的终止操作,用于将流中的元素收集到一个集合中。Collectors.toList()
是 Collectors
类提供的一个静态方法,它会把流中的元素收集到一个 List
集合里。经过这一步,之前转换得到的 FindActivityListResult.ActivityInfo
对象就被收集到一个新的列表中。
5. 设置结果
将上一步收集得到的 FindActivityListResult.ActivityInfo
对象列表设置到 result
对象的 records
属性中。result
对象可能是用于封装最终查询结果的数据对象,通过这一步操作,result
对象就包含了转换后的活动信息列表。
总结
这段代码借助 Java Stream API 实现了对 ActivityDTO
列表的转换和收集操作,最终把转换后的结果存储到 result
对象中。这种方式让代码更加简洁易读,同时还能利用 Stream API 的并行处理能力提升性能。
Java反射(用的不多,慎用)
1、Java反射机制的核心是在程序运行时动态加载类并获取类的详细信息,从而操作类或对象的属性和方法。本质是JVM得到class对象之后,再通过class对象进行反编译,从而获取对象的各种信息。 2、Java属于先编译再运行的语言,程序中对象的类型在编译期就确定下来了,而当程序在运行时可能需要动态加载某些类,这些类因为之前用不到,所以没有被加载到JVM。通过反射,可以在运行时动态地创建对象并调用其属性,不需要提前在编译期知道运行的对象是谁。
白话理解一下反射:
我们编译时知道类或对象的具体信息,此时直接对类和对象进行操作即可,无需使用反射(reflection)
如果编译不知道类或对象的具体信息,此时应该如何做呢?这时就要用到 反射 来实现。比如类的名称放在XML文件中,属性和属性值放在XML文件中,需要在运行时读取XML文件,动态获取类的信息.
反射机制的优缺点
1、优点:
在运行时获得类的各种内容,进行反编译,对于Java这种先编译再运行的语言,能够让我们很方便的创建灵活的代码,这些代码可以在运行时装配,无需在组件之间进行源代码的链接,更加容易实现面向对象。
2、缺点:
(1)反射会消耗一定的系统资源,因此,如果不需要动态地创建一个对象,那么就不需要用反射;
(2)反射调用方法时可以忽略权限检查,因此可能会破坏封装性而导致安全问题。
反射机制常用的类文件:
Java.lang.Class;
Java.lang.reflect.Constructor;
Java.lang.reflect.Field;
Java.lang.reflect.Method;
Java.lang.reflect.Modifier;
反射的作用
动态创建对象
动态操作属性
动态调用方法
在JDK中,主要由以下类来实现Java反射机制,这些类都位于java.lang.reflect包中
Class类:代表一个类
Constructor 类:代表类的构造方法
Field 类:代表类的成员变量(属性)
Method类:代表类的成员方法
反射的入口—Class类
-Class类是Java 反射机制的起源和入口
用于获取与类相关的各种信息
提供了获取类信息的相关方法
Class类继承自Object类
-Class类是所有类的共同的图纸
每个类有自己的对象,好比图纸和实物的关系
每个类也可看做是一个对象,有共同的图纸Class,存放类的结构信息,比如类的名字、属性、方法、构造方法、父类和接口,能够通过相应方法取出相应信息
Class类的常用方法:
getFields()—— 获得类的public类型的属性。
getDeclaredFields()—— 获得类的所有属性
getField(String name)—— 获得类的指定属性
getMethods()—— 获得类的public类型的方法
getMethod (String name,Class [] args)—— 获得类的指定方法
getConstrutors()—— 获得类的public类型的构造方法
getConstrutor(Class[] args)—— 获得类的特定构造方法
newInstance()—— 通过类的无参构造方法创建对象
getName()—— 获得类的完整名字
getPackage()—— 获取此类所属的包
getSuperclass()—— 获得此类的父类对应的Class对象
使用反射创建对象
调用无参数构造方法创建对象
方法1:通过Class的newInstance()方法
该方法要求该Class对象的对应类有无参构造方法
执行newInstance()实际上就是执行无参构造方法来创建该类的实例
方法2:通过Constructor的newInstance()方法
先使用Class对象获取指定的Constructor对象
再调用Constructor对象的newInstance()创建Class对象对应类的对象
通过该方法可选择使用指定构造方法来创建对象
代码示例:通过Class的newInstance()方法
public class TestConstructor1 {
public static void main(String[] args) throws Exception{
//不使用反射创建对象
//Dog dog = new Dog();
//使用反射创建对象
//1.获取类的完整路径字符串
String className = "com.bjsxt.why.Dog";
//2.根据完整路径字符串获取Class对象信息
Class clazz = Class.forName(className);
//3.直接使用Class的方法创建对象
Object obj = clazz.newInstance();
System.out.println(obj.toString());
}
}
代码示例:通过Constructor的newInstance()方法创建对象
public class TestConstructor2 {
public static void main(String[] args) throws Exception{
//不使用反射创建对象
//Dog dog = new Dog();
//使用反射创建对象
//1.获取类的完整路径字符串
String className = "com.bjsxt.why.Dog";
//2.根据完整路径字符串获取Class对象信息
Class clazz = Class.forName(className);
//3.获取无参数构造方法
Constructor con = clazz.getConstructor();
//4.使用无参数构造方法来创建对象
Object obj = con.newInstance();
System.out.println(obj);
}
}