首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么我的TreeSet在我试图添加字符串时给我一个空指针异常?

为什么我的TreeSet在我试图添加字符串时给我一个空指针异常?
EN

Stack Overflow用户
提问于 2022-03-21 00:50:49
回答 1查看 183关注 0票数 -1

我正在为一个Java类做一个项目,我似乎无法通过这个NullPointerException。该项目是一个命令行LinkedIn程序.我正在实现的一个方面是向用户配置文件添加技能集的能力。

我有一个LinkedInUser类,其中我定义了一个TreeSet,它以用户输入的字符串的形式保存这些技能集。我使用TreeSet,因为分配需要对它们进行排序。

我在这里定义了TreeSet类中的LinkedInUser:

代码语言:javascript
复制
private Set<String> skillsets = new TreeSet<>();

用户采取的操作在AddSkillsetAction类中定义:

代码语言:javascript
复制
String skillset;
    
System.out.println("Enter a skillset to add to your list:");
skillset = scanner.nextLine();

loggedInUser.addSkillset(skillset);
System.out.println(skillset + " has been added to your skillsets.");

并将它们输入的字符串传递给LinkedInUser类中的LinkedInUser函数:

代码语言:javascript
复制
public void addSkillset(String skillset) {
    skillsets.add(skillset);
}

我总是在网上得到一个NullPointerException:

代码语言:javascript
复制
skillsets.add(skillset);

我做错了什么?我已经测试过这条线的每一层了。我甚至用以下代码测试了TreeSet函数中的addSkillset:

代码语言:javascript
复制
if(skillsets == null) {
   System.out.println("The TreeSet is null.")
}

它告诉我TreeSet是空的。我想用以下方法实例化该集:

代码语言:javascript
复制
private Set<String> skillsets = new TreeSet<>();

实际上将创建一个空的TreeSet,而不是指向空位置。为什么我的集合“技能集”仍然指向null?我在这里做错什么了?

编辑:下面是完整的类:

代码语言:javascript
复制
package edu.institution.asn2;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

public class LinkedInUser extends UserAccount implements Comparable<LinkedInUser>, Serializable {

    private static final long serialVersionUID = 75648957489235739L;
    private String type;
    private List<LinkedInUser> connections = new ArrayList<>(); 
    private Set<String> skillsets = new TreeSet<>();
    
    public LinkedInUser(String username, String password) {
        super(username, password);
    }
    
    @Override
    public void setType(String type) {
        this.type = type;
    }
    
    public String getType() {
        return this.type;
    }
    
    // Add a connection to user's list
    public void addConnection(LinkedInUser user) throws LinkedInException {
        int index = connections.indexOf(user);
        if (index >= 0) {
            throw new LinkedInException("You are already connected with this user.");
        }
        else {
            connections.add(user);
        }
    }
    
    // Remove a connection from the user's connection list
    public void removeConnection(LinkedInUser user) throws LinkedInException {
        int index = connections.indexOf(user);
        if (index < 0) {
            throw new LinkedInException("You are NOT connected to this user.");
        }
        else {
            connections.remove(index);
        }
    }
    
    // Return a copy of the ArrayList of connections
    public List<LinkedInUser> getConnections() {
        ArrayList<LinkedInUser> copy = new ArrayList<>(connections);
        return copy;
    }
    
    // Return the number of connections
    public int getNumberOfConnections() {
        return connections.size();
    }
    
    // Return the skillsets
    public Set<String> getSkillsets(){
        return skillsets;
    }
    
    // Add a skillset
    public void addSkillset(String skillset) {
        skillsets.add(skillset);
    }
    
    // Remove a skillset
    public void removeSkillset (String skillset) {
        if(skillsets.contains(skillset)){
            skillsets.remove(skillset);
        } else {
            System.out.println(skillset + " is not in your skills list.");
        }
    }
    
    // Override the compareTo function
    @Override
    public int compareTo(LinkedInUser user) {
        int i = this.getUsername().compareToIgnoreCase(user.getUsername());
        return i;
    }

}

并增加了一套技能:

代码语言:javascript
复制
package edu.institution.actions.asn7;

import java.util.Scanner;

import edu.institution.ApplicationHelper;
import edu.institution.UserRepository;
import edu.institution.actions.MenuAction;
import edu.institution.asn2.LinkedInUser;

public class AddSkillsetAction implements MenuAction {

    @Override
    public boolean process(Scanner scanner, UserRepository userRepository, LinkedInUser loggedInUser) {
        String skillset;
        
        System.out.println("Enter a skillset to add to your list:");
        skillset = scanner.nextLine();
        
        loggedInUser.addSkillset(skillset);
        System.out.println(skillset + " has been added to your skillsets.");
        
        ApplicationHelper.incrementSkillsetCount(skillset);
        
        return true;
    }
}

在运行并尝试添加一个技能集之后,我得到了以下错误:

代码语言:javascript
复制
Exception in thread "main" java.lang.NullPointerException
    at edu.institution.asn2.LinkedInUser.addSkillset(LinkedInUser.java:69)
    at edu.institution.actions.asn7.AddSkillsetAction.process(AddSkillsetAction.java:19)
    at edu.institution.ApplicationController.process(ApplicationController.java:61)
    at edu.institution.LinkedInCLI.main(LinkedInCLI.java:39)

LinkedInUser.java:69是:

代码语言:javascript
复制
    skillsets.add(skillset);
EN

回答 1

Stack Overflow用户

发布于 2022-03-21 01:09:04

顺便说一句,…你的名字让人困惑。String skillset;应该是String skill,而不是.addSkillset,因为您是在添加个人技能,而不是添加集合。

澄清您的命名可能会澄清您的代码。注意下面代码中使用的单数skill和复数skills命名。

您没有提供足够的细节来诊断问题。但是我可以根据你的描述向你展示一些示例代码。

您的问题可能与您没有正确实例化TreeSet有关。请注意,在此代码中,您至少可以选择两个位置来实例化:

  • skills的声明行上。
  • 在构造函数中。(代码当前注释掉。)

LinkedInUser类。

代码语言:javascript
复制
package work.basil.linkedin;

import java.util.NavigableSet;
import java.util.Set;
import java.util.TreeSet;

public class LinkedInUser
{
    private String name;
    private NavigableSet < String > skills = new TreeSet <>();

    // Constructor
    public LinkedInUser ( final String name )
    {
        this.name = name;
//        this.skills = new TreeSet <>() ;
    }

    // Modifiers

    public void setName ( String name ) { this.name = name; }

    public void addSkill ( String skill ) { this.skills.add( skill ); }

    // Getters

    public String getName ( ) { return name; }

    public Set < String > getSkills ( ) { return Set.copyOf( this.skills ); }  // Return a unmodifiable copy of the set. (defensive programming)
}

对于防御程序设计,我们返回一个集合的副本。Set.copyOf返回的这个不可修改的副本没有订单。在某些实现中,每个迭代器的顺序甚至可能任意更改。如果要返回排序的NavigableSet,请执行以下操作:

  • 将方法的返回类型更改为NavigableSet
  • 更改代码,将实例的集合传递给另一组的构造函数。
代码语言:javascript
复制
public NavigableSet < String > getSkills ( ) { return new TreeSet <>(this.skills ); }

使用。

代码语言:javascript
复制
LinkedInUser alice = new LinkedInUser( "Alice" );
LinkedInUser bob = new LinkedInUser( "Bob" );

alice.addSkill( "Yodeling" );
alice.addSkill( "Tap Dancing" );
bob.addSkill( "Juggling" );

System.out.println( alice.getName() + " does " + alice.getSkills() );
System.out.println( bob.getName() + " does " + bob.getSkills() );

System.out.println( List.of( alice , bob ) );

跑的时候。

代码语言:javascript
复制
Alice does [Yodeling, Tap Dancing]
Bob does [Juggling]
[LinkedInUser{name='Alice', skills=[Tap Dancing, Yodeling]}, LinkedInUser{name='Bob', skills=[Juggling]}]

你说过:

我想用以下方法实例化该集: private Set<String> skillsets = new TreeSet<>();

是的,这将实例化一个TreeSet对象,并将对该集合的引用存储在一个名为skillsets的变量中。我想你把代码放错地方了。同样,看看我在前面这个答案中建议的两个位置:在声明行中,或者在构造函数中。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71551789

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档