首页 > 解决方案 > Java 列表重复

问题描述

我有这种方法可以打印我的专业列表,在这些条件下,我不能重复使用专业名称。我希望创建另一个不让我拥有超过 3 个类别的条件,即医学、护士、助理。

public void RegistarProfissional(List<Profissional> rProfissional, String nomeP, String categoriaP) {
    int i = 0;
    for (; i < rProfissional.size(); i++) {
        if (rProfissional.get(i).nomeP.equals(nomeP)) {
            System.out.println("Existing Professional, error.");
            break;
        }

        if (i == rProfissional.size()) {
            rProfissional.add(new Profissional(nomeP, categoriaP));
            System.out.println("Professional registered");
        }
    }
}

标签: javaclassobjectmethods

解决方案


(调整你的英语条款)

验证规则

听起来您正在尝试验证现有列表中的数据。您似乎有一对验证规则的标准:

  • 对象列表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 >返回 an。如果我们使用 来检查该Optional对象内部isPresent,我们会返回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 教程

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 ) ;

这将消除您对作为预期值之一的类别的检查验证测试。因为所有可能的值都已经定义,编译器会检查类型和值,所以Professional不会用无效值实例化任何对象。Category任何诸如此类的尝试都将失败:

  • new Professional ( "Alice" , "driver" )➙ 由于类型不匹配导致的编译器错误,第二个参数是期望枚举对象String的对象。Category
  • new Professional ( "Alice" , Category.DRIVER )➙ 由于无效值导致的编译器错误,因为DRIVER枚举类上没有定义这样的枚举对象。

推荐阅读