java借助groovy混合开发项目,提升项目简洁性和代码质量
在正常情况下,我们肯定会认为 Java 虚拟机是用于运行 Java 语言的,其实这么说并不能说是错误,但是也不完全对,这是因为 Java 虚拟机实际上运行的是特定的二进制字节码文件。实际上 Java 虚拟机和某种语言并没有必然的关联,因为不管什么语言只要能够编译成字节码文件,并符合 Java 虚拟机规范,那么 Java 虚拟机就可以加载该字节码文件,并且执行字节码文件中的指令。JVM 支持的语言:
一、Java 虚拟机语言无关性
在正常情况下,我们肯定会认为 Java 虚拟机是用于运行 Java 语言的,其实这么说并不能说是错误,但是也不完全对,这是因为 Java 虚拟机实际上运行的是特定的二进制字节码文件。实际上 Java 虚拟机和某种语言并没有必然的关联,因为不管什么语言只要能够编译成字节码文件,并符合 Java 虚拟机规范,那么 Java 虚拟机就可以加载该字节码文件,并且执行字节码文件中的指令。
JVM 支持的语言: Clojure、JRuby、Groovy、Scala、JavaScript、Kotlin、…
因此,每种语言只要编译成符合 Java 虚拟机规范的字节码文件,就可以使用 Java 虚拟机运行指定语言的代码。
二、Java项目引入Groovy
<dependencies>
<dependency>
<groupId>org.apache.groovy</groupId>
<artifactId>groovy</artifactId>
<version>${groovy.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.gmavenplus</groupId>
<artifactId>gmavenplus-plugin</artifactId>
<version>${gmavenplus-plugin.version}</version>
<executions>
<execution>
<goals>
<goal>addSources</goal>
<goal>addTestSources</goal>
<goal>generateStubs</goal>
<goal>compile</goal>
<goal>generateTestStubs</goal>
<goal>compileTests</goal>
<goal>removeStubs</goal>
<goal>removeTestStubs</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<properties>
<groovy.version>4.0.21</groovy.version>
<gmavenplus-plugin.version>3.0.2</gmavenplus-plugin.version>
</properties>
三、Java与Groovy集合
https://www.groovy-lang.org/differences.html
groovy语法非常简洁
1.多行文本字符串
java8之前,如果要将多行字符串引入代码中,会非常丑陋。
{
"employees":[
{ "firstName":"John", "lastName":"Doe" },
{ "firstName":"Anna", "lastName":"Smith" },
{ "firstName":"Peter", "lastName":"Jones" }
]
}
<employees>
<employee>
<firstName>John</firstName>
<lastName>Doe</lastName>
</employee>
<employee>
<firstName>Anna</firstName>
<lastName>Smith</lastName>
</employee>
<employee>
<firstName>Peter</firstName>
<lastName>Jones</lastName>
</employee>
</employees>
但groovy是很理想的选择,比如Constants.groovy:
package com.baeldung.demo
/**
* 常量
* @author duhongming
* @see
* @since 1.0.0
*/
class Constants {
public static final String JSON_DEMO = """
{
"employees":[
{ "firstName":"John", "lastName":"Doe" },
{ "firstName":"Anna", "lastName":"Smith" },
{ "firstName":"Peter", "lastName":"Jones" }
]
}
"""
public static final String XML_DEMO = """
<employees>
<employee>
<firstName>John</firstName>
<lastName>Doe</lastName>
</employee>
<employee>
<firstName>Anna</firstName>
<lastName>Smith</lastName>
</employee>
<employee>
<firstName>Peter</firstName>
<lastName>Jones</lastName>
</employee>
</employees>
"""
}
测试类:GroovyConstantsTest.java
package com.baeldung.demo;
import org.junit.Test;
/**
* Groovy 常量测试
*
* @author duhongming
* @see
* @since 1.0.0
*/
public class GroovyConstantsTest {
@Test
public void testJsonDemo() {
System.out.println(Constants.JSON_DEMO);
}
@Test
public void testXMLDemo() {
System.out.println(Constants.XML_DEMO);
}
}
2.更为简洁的lambda表达式
使用groovy建立User实体类,看看是不是很简洁
package com.baeldung.demo
/**
* 用户
* @author duhongming
* @see
* @since 1.0.0
*/
class User {
private String name
private Boolean male
private String address
User(String name, Boolean male, String address) {
this.name = name
this.male = male
this.address = address
}
String getName() {
return name
}
void setName(String name) {
this.name = name
}
Boolean getMale() {
return male
}
void setMale(Boolean male) {
this.male = male
}
String getAddress() {
return address
}
void setAddress(String address) {
this.address = address
}
@Override
String toString() {
return "User{" +
"name='" + name + '\'' +
", male=" + male +
", address='" + address + '\'' +
'}';
}
}
GroovyLambdaTest.groovy中单元测试按顺序执行:在类上加上@TestMethodOrder(MethodOrderer.OrderAnnotation.class),在方法上加上@Order(1)
package com.baeldung.demo
import org.junit.jupiter.api.*
/**
* Groovy Lambda测试
* @author duhongming
* @see
* @since 1.0.0
*/
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class GroovyLambdaTest {
static List<User> initData() {
List<User> users = new LinkedList<>()
users.add(new User("小红", false, "长春"))
users.add(new User("小丽", false, "黑龙江"))
users.add(new User("小李", true, "沈阳"))
users.add(new User("小明", true, "长春"))
return users
}
@Test
@Order(1)
@DisplayName("按地址分组")
void testGroupingBy() {
List<User> users = initData()
Map<String, List<User>> userGroupMap = users.groupBy { it.address }
println(userGroupMap)
}
@Test
@Order(2)
@DisplayName("按地址分组并获取第一条")
void testGroupingBy_GetFirst() {
List<User> users = initData()
Map<String, User> userGroupMap = users.groupBy { it.address }
.collectEntries { k, v -> [k, v.get(0)] }
println(userGroupMap)
}
@Test
@Order(3)
@DisplayName("按性别分区")
void testPartitioningBy() {
List<User> users = initData()
Map<Boolean, List<User>> userPartitionMap = users.groupBy { it -> it.male }
println(userPartitionMap)
}
@Test
@Order(4)
@DisplayName("按性别分区并获取第一条")
void testPartitioningBy_GetFirst() {
List<User> users = initData()
Map<Boolean, User> userPartitionMap = users.groupBy { it -> it.male }
.collectEntries { k, v -> [k, v.get(0)] }
println(userPartitionMap)
}
}
JavaLambdaTest.java中单元测试按顺序执行:在类上加上@TestMethodOrder(MethodOrderer.OrderAnnotation.class),在方法上加上@Order(1)
package com.baeldung.demo;
import org.junit.jupiter.api.*;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import static java.util.stream.Collectors.*;
/**
* Java Lambda测试
*
* @author duhongming
* @see
* @since 1.0.0
*/
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class JavaLambdaTest {
public List<User> initData() {
List<User> users = new LinkedList<>();
users.add(new User("小红", false, "长春"));
users.add(new User("小丽", false, "黑龙江"));
users.add(new User("小李", true, "沈阳"));
users.add(new User("小明", true, "长春"));
return users;
}
@Test
@Order(1)
@DisplayName("按地址分组")
public void testGroupingBy() {
List<User> users = initData();
Map<String, List<User>> userMap = users.stream().collect(
groupingBy(User::getAddress, toList())
);
System.out.println(userMap);
}
@Test
@Order(2)
@DisplayName("按地址分组并获取第一条")
public void testGroupingBy_GetFirst() {
List<User> users = initData();
Map<String, User> userMap = users.stream().collect(
groupingBy(
User::getAddress,
collectingAndThen(toList(), list -> list.get(0))
)
);
System.out.println(userMap);
}
@Test
@Order(3)
@DisplayName("按性别分区")
public void testPartitioningBy() {
List<User> users = initData();
Map<Boolean, List<User>> userMap = users.stream().collect(
partitioningBy(User::getMale, toList())
);
System.out.println(userMap);
}
@Test
@Order(4)
@DisplayName("按性别分区并获取第一条")
public void testPartitioningBy_GetFirst() {
List<User> users = initData();
Map<Boolean, User> userMap = users.stream().collect(
partitioningBy(
User::getMale,
collectingAndThen(toList(), list -> list.get(0))
)
);
System.out.println(userMap);
}
}
测试结果如下:
四、参考
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐

所有评论(0)