全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

Java8中lambda表达式的应用及一些泛型相关知识

语法部分就不写了,我们直接抛出一个实际问题,看看java8的这些新特性究竟能给我们带来哪些便利

顺带用到一些泛型编程,一切都是为了简化代码

场景:

一个数据类,用于记录职工信息

public class Employee {
 public String name;
 public int age;
 public char sex;
 public String time;
 public int salary;
}

我们有一列此类数据

List<Employee> data = Arrays.asList(e1,e2,e3......)

现在有需求:将员工Employee按照姓名的首字母(假设均为英文名)进行分组:

那么我们要得到的结果应该是一个Map:char -> List<Employee> 这样的映射关系

public static Map<Character, List<Employee>> groupByFirstChar(
 List<Employee> data){
  Map<Character, List<Employee>> result = new HashMap<>();
  for(Employee e : data){
   Character c = e.name.charAt(0);
   List<Employee> l = result.get(c);
   if(l == null){
    l = new ArrayList<>();
    result.put(c, l);
   }
   l.add(e);
  }
  return result;
}

代码并不复杂,很快就可以完成,老板看你效率这么高,于是说,再按照工资分个组吧,5000以下的,5000~10000的 ...等

也不会太难,将key换一下,稍作逻辑处理即可

public static Map<String, List<Employee>> groupBySalary(List<Employee> data) {
 Map<String, List<Employee>> result = new HashMap<>();
 for (Employee e : data) {
  String key = separate(e.salary);
  List<Employee> l = result.get(key);
  if (l == null) {
   l = new ArrayList<>();
   result.put(key, l);
  }
  l.add(e);
 }
 return result;<br>}
private static String separate(int salary) {
 if (salary <= 5000) {
  return "5000以下";
 }
 if (salary <= 10000) {
   return "5000~10000";
 }
 if (salary <= 20000) {
  return "10000~20000";
 }
 return "20000以上"
}

然后老板又说了,按照员工的入职年份分下组吧。。。

这里就代码就不写了,稍作比较可以发现,无论怎么分组,唯一的变化是key值的选取方式,

第一次将Employee的name的第一字母作为key:

Employee e -> e.name.charAt(0)

第二次将Employee的salary按照方法separat转换为String作为key:

Employee e -> separate(e.salary):String

以此类推

Employee e -> getYear(e.time):String

事实上第一次也可以将获取首字母单独写成一个方法

Employee e -> getFirstChar(e.name):Character

为了看起来更美观,可以讲三个方法的参数都设置成Employee 方法体就不写了 这里只列出参数和返回值

Employee e -> getFirstChar(e) : Character
Employee e -> separate(e) : String
Employee e -> getYear(e) : String

->的左边为参数,:的右边为返回值,->的右边是方法的签名

那么我们自然会想到将变化的部分抽取为参数,其他不变的部分抽取为方法体,那么就可以省去那些重复的代码,显然变化的部分就是上面列出的,将Employee e转化成key的方法,但是我们知道java是不能把方法作为参数进行传递的。不过对于稍有经验的程序猿来说这并不是问题,我们可以使用接口来实现我们的目的,同时又会遇到另一个问题,以上三个方法的返回值是不同的,因此我们要用到泛型:

public static <K> Map<K, List<Employee>> groupByKey(List<Employee> data, GetKey<K> getKey){
 Map<K, List<Employee>> result = new HashMap<>();
 for(Employee e : data) {
  K key = getKey.getKey(e);
  List<Employee> l = result.get(key);
  if (l == null) {
   l = new ArrayList<>();
   result.put(key, l);
  }
  l.add(e);
 }
  return result;
}
interface GetKey<K>{
 K getKey(Employee e);
}

那么上面的第一个需求就可以这样实现

Map<Character, List<Employee>> result = groupByKey(data, new GetKey<Character>() {
   @Override
   public Character getKey(Employee e) {
    e.name.charAt(0);
   }
  });

第二个需求

Map<String, List<Employee>> result = groupByKey(list, new GetKey<String>() {
   @Override
   public String getKey(Employee e) {
    separate(e.salary);
   }
  });

可以发现,我们只需要更改泛型参数和匿名内部类的实现即可,唯一的问题恐怕是这么写实在不太好看,而且很多例行公事的代码,尤其体现在匿名内部类上。

事实上我们只关心这个匿名内部类的参数和返回值,其他部分仅仅是语法要求。

java8恰好为我们提供了很好的方式来避免复杂的例行公事的方式:lambda表达式,以上实现就可以写成

Map<Character, List<Employee>> resultByFirstChar = groupByKey(list, e -> e.name.charAt(0));
Map<String, List<Employee>> resultBySalary = groupByKey(list, e -> separate(e.salary));

lambda表达式恰恰只表现出我们所关心的,参数和返回值,同时由于类型推断,可以省去参数类型,具体语法这里就不介绍了,网上可以查到很多资料

extra:

如果你对泛型有不错的了解的话,方法groupByKey还可以进一步抽象:

public static <K, E> Map<K, List<E>> groupBy(List<? extends E> data, Function<? super E, ? extends K> fun) {
 Map<K, List<E>> result = new HashMap<>();
 for(E e : data) {
  K k = fun.apply(e);<br>  List<E> l = result.get(k);
  if(l == null) {
   l = new ArrayList<>();
   result.put(k, l);
  }
  l.add(e);
 }
 return result;<br>
 }

我们将Employee这个类也抽取了,好处显而易见

Function接口是java8新加入的接口:

@FunctionalInterface
public interface Function<T, R> {
 R apply(T t);
}

输入一个T类型 返回R类型。泛型和函数式编程结合的很不错,虽然java8的新特性被各种吐槽,但是能带来好处总是好的,这给了我们更多的选择。

有时间的话会介绍stream,java8的另一大利器

以上所述是小编给大家介绍的Java8中lambda表达式的应用及一些泛型相关知识,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!


# java8  # lambda表达式  # java  # lambda  # 泛型  # Java Lambda表达式超详细介绍  # Java编程中使用lambda表达式的奇技淫巧  # Java Lambda表达式详解和实例  # java lambda表达式用法总结  # Java8新特性之Lambda表达式浅析  # Java Lambda表达式语法及用法示例  # 就不  # 返回值  # 就可以  # 写了  # 例行公事  # 小编  # 稍作  # 新特性  # 首字母  # 是一个  # 事实上  # 很好  # 还可以  # 第一个  # 在此  # 不太  # 均为  # 以此类推  # 看你  # 表现出 


相关文章: 韩国代理服务器如何选?解析IP设置技巧与跨境访问优化指南  网站制作中优化长尾关键字挖掘的技巧,建一个视频网站需要多少钱?  成都品牌网站制作公司,成都营业执照年报网上怎么办理?  国美网站制作流程,国美电器蒸汽鍋怎么用官方网站?  昆明网站制作哪家好,昆明公租房申请网上登录入口?  如何在IIS中新建站点并配置端口与IP地址?  建站之星代理费用多少?最新价格详情介绍  重庆市网站制作公司,重庆招聘网站哪个好?  微信h5制作网站有哪些,免费微信H5页面制作工具?  如何通过建站之星自助学习解决操作问题?  如何选择靠谱的建站公司加盟品牌?  如何用AWS免费套餐快速搭建高效网站?  如何配置FTP站点权限与安全设置?  电视网站制作tvbox接口,云海电视怎样自定义添加电视源?  家庭服务器如何搭建个人网站?  如何通过WDCP绑定主域名及创建子域名站点?  独立制作一个网站多少钱,建立网站需要花多少钱?  网站规划与制作是什么,电子商务网站系统规划的内容及步骤是什么?  焦点电影公司作品,电影焦点结局是什么?  攀枝花网站建设,攀枝花营业执照网上怎么年审?  学校免费自助建站系统:智能生成+拖拽设计+多端适配  如何用景安虚拟主机手机版绑定域名建站?  视频网站制作教程,怎么样制作优酷网的小视频?  高防服务器租用首荐平台,企业级优惠套餐快速部署  长沙做网站要多少钱,长沙国安网络怎么样?  Swift中循环语句中的转移语句 break 和 continue  网站专业制作公司有哪些,做一个公司网站要多少钱?  长沙企业网站制作哪家好,长沙水业集团官方网站?  上海网站制作开发公司,上海买房比较好的网站有哪些?  网站制作哪家好,cc、.co、.cm哪个域名更适合做网站?  南京网站制作费用,南京远驱官方网站?  专业商城网站制作公司有哪些,pi商城官网是哪个?  高端企业智能建站程序:SEO优化与响应式模板定制开发  如何快速配置高效服务器建站软件?  相册网站制作软件,图片上的网址怎么复制?  如何在阿里云ECS服务器部署织梦CMS网站?  完全自定义免费建站平台:主题模板在线生成一站式服务  定制建站平台哪家好?企业官网搭建与快速建站方案推荐  武汉外贸网站制作公司,现在武汉外贸前景怎么样啊?  大学网站设计制作软件有哪些,如何将网站制作成自己app?  如何通过多用户协作模板快速搭建高效企业网站?  如何快速查询网站的真实建站时间?  广德云建站网站建设方案与建站流程优化指南  北京制作网站的公司排名,北京三快科技有限公司是做什么?北京三快科技?  建站DNS解析失败?如何正确配置域名服务器?  制作网站哪家好,cc、.co、.cm哪个域名更适合做网站?  北京专业网站制作设计师招聘,北京白云观官方网站?  专业的网站制作设计是什么,如何制作一个企业网站,建设网站的基本步骤有哪些?  小型网站建站如何选择虚拟主机?  定制建站策划方案_专业建站与网站建设方案一站式指南 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。