jdk1.8(java8)新特性
借鉴之:https://blog.csdn.net/qq_28410283/article/details/80601495
Lambda 表达式:
//1.Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性。
//2.Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。
//3.使用 Lambda 表达式可以使代码变的更加简洁紧凑。
/*以下是lambda表达式的重要特征:
可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。
可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。
可选的大括号:如果主体包含了一个语句,就不需要使用大括号。
可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定明表达式返回了一个数值。*/
1. 左侧:lambda表达式的参数列表
2. 右侧:lambda表达式中所需要执行的功能,即lambda函数体
3 .lambda表达式语法格式有三种:
1).无参数,无返回值的用法 :( ) -> System.out.println("hello lambda");
2). 有一个参数,无返回值的用法: (x) -> System.out.println(x); 或者 x -> System.out.println(x); 一个参数,可以省略参数的小括号
3)有两个参数,有返回值的:(x, y) -> x + y
public void test4() {
// 无返回值lambda函数体中用法
//多行的,只需要用大括号{}把语句包含起来就可以了
//只有一条语句的,大括号可以不用写;
Runnable r1 = () -> {
System.out.println("hello lambda1");
System.out.println("hello lambda2");
System.out.println("hello lambda3");
};
r1.run();
// 有返回值lambda函数体中用法
//有返回值和无返回值的,只有一个return的区别
//只有一条语句的,renturn都可以不用写;
BinaryOperator<Integer> binary = (x, y) -> {
int a = x * 2;
int b = y + 2;
return a + b;
};
System.out.println(binary.apply(1, 2));// 6
}
2.方法的引用的语法,主要有三类
1.指向静态方法的方法引用,例如Integer的parseInt方法 ,可以写成 Integer::parseInt
类::静态方法名
2.指向任意类型实例方法的方法引用,例如String的length方法,写成 String::length;
类::实例方法名
3.指向现有对象的实例方法的方法引用
对象::实例方法名
构造器的引用:对于一个现有构造函数,你可以利用它的名称和关键字new来创建它的一个引用ClassName::new;
public static void main(String args[]){
/*************** 方法的引用 ****************/
// 类::静态方法名
Comparator<Integer> cam1 = (x, y) -> x.compareTo(y);
System.out.println(cam1.compare(2, 4));
Comparator<Integer> cam = Integer::compareTo;
System.out.println(cam.compare(3, 2));
// 类::实例方法名
BiPredicate<String, String> bp = (x, y) -> x.equals(y);
System.out.println(bp.test("a", "b"));
BiPredicate<String, String> bp1 = String::equals;
System.out.println(bp1.test("a", "b"));
// 对象::实例方法名
Consumer<String> con1 = x -> System.out.println(x);
con1.accept("abc");
Consumer<String> con = System.out::println;
con.accept("abc");
Emp emp = new Emp("上海", "xiaoMIng", 18);
Supplier<String> supper1 = () -> emp.getAddress();
System.out.println(supper1.get());
Supplier<String> supper = emp::getAddress;
System.out.println(supper.get());
/*************** 构造器的引用 ****************/
// 无参构造函数,创建实例
Supplier<Emp> supper2 = () -> new Emp();
Supplier<Emp> supper3 = Emp::new;
Emp emp1 = supper3.get();
emp1.setAddress("上海");
System.out.println("emp1="+emp1.toString());
// 一个参数
Function<String, Emp> fun = address -> new Emp(address);
Function<String, Emp> fun1 = Emp::new;
System.out.println("beijing="+fun1.apply("beijing"));
// 两个参数
BiFunction<String, Integer, Emp> bFun = (name, age) -> new Emp(name, age);
BiFunction<String, Integer, Emp> bFun1 = Emp::new;
System.out.println("xiaohong="+bFun1.apply("xiaohong", 18));
}
3、java8 函数式接口简介:https://blog.csdn.net/qq_28410283/article/details/80962325
4、Stream接口简介: 流是java API中的新的成员,它可以让你用声明式的方式处理集合,简单点说,可以看成遍历数据的一个高级点的迭代器。
1.Arrays.stream,我们可以通过Arrays的静态方法,传入一个泛型数组,创建一个流。
2.Stream.of,我们可以通过Stream的静态方法,传入一个泛型数组,或者多个参数,创建一个流,这个静态方法,也是调用了Arrays的stream静态方法,如下
System.out.println(Stream.of("one", "two", "three", "four").filter(e -> e.length() > 3));
通过stream里面抽象方法的定义,我们可以看到,这个方法,可以分成两种类型,一种返回类型为接口本身的Stream<T>,另外一种是返回其他对象类型的,返回接口类型的,我们称这些方法为中间操作,返回其他具体类型的,我们称为终端操作;
5、Stream接口之
⑥对对象的操作:peek
⑥统计个数:count
⑦取用前几个:limit
⑧跳过前几个:skip
⑨组合数组:concat
⑩排序:sorted:
sorted() 自然排序
sorted(Comparator com) 定制排序
allMatch 检查是否匹配所有元素
anyMatch 检查是否至少匹配一个元素
noneMatch 检查是否没有匹配所有元素
findFirst 返回第一个元素
findAny 返回当前流中的任意元素
count 返回流中元素的总个数
max 返回流中最大值
min 返回流中最小值
⑪Collect: 将流转换为其他形式。接收一个Collector的实现,用于给stream中元素做汇总的方法。
⑪map映射, 用来归类,结果一般是一组数据,比如可以将list中的学生分数映射到一个新的stream中。
⑪reduce规约, 用来计算值,结果是一个值,比如计算最高分。
④flatMap 接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流。即对流扁平化处理,浅显一点解释就是把几个小的list转换到一个大的list
6.并行流和顺序流:
并行流是把一个内容分成多个数据块,并用不同的线程分别处理每个数据块的流。
通过parallel()与sequential()可以实现并行流和顺序流之间的切换。
7、流的实例用法demo:
package jdk18meths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream; public class TestJava8 {
public static List<Emp> list = new ArrayList<>();
static {
list.add(new Emp("xiaoHong1", 20, 1000.0));
list.add(new Emp("xiaoHong2", 25, 2000.0));
list.add(new Emp("xiaoHong3", 30, 3000.0));
list.add(new Emp("xiaoHong4", 35, 4000.0));
list.add(new Emp("xiaoHong5", 38, 5000.0));
list.add(new Emp("xiaoHong6", 45, 9000.0));
list.add(new Emp("xiaoHong7", 55, 10000.0));
list.add(new Emp("xiaoHong8", 42, 15000.0));
} public static void main(String[] args) {
// 对数组流,先过滤重复,在排序,再控制台输出 1,2,3
List arr =Arrays.asList(3, 1, 2, 1).stream().distinct().sorted().collect(Collectors.toList());
System.out.println(arr); // 对list里的emp对象,取出薪水,并对薪水进行排序,然后输出薪水的内容,map操作,改变了Strenm的泛型对象
List list2= list.stream().map(emp -> emp.getSalary()).sorted().collect(Collectors.toList());
System.out.println(list2); //peek 给年纪大于30岁的人,薪水提升1.5倍,并输出结果
List<Emp> stream = list.stream().filter(emp -> {
return emp.getAge() > 30;
}).peek(emp -> {
emp.setSalary(emp.getSalary() * 1.5);
}).collect(Collectors.toList()); stream.forEach(s -> System.out.println(s.getName()));
System.out.println("stream="+stream.toString()); //peek
List list = Stream.of("one", "two", "three", "four").filter(e -> e.length() > 3).peek(e -> e.equals("four"))
.map(String::toUpperCase).collect(Collectors.toList());
System.out.println(list); //把2个数组组合在一起
Stream<String> stream1 = Stream.of("陈奕迅", "陈伟霆", "陈七", "钟汉良");
String[] arr2 = {"1","2","3"};
Stream<String> stream2 = Stream.of(arr2);
Stream<String> concatStream = Stream.concat(stream1, stream2);
concatStream.forEach(str-> System.out.println(str));
System.out.println(concatStream);
//另一种方法:flatMap
//接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流。即对流扁平化处理,浅显一点解释就是把几个小的list转换到一个大的list
} public static class Emp {
@Override
public String toString() {
return "Emp [name=" + name + ", age=" + age + ", salary=" + salary + "]";
}
private String name;
private Integer age;
private Double salary;
public Emp(String name, Integer age, Double salary) {
super();
this.name = name;
this.age = age;
this.salary = salary;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Double getSalary() {
return salary;
}
public void setSalary(Double salary) {
this.salary = salary;
}
}
}
判断list非空:
CollectionUtils.isNotEmpty(accountList)
合并;list:
List<MemberPreference> preferenceTotal = Stream.of(memberPreferences, memberPreferences2).flatMap(Collection::stream).distinct().collect(Collectors.toList()); list 去null :
List<String> result = listStrings.stream().filter(x -> x!=null).collect(Collectors.toList());
List<String> result2 = listStrings.stream().filter(Objects::nonNull).collect(Collectors.toList());
//list对象赋值给另一个list对象
List a = list.stream().map(it ->{
MemberCard mcard = new MemberCard();
BeanUtils.copyProperties(it, mcard);
return mcard;
}).collect(Collectors.toList());
System.out.println(a);
}
package jdk180reduce; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.OptionalDouble;
import java.util.stream.Collectors;
import java.util.stream.IntStream; public class StreamTest01 {
public static void main(String[] args) {
List<Student> stuList = new ArrayList<>(10);
stuList.add(new Student("刘一", 85));
stuList.add(new Student("陈二", 90));
stuList.add(new Student("张三", 98));
stuList.add(new Student("李四", 88));
stuList.add(new Student("王五", 83));
stuList.add(new Student("赵六", 95));
stuList.add(new Student("孙七", 87));
stuList.add(new Student("周八", 84));
stuList.add(new Student("吴九", 100)); //需求:列出90分以上的学生姓名,并按照分数降序排序
List<Student> result1 = new ArrayList<>(10);
result1 = stuList.stream().filter(s -> s.getScore()>=90)
.sorted(Comparator.comparing(Student :: getScore).reversed())
.collect(Collectors.toList());
System.out.println(result1); //list.stream().sorted(Comparator.reverseOrder()); //计算学生总分 2个参数:初始值(即0+a[1]+a[2]+...)开始一直相加, //reduce用来计算值,结果是一个值,比如计算最高分。
Integer totalScore1 = stuList.stream().map(Student::getScore).reduce(0,(a,b) -> a + b);
System.out.println("totalScore1="+totalScore1); //计算学生总分,一个参数忽略a[0] 返回Optional类型的数据,改类型是java8中新增的,主要用来避免空指针异常
Optional<Integer> totalScore2 = stuList.stream().map(Student::getScore).reduce((a,b) -> a + b);
System.out.println("totalScore2="+totalScore2.get()); //计算最高分和最低分(总分Integer ::sum)
Optional<Integer> max = stuList.stream().map(Student::getScore).reduce(Integer::max);
Optional<Integer> min = stuList.stream().map(Student::getScore).reduce(Integer::min);
System.out.println("max="+max.get());
System.out.println("min="+min.get()); //stream没有sum求和的方法,但是有别的。
//将stream转换为IntStream求和
int totalScoreInt = stuList.stream().mapToInt(Student::getScore).sum();
System.out.println("Int_totalScore="+totalScoreInt);
//计算平均分
OptionalDouble avgScore = stuList.stream().mapToInt(Student::getScore).average();
System.out.println("avgScore="+avgScore.getAsDouble());
//生成1~100之间的数字
IntStream num = IntStream.rangeClosed(1, 100);
System.out.println("num="+num.toString()); List<String> lists = new ArrayList<>();
lists.add("li");
lists.add("zhang");
lists.add("chen");
//Match匹配
boolean a = lists.stream().anyMatch(s -> s.startsWith("li"));
System.out.println("li = " + a);
//判断是否全为li开头的
System.out.println(lists.stream().allMatch(s -> s.startsWith("li")));
//判断一个字符在该集合中不存在
System.out.println(lists.stream().noneMatch(s -> s.startsWith("li2"))); //filter: filter方法的作用,是对这个boolean做判断,返回true判断之后的对象
//返回字符串为a的值
String[] dd = { "a", "b", "c" };
java.util.stream.Stream<String> stream = Arrays.stream(dd);
stream.filter(str -> str.equals("c")).forEach(System.out::println);
} }
package jdk180reduce;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.IntSummaryStatistics;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.OptionalDouble;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors; public class TestJava8 {
public static List<Emp> list = new ArrayList<>();
static {
list.add(new Emp("上海", "小名", 17));
list.add(new Emp("北京", "小红", 18));
list.add(new Emp("深圳", "小蓝", 19));
list.add(new Emp("广州", "小灰", 20));
list.add(new Emp("杭州", "小黄", 21));
list.add(new Emp("贵阳", "小白", 22));
} public static void main(String[] args) {
//groupingBy返回 userId:List<User>
Map<Integer, List<User>> map = userList.stream().collect(Collectors.groupingBy(User::getUserId));
System.out.println("map=" + map);
//groupingBy返回 userId:每组个数
Map<Integer, Long> mapCount = userList.stream().collect(Collectors.groupingBy(User::getGender,Collectors.counting()));
System.out.println("mapCount个数=" + mapCount);
// 转list
List<String> names = list.stream().map(e -> e.getName()).collect(Collectors.toList());
System.out.println("names="+names); // 转set
Set<String> address = list.stream().map(emp -> emp.getName()).collect(Collectors.toSet());
System.out.println("address="+address); // 转map,需要指定key和value,Function.identity()表示当前的Emp对象本身
Map<String, Emp> map = list.stream().collect(Collectors.toMap(Emp::getName, Function.identity()));
System.out.println("转map="+map); // 计算元素中的个数
Long count = list.stream().collect(Collectors.counting()); // 数据求和 summingInt summingLong,summingDouble
Integer sumAges = list.stream().collect(Collectors.summingInt(Emp::getAge));
int totalScoreInt = list.stream().mapToInt(Emp::getAge).sum();
System.out.println("求和="+sumAges);
System.out.println("求和2="+totalScoreInt); // 平均值 averagingInt,averagingDouble,averagingLong
Double aveAges = list.stream().collect(Collectors.averagingInt(Emp::getAge));
OptionalDouble avgScore = list.stream().mapToInt(Emp::getAge).average();
System.out.println("平均值 1="+aveAges);
System.out.println("平均值 2="+avgScore); // 综合处理的,求最大值,最小值,平均值,求和操作
// summarizingInt,summarizingLong,summarizingDouble
IntSummaryStatistics intSummary = list.stream().collect(Collectors.summarizingInt(Emp::getAge));
System.out.println(intSummary.getAverage());// 19.5
System.out.println(intSummary.getMax());// 22
System.out.println(intSummary.getMin());// 17
System.out.println(intSummary.getSum());// 117 // 连接字符串,当然也可以使用重载的方法,加上一些前缀,后缀和中间分隔符
String strEmp = list.stream().map(emp -> emp.getName()).collect(Collectors.joining());
String strEmp1 = list.stream().map(emp -> emp.getName()).collect(Collectors.joining("-中间的分隔符-"));
String strEmp2 = list.stream().map(emp -> emp.getName()).collect(Collectors.joining("-中间的分隔符-", "前缀*", "&后缀"));
// 小名小红小蓝小灰小黄小白
// 小名-中间的分隔符-小红-中间的分隔符-小蓝-中间的分隔符-小灰-中间的分隔符-小黄-中间的分隔符-小白
// 前缀*小名-中间的分隔符-小红-中间的分隔符-小蓝-中间的分隔符-小灰-中间的分隔符-小黄-中间的分隔符-小白&后缀
System.out.println(strEmp);
System.out.println(strEmp1);
System.out.println(strEmp2); // maxBy 按照比较器中的比较结果刷选 最大值
Optional<Integer> maxAge = list.stream().map(emp -> emp.getAge()).collect(Collectors.maxBy(Comparator.comparing(Function.identity())));
// 最小值
Optional<Integer> minAge = list.stream().map(emp -> emp.getAge()).collect(Collectors.minBy(Comparator.comparing(Function.identity())));
System.out.println("max:" + maxAge);
System.out.println("min:" + minAge); // 归约操作
list.stream().map(emp -> emp.getAge()).collect(Collectors.reducing((x, y) -> x + y));
list.stream().map(emp -> emp.getAge()).collect(Collectors.reducing(0, (x, y) -> x + y));
// 分操作 groupingBy 根据地址,把原list进行分组
Map<String, List<Emp>> mapGroup = list.stream().collect(Collectors.groupingBy(Emp::getAddress));
//根据accountNum分组,再把QtyEarn相加,得到一个新的map。
Map<String, Integer> waitingPoints = customerLoyOrderTxns.stream().
collect(Collectors.groupingBy(CustomerLoyOrderTxnPO::getAccountNum,Collectors.summingInt(x -> x.getQtyEarn())));
System.out.println("mapGroup:" + mapGroup);
// partitioningBy 分区操作 需要根据类型指定判断分区
Map<Boolean, List<Integer>> partitioningMap = list.stream().map(emp -> emp.getAge()).collect(Collectors.partitioningBy(emp -> emp > 20));
System.out.println("partitioningMap:" + partitioningMap);
}
static class Emp {
private String address;
private String name;
private Integer age;
public Emp() {
}
public Emp(String address) {
this.address = address;
}
public Emp(String name, Integer age) {
this.name = name;
this.age = age;
}
public Emp(String address, String name, Integer age) {
super();
this.address = address;
this.name = name;
this.age = age;
}
//get set 方法
}
//Collectors.groupingBy()的写法:
public static void main(String[] args) {
//3 apple, 2 banana, others 1
List<Item> items = Arrays.asList(
new Item("apple", 10, new BigDecimal("9.99")),
new Item("banana", 20, new BigDecimal("19.99")),
new Item("orang", 10, new BigDecimal("29.99")),
new Item("watermelon", 10, new BigDecimal("29.99")),
new Item("papaya", 20, new BigDecimal("9.99")),
new Item("apple", 10, new BigDecimal("9.99")),
new Item("banana", 10, new BigDecimal("19.99")),
new Item("apple", 20, new BigDecimal("9.99"))
);
//Group by + Count
Map<String, Long> counting = items.stream().collect(Collectors.groupingBy(Item::getName, Collectors.counting()));
System.out.println(counting); //求和//Group by + Sum qty
Map<String, Integer> sum = items.stream().collect(Collectors.groupingBy(Item::getName, Collectors.summingInt(Item::getQty)));
System.out.println(sum); Map<String, List<Item>> env = items.stream().collect(Collectors.groupingBy(Item::getName));
System.out.println(env);
}

jdk1.8(java8)新特性的更多相关文章
- java8新特性全面解析
在Java Code Geeks上有大量的关于Java 8 的教程了,像玩转Java 8--lambda与并发,Java 8 Date Time API 教程: LocalDateTime和在Java ...
- JAVA8新特性——Lamda表达式
JAVA9都要出来了,JAVA8新特性都没搞清楚,是不是有点掉队哦~ Lamda表达式,读作λ表达式,它实质属于函数式编程的概念,要理解函数式编程的产生目的,就要先理解匿名内部类. 先来看看传统的匿名 ...
- java8新特性——Lambda表达式
上文中简单介绍了一下java8得一些新特性,与优点,也是为本次学习java8新特性制定一个学习的方向,后面几篇会根据上文中得新特性一一展开学习.本文就从java8新特性中比较重要的Lambda表达式开 ...
- JAVA8新特性——接口定义增强
JAVA9都要出来了,JAVA8新特性都没搞清楚,是不是有点掉队哦~ 接口定义增强 在JDK1.8以前,接口是定义的: 接口(英文:Interface),在JAVA编程语言中是一个抽象类型,是抽象方法 ...
- java8 新特性精心整理
前言 越来越多的项目已经使用 Java 8 了,毫无疑问,Java 8 是Java自Java 5(发布于2004年)之后的最重要的版本.这个版本包含语言.编译器.库.工具和 JVM 等方面的十多个新特 ...
- java8 新特性精心整理(全)
前言 越来越多的项目已经使用 Java 8 了,毫无疑问,Java 8 是Java自Java 5(发布于2004年)之后的最重要的版本.这个版本包含语言.编译器.库.工具和 JVM 等方面的十多个新特 ...
- java8 新特性学习笔记
Java8新特性 学习笔记 1主要内容 Lambda 表达式 函数式接口 方法引用与构造器引用 Stream API 接口中的默认方法与静态方法 新时间日期 API 其他新特性 2 简洁 速度更快 修 ...
- 【Java8新特性】重复注解与类型注解,你真的学会了吗?
写在前面 在Java8之前,在某个类或者方法,字段或者参数上标注注解时,同一个注解只能标注一次.但是在Java8中,新增了重复注解和类型注解,也就是说,从Java8开始,支持在某个类或者方法,字段或者 ...
- javaSE高级篇5 — java8新特性详解———更新完毕
java8新特性 在前面已经见过一些东西了,但是:挖得有坑儿 1.lambda表达式 lambda表达式是jdk1.8引入的全新语法特性 它支持的是:只有单个抽象方法的函数式接口.什么意思? 就是说: ...
- Java8新特性—四大内置函数式接口
Java8新特性--四大内置函数式接口 预备知识 背景 Lambda 的设计者们为了让现有的功能与 Lambda 表达式良好兼容,考虑了很多方法,于是产生了函数接口这个概念. 什么是函数式接口? 函数 ...
随机推荐
- 【Android】做一个简单的每日打卡app-day01【还没做好】
任务: 第一阶段目标: 1.用户注册:用户注册信息包括用户ID(学号).用户名(姓名),手机号码,用户单位(班级),用户班级四项基本信息,用户第一次注册后,用户姓名不用每次输入 . 2.每日总结打卡: ...
- JavaWeb项目练习(学生选课管理系统)三【登录功能】
需求: 首页为用户登录页面,管理员,教师,学生三种角色用户登录后,进入相应的功能页. 在index.jsp文件里跳转到login.jsp页面,为了更好地书写 <%@ page contentTy ...
- 在WPF应用中使用GongSolutions.WPF.DragDrop实现列表集合控件的拖动处理
WPF应用中,控件本身也可以通过实现事件代码实现拖动的处理,不过如果我们使用GongSolutions.WPF.DragDrop来处理,事情会变得更加简单轻松,它支持很多控件的拖动处理,如ListBo ...
- vertx的学习总结7之用kotlin 与vertx搞一个简单的http
这里我就简单的聊几句,如何用vertx web来搞一个web项目的 1.首先先引入几个依赖,这里我就用maven了,这个是kotlin+vertx web <?xml version=" ...
- [CF1849F] XOR Partition
XOR Partition 题目描述 For a set of integers $ S $ , let's define its cost as the minimum value of $ x \ ...
- VUE路由基本操作
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- 3D网站LOGO动画
相关技术和实现分析 3D模型 帧动画 threejs 推荐用blender创建3d模型,k帧实现从上到下翻转的帧动画 threejs 中执行帧动画,并关联滚动条 threejs 模型材质 Blende ...
- 聊聊流式数据湖Paimon(五)
从Demo入手,了解Paimon/Flink项目搭建的全过程.记录下采坑之旅. 创建Flink项目 在IDEA中创建Flink项目,由于没有Flink的archetype,因此需要手动创建一下. 参考 ...
- idea2020.1.3汉化包报错问题
已解决:idea2020.1.3汉化包报错问题 问题描述:插件市场提供的版本不对.不兼容,所以需要手动下载安装 这里附上文件 https://wwsi.lanzouq.com/b03czdtwf 密码 ...
- UnionFind 并查集
简介 UnionFind 主要用于解决图论中的动态联通性的问题(对于输入的一系列元素集合,判断其中的元素是否是相连通的). 以下图为例: 集合[1, 2, 3, 4] 和 [5, 6]中的每个元素之间 ...