【问题标题】:How to use setter to set a value to a attribute which is a private array?如何使用 setter 为私有数组的属性设置值?
【发布时间】:2017-09-01 12:48:38
【问题描述】:

我已经制作了一个卷号数组,因此如何使用 setter 将用户输入提供给作为卷号的私有属性。 我做了一个学生类的对象,它是一个学生并尝试了这个students.for(int i=0;i<n;i++) {(setRollno[i](sc.next()))}; 但它没有用。

class Students{
    private  String[] rollno = new String[1000];
    private  int[] intel = new int[1000];
    private  int[] type = new int[1000];
    private  String[] name = new String[1000];

    public void setRollno(String[] rollno) {
        this.rollno = rollno;
    }

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

    public void setIntel(int[] intel) {
        this.intel = intel;
    }

    public void setType(int[] type) {
        this.type = type;
    }


    public String[] getRollno() {
        return rollno;
    }

    public String[] getName() {
        return name;
    }

    public int[] getIntel() {
        return intel;
    }

    public int[] getType() {
        return type;
    }
 }

【问题讨论】:

  • 你的意思是students.setType(students.(
  • 1.您不能在像 setRollno[i] 2 这样的方法调用上使用数组 [i]。您必须将该方法传递给字符串数组,而不是字符串
  • 我想使用 setter 向 rollno 数组提供用户输入。
  • 所以你只想修改你的rollno的一个值?如果不是,请告诉我,我会更新我的答案。
  • 你可能想用这个来代替:students.getRollno()[i] = sc.next();.

标签: java oop private setter getter


【解决方案1】:

可能我误解了您的数据结构的目的,但听起来您正试图在一个地方创建学生数据的集合。如果是这种情况,那么我强烈建议创建一个 Student 类,它一次只代表一个学生,然后使用 Java 集合框架中的一种或多种标准类型来轻松找到特定的学生。

例如,您的Student 班级可能只包含包含一个学生的卷号、姓名和其他数据的字段。然后,假设您希望通过卷号快速找到学生,您可以创建一个Map&lt;String, Student&gt;,其中映射键是卷号,对应的映射值是具有该卷号的学生。只需在构造后将一个新的Student 对象放入Map 中。如果您需要按姓名查找学生,那么您可以创建一个Map&lt;String, Collection&lt;Student&gt;&gt;(因为可能有多个学生具有相同的姓名)并在构建后将每个新的Student 对象放入此名称映射中。

这可能会导致代码比诸如您的问题中显示的多合一自定义集合类更容易阅读、维护和使用。

作为一个粗略的代码示例:

String rollNumber = getNewRollNumber(); // wherever roll numbers come from
String name = getStudentName(); // wherever the name comes from
Student newStudent = new Student(rollNumber, name, etc);
studentsByRollNumber.put(rollNumber, newStudent);
studentsByName.computeIfAbsent(name,
        n -> new ArrayList<>(1)).add(student);

Student studentWithParticularRollNumber =
        studentsByRollNumber.get("123456");
Collection<Student> studentsWithParticularName =
        studentsByName.get("Perry, Fred");

Map#computeIfAbsent 方法将在给定的学生姓名下创建一个新的ArrayList,前提是该名称下不存在任何条目,或者如果该名称已经存在于地图中,则将获取现有列表,然后将新学生进入列表。

在对computeIfAbsent 的调用中,lambda 表达式t -&gt; new ArrayList&lt;&gt;(1) 仅表示“获取映射键的值,无论它是什么,都只是创建一个大小为1 的新ArrayList”。它只是保证如果在给定的学生姓名下还没有存储Collection&lt;Student&gt;,那么将创建一个新的ArrayList&lt;Student&gt; 并将其存储在那里。

【讨论】:

  • 这是非常正确的,我应该在我的回答中这么说。我专注于解决问题,并没有意识到潜在的问题。虽然 TO 对 JAVA 来说似乎相当新(他实际上是这么说的),并且可能还没有掌握集合的用法。
  • 编辑后:我相信对于不习惯集合的人来说,您对 lambda 的使用有点难以理解(但这只是我的观点)
  • Lambda 表达式乍一看很时髦,我同意。答案已被编辑,以添加有关该特定 lambda 表达式含义的简短说明。完全一样的事情可以不使用 lambda 来完成,但替代方案占用了 4 行并且更丑陋。
【解决方案2】:

setRollno[i](sc.next()); 不是好的语法。您的函数setRollno 将字符串数组作为参数,并更改您拥有的所有数组。如果这是你想要的,你必须传递一个Strings 的数组作为参数:

如果你想在你的rollno 中设置一个特定的String,你必须创建另一个函数:

setRollNoAtIndex(int i, String s) {
    this.rollno[i] = s;
}

如果你需要在循环中调用它,你可以简单地这样做:

for(int i=0; i < n ;i++) {
    students.setRollNoAtIndex(i, sc.next());
}

根据Berger的评论:

您尝试使用的语法可能是:

for(int i=0; i < n ;i++) {
    students.getRollno()[i] = sc.next();
}

String[] list = new String [1000];
for(int i=0; i < n ;i++) {
    list[i] = sc.next();
}
students.setRollno(list);

【讨论】:

  • 我必须使用循环输入一系列字符串。
  • @ÄnsuMan 给你。但是当谈到 java 中的数组时,您似乎很迷茫,也许您应该先阅读一些教程。
  • 我是 JAVA 的初学者,不知道如何使用 setter 来给用户输入。
【解决方案3】:

我认为这个类的设计是不正确的,因为我们可以直接访问内部数组。此外,在这种情况下,您不必在创建新实例时初始化所有这些数组。我提供了这个类的另一个实现,我发现它更适合这个目标:

final class Students {
    private static final int TOTAL = 1000;

    private final Map<String, Student> students = new HashMap<>(TOTAL);

    public void setName(String rollno, String name) {
        getOrCreateStudent(rollno).name = name;
    }

    public void setIntel(String rollno, int intel) {
        getOrCreateStudent(rollno).intel = intel;
    }

    public void setType(String rollno, int type) {
        getOrCreateStudent(rollno).type = type;
    }

    public Set<String> getRollno() {
        return students.keySet();
    }

    public String getName(String rollno) {
        return students.getOrDefault(rollno, Student.NULL).name;
    }

    public int getIntel(String rollno) {
        return students.getOrDefault(rollno, Student.NULL).intel;
    }

    public int getType(String rollno) {
        return students.getOrDefault(rollno, Student.NULL).type;
    }

    private Student getOrCreateStudent(String rollno) {
        Student student = students.get(rollno);

        if (student == null)
            students.put(rollno, student = new Student(rollno));

        return student;
    }

    private static final class Student {
        private static final Student NULL = new Student(null);

        private final String rollno;
        private int intel;
        private int type;
        private String name;

        public Student(String rollno) {
            this.rollno = rollno;
        }
    }
}

【讨论】:

  • 这个例子是在你的问题上写的。然后,您可以将 Student 类移到 Student 类之外,并将其替换为 Map 学生集合。无论如何,我的观点是,在你的问题中,你选择了错误的实现。
猜你喜欢
  • 1970-01-01
  • 2011-01-19
  • 2019-07-09
  • 2015-09-17
  • 1970-01-01
  • 2023-02-22
  • 2023-01-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多