(调整你的英语术语)
验证规则
听起来您正在尝试验证现有列表中的数据。您的验证规则似乎有一对标准:
-
Professional 对象列表不能有重复的人名。
- 每个
Professional 对象都必须带有一个profession 属性,该属性具有以下三个值之一:护士、医师、助理。
我们将忽略现实世界中两个人可以同名的实际问题。
我们的Professional 班级。
package work.basil.example;
public class Professional
{
public String name, category;
public Professional ( String name , String category )
{
this.name = name;
this.category = category;
}
}
虚拟数据。
List < Professional > pros = List.of(
new Professional( "Alice" , "physician" ) ,
new Professional( "Bob" , "nurse" ) ,
new Professional( "Carol" , "assistant" ) ,
new Professional( "David" , "physician" )
);
测试我们的两条规则。
String targetName = "Bob";
String targetCategory = "driver";
// Test for category.
List < String > categories = List.of( "nurse" , "physician" , "assistant" );
if ( ! categories.contains( "targetCategory" ) )
{
System.out.println( "Validation violation. The category: " + targetCategory + " not found in category list: " + categories );
return;
}
// Test for duplicate name.
for ( Professional pro : pros )
{
boolean foundDuplicateName = pro.name.equalsIgnoreCase( targetName );
if ( foundDuplicateName )
{
System.out.println( "Validation violation. Duplicate name found: " + targetName );
break;
}
}
流
我们可以使用 Java Streams 和 lambda 语法来检查重复项。
制作一个列表流。
Stream< Professional > prosStream = pros.stream() ;
对于流生成的每个Professional 对象,应用谓词测试以查看该对象中的名称是否与我们的目标名称匹配。找到第一个匹配项后,将返回 Optional< Professional >。如果我们用isPresent检查那个Optional对象,我们会得到true。如果没有找到匹配项,将返回一个空的Optional,isPresent 返回false。
Stream < Professional > prosStream = pros.stream();
boolean foundDuplicateName =
prosStream
.filter( ( Professional pro ) -> pro.name.equalsIgnoreCase( targetName ) )
.findFirst()
.isPresent()
;
if ( foundDuplicateName )
{
System.out.println( "Validation violation. Duplicate name found: " + targetName );
return;
}
我们可以简化流工作。方法Stream::anyMatch也有同样的效果。
Stream < Professional > prosStream = pros.stream();
boolean foundDuplicateName =
prosStream
.anyMatch( ( Professional pro ) -> pro.name.equalsIgnoreCase( targetName ) )
;
if ( foundDuplicateName )
{
System.out.println( "Validation violation. Duplicate name found: " + targetName );
return;
}
我们可以将其简化为单行。
if ( pros.stream().anyMatch( ( Professional pro ) -> pro.name.equalsIgnoreCase( targetName ) ) )
{
System.out.println( "Validation violation. Duplicate name found: " + targetName );
return;
}
枚举
您应该使用枚举,而不是仅仅为您的category 值使用字符串。 Java 有一个简单而强大且灵活的枚举工具,比大多数语言都要好得多。见Oracle Tutorial。
package work.basil.example;
public enum Category
{
NURSE , PHYSICIAN , ASSISTANT ;
}
将我们的 Professional 类更改为使用枚举而不是单纯的字符串。
package work.basil.example;
public class Professional
{
public String name;
Category category;
public Professional ( String name , Category category )
{
this.name = name;
this.category = category;
}
}
像这样实例化:
Professional pro = new Professional( "Alice" , Category.PHYSICIAN ) ;
这将消除您对作为预期值之一的类别的检查验证测试。不会使用 Category 的无效值来实例化 Professional 对象,因为所有可能的值都已定义,并且编译器会检查类型和值。任何诸如此类的尝试都会失败:
-
new Professional ( "Alice" , "driver" ) ➙ 由于类型不匹配导致的编译器错误,第二个参数是 String 对象,其中应该是 Category 枚举对象。
-
new Professional ( "Alice" , Category.DRIVER ) ➙ 无效值导致编译器错误,因为枚举类上没有定义这样的枚举对象 DRIVER。