Java由于没有委托的概念,所以用函数式接口 @FunctionalInterface 与 lambda表达式相结合,实现了类似于C# 中委托,C++中函数指针的功能。
函数指针/委托在Java中被命名为函数式编程。
在Java中,从函数式编程又引申出了Stream流。整个过程分为创建流,中间操作和终结操作。
C# 中的Linq 与此相似,但没有那么多繁琐的步骤,大多都是类似于sql语句中的where,select这种形式,配合lambda表达式实现Java中的Stream流的功能。
C# 可以借助Select 轻松截取集合对象中三个以上的字段,Java却很难做到。
举一个例子,对比Java的Stream流和C# 的Linq
Java:
package com.zg.myssm.entities;
import lombok.*;
import java.util.List;
/**
* @Auther: Zg
* @Date: 2022/10/26 - 10 - 26 - 22:33
* @Description: com.zg.myssm.entities
* @version: 1.0
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode//用于后期的去重使用
public class Author {
//id
private Long id;
//姓名
private String name;
//年龄
private Integer age;
//简介
private String intro;
//作品
private List<Book> books;
}
package com.zg.myssm.entities;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
/**
* @Auther: Zg
* @Date: 2022/10/26 - 10 - 26 - 22:35
* @Description: com.zg.myssm.entities
* @version: 1.0
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode//用于后期的去重使用
public class Book {
//id
private Long id;
//书名
private String name;
//分类
private String category;
//评分
private Integer score;
//简介
private String intro;
}
package com.zg.myssm.test;
import com.zg.myssm.entities.Author;
import com.zg.myssm.entities.Book;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* @Auther: Zg
* @Date: 2022/10/26 - 10 - 26 - 22:42
* @Description: com.zg.myssm.test
* @version: 1.0
*/
public class Authors {
public Authors() {
//数据初始化
Author author = new Author(1L,"蒙多",33,"一个从菜刀中明悟哲理的祖安人",null);
Author author2 = new Author(2L,"亚拉索",15,"狂风也追逐不上他的思考速度",null);
Author author3 = new Author(3L,"易",14,"是这个世界在限制他的思维",null);
Author author4 = new Author(3L,"易",14,"是这个世界在限制他的思维",null);
//书籍列表
List<Book> books1 = new ArrayList<>();
List<Book> books2 = new ArrayList<>();
List<Book> books3 = new ArrayList<>();
books1.add(new Book(1L,"刀的两侧是光明与黑暗","哲学,爱情",88,"用一把刀划分了爱恨"));
books1.add(new Book(2L,"一个人不能死在同一把刀下","个人成长,爱情",99,"讲述如何从失败中明悟真理"));
books2.add(new Book(3L,"那风吹不到的地方","哲学",85,"带你用思维去领略世界的尽头"));
books2.add(new Book(3L,"那风吹不到的地方","哲学",85,"带你用思维去领略世界的尽头"));
books2.add(new Book(4L,"吹或不吹","爱情,个人传记",56,"一个哲学家的恋爱观注定很难把他所在的时代理解"));
books3.add(new Book(5L,"你的剑就是我的剑","爱情",56,"无法想象一个武者能对他的伴侣这么的宽容"));
books3.add(new Book(6L,"风与剑","个人传记",100,"两个哲学家灵魂和肉体的碰撞会激起怎么样的火花呢?"));
books3.add(new Book(6L,"风与剑","个人传记",100,"两个哲学家灵魂和肉体的碰撞会激起怎么样的火花呢?"));
author.setBooks(books1);
author2.setBooks(books2);
author3.setBooks(books3);
author4.setBooks(books3);
this.authors = Arrays.asList(author, author2, author3, author4);
}
public List<Author> getAuthors() {
return authors;
}
public void setAuthors(List<Author> authors) {
this.authors = authors;
}
private List<Author> authors = new ArrayList<>();
}
测试:输出一个小于18岁的作者名字集合,并且不重复:
//终结操作,返回List
@Test
public void Test16(){
Authors authors1 = new Authors();
List<Author> authors = authors1.getAuthors();
List<String> collect = authors.stream().filter(a->a.getAge()<18).map(Author::getName).distinct().collect(Collectors.toList());
collect.forEach(name-> System.out.println(name));
/*
结果:亚拉索 易
*/
System.out.println("====================");
//返回两个字段:
Map<String, Integer> collect1 = authors.stream().filter(a -> a.getAge() < 18).distinct().collect(Collectors.toMap(Author::getName, Author::getAge));
for (Map.Entry<String,Integer> map:collect1.entrySet()
) {
System.out.println(map.getKey());
System.out.println(map.getValue());
}
/*
结果:亚拉索
15
易
14
*/
}
对比C#:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace MyLinqTest
{
public class Author
{
private long id;
//姓名
private string name;
//年龄
private int age;
//简介
private string intro;
//作品
private List<Book> books;
public long Id
{
get { return id; }
set { id = value; }
}
public string Name
{
get { return name; }
set { name = value; }
}
public int Age
{
get { return age; }
set { age = value; }
}
public List<Book> Books
{
get { return books; }
set { books = value; }
}
public Author(long id, string name, int age, string intro, List<Book> books)
{
Id = id;
Name = name;
Age = age;
this.intro = intro;
Books = books;
Id = id;
Name = name;
Age = age;
Books = books;
}
}
}
using System.Runtime.InteropServices;
namespace MyLinqTest
{
public class Book
{
private long id;
public long Id
{
get { return id; }
set { id = value; }
}
//书名
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
//分类
private string category;
public string Category
{
get { return category; }
set { category = value; }
}
//评分
private int score;
public int Score
{
get { return score; }
set { score = value; }
}
//简介
private string intro;
public string Intro
{
get { return intro; }
set { intro = value; }
}
public Book(long id, string name, string category, int score, string intro)
{
Id = id;
Name = name;
Category = category;
Score = score;
Intro = intro;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MyLinqTest
{
public class MyAuthors
{
public MyAuthors()
{
Author author = new Author(1L, "蒙多", 33, "一个从菜刀中明悟哲理的祖安人", null);
Author author2 = new Author(2L, "亚拉索", 15, "狂风也追逐不上他的思考速度", null);
Author author3 = new Author(3L, "易", 14, "是这个世界在限制他的思维", null);
Author author4 = new Author(3L, "易", 14, "是这个世界在限制他的思维", null);
//书籍列表
List<Book> books1 = new List<Book>();
List<Book> books2 = new List<Book>();
List<Book> books3 = new List<Book>();
books1.Add(new Book(1L, "刀的两侧是光明与黑暗", "哲学,爱情", 88, "用一把刀划分了爱恨"));
books1.Add(new Book(2L, "一个人不能死在同一把刀下", "个人成长,爱情", 99, "讲述如何从失败中明悟真理"));
books2.Add(new Book(3L, "那风吹不到的地方", "哲学", 85, "带你用思维去领略世界的尽头"));
books2.Add(new Book(3L, "那风吹不到的地方", "哲学", 85, "带你用思维去领略世界的尽头"));
books2.Add(new Book(4L, "吹或不吹", "爱情,个人传记", 56, "一个哲学家的恋爱观注定很难把他所在的时代理解"));
books3.Add(new Book(5L, "你的剑就是我的剑", "爱情", 56, "无法想象一个武者能对他的伴侣这么的宽容"));
books3.Add(new Book(6L, "风与剑", "个人传记", 100, "两个哲学家灵魂和肉体的碰撞会激起怎么样的火花呢?"));
books3.Add(new Book(6L, "风与剑", "个人传记", 100, "两个哲学家灵魂和肉体的碰撞会激起怎么样的火花呢?"));
author.Books = books1;
author2.Books = books1;
author3.Books = books1;
author4.Books = books1;
this.authors.Add(author);
this.authors.Add(author2);
this.authors.Add(author3);
this.authors.Add(author4);
}
private List<Author> authors = new List<Author>();
public List<Author> Authors
{
get { return authors; }
set { authors = value; }
}
}
}
// See https://aka.ms/new-console-template for more information
using MyLinqTest;
MyAuthors myAuthors = new MyAuthors();
var names = myAuthors.Authors.Where(x => x.Age < 18).Select(x => x.Name).Distinct().ToList();
//多个字段:
var files = myAuthors.Authors.Where(x => x.Age < 18).Select(x => new{name = x.Name, age = x.Age, Id=x.Id }).Distinct().ToList();
foreach (var item in files)
{
Console.WriteLine(item.Id.ToString());
Console.WriteLine(item.age.ToString());
Console.WriteLine(item.name);
}
Console.WriteLine("========================");
/*
结果:2 15 亚拉索
3 14 易
*/
foreach (var item in names)
{
Console.WriteLine(item);
}
/*
结果:亚拉索 易
*/