如何在每次调用组件方法时增加字符串输入

huangapple go评论82阅读模式
英文:

How to increase String input for every time component method is called

问题

我刚开始在大学学习编程(主要是Java),大约6个月了,我们刚刚学习了组合设计模式的部分(使用了组件、叶子和组合类)。

我的课堂问题要求我使用下面的Component接口来创建一个简单的导演程序,可以创建/添加/删除文件/目录。

以下是我编写的用作叶子的File类:

public class File implements Component { 
    // ... (内容太多,请参考原文)
}

以下是组件类 - Directory类。在问题中标记了显示方法的上面部分:

public class Directory implements Component {
    // ... (内容太多,请参考原文)
}

我的目标是,当应用显示方法时,每次组件具有子项时,显示方法中的前缀应该增加1。测试方法如下:

public class Test3 {
    // ... (内容太多,请参考原文)
}

然而,由于显示方法中,当组件有子项时,它调用(prefix + prefix),这仅在第3个目录/文件之前起作用,而不是每次递增1。以下是我得到的结果:

pictures: (count=2, size=622)
\+personal: (count=2, size=622)
\++family-holiday (201)
\++misc: (count=1, size=421)
\++++dog: (count=1, size=421)
\++++++++wallpaper (421)

我尝试了多种我能想到的方式:

  • 在File的display方法中添加前缀:当目录中有子目录时,显然无法工作
  • 使用静态参数来计算调用的方法次数,因为应该使用前缀的次数取决于文件/目录所在的级别,但无法对方法使用的次数进行完全计数
  • 在许多不同的地方添加前缀... 如何在每次调用组件方法时增加字符串输入 仍然无法正常工作。我可以想象,必须是我传递前缀的方式在循环再次调用display时出了问题,但我无法弄清楚是什么问题...

如果您能就我可以做什么或者我应该阅读哪些内容给予指导或建议,将会非常有帮助。如果我的关键字的当前知识中有类似的主题,我在此提前表示歉意,因为我找不到它们,如果您能引导我到相关内容,我将不胜感激。

英文:

I just started learning coding (mainly Java) for about 6 months at a University and now we just covered section of Composite design pattern (with Component, Leaf and Composite classes).

My class problem requires I use the below Component Interface to make a simple director program that I can create/add/remove files/directory.

public interface Component {
    public String getName();
    public int getSize();
    public int getCount();
    public String display(String prefix);
    public Component search(String name);
}

Below is the File class that I wrote to be used as Leaf

public class File implements Component { 
    private String name;
    private int size;
    public File(String name, int size){
        this.name = name;
        this.size = size;
    }
    
    @Override
    public String getName() {
        return this.name;
    }
    
    @Override
    public int getSize() {
        return this.size;
    }
    
    @Override
    public int getCount() {
        return 1;
    }
    
    @Override
    public String display(String prefix) {
        return this.name + " " + "(" + this.size + ")" + System.lineSeparator();
    }
    
    @Override
    public Component search(String name) {
        if(this.name.equals(name)){
            return this;
        }
        else {
            return null;
        }
    }

Below is the Component Class - Directory Class. I put line of * above the method display in question.

import java.util.ArrayList;

public class Directory implements Component {
    static int count = 0;
    private String name;
    //Array List to store the leafs
    public ArrayList<Component> children;

    public Directory(String name){
        this.name = name;
        this.children = new ArrayList<>();
    }

    //Method to add leaf to Directory
    public void add(Component component){
        children.add(component);
    }

    //Method to remove leaf from Directory
    public void remove(Component component){
        children.remove(component);
    }

    @Override
    public String getName() {
        return this.name;
    }

    @Override
    public int getSize() {
        int size = 0;
        for(Component component : children) {
            size += component.getSize();
        }
        return size;
    }

    @Override
    public int getCount() {
        int count = 0;
        for(Component component : children) {
            count += component.getCount();
        }
        return count;
    }

//***********************************
    @Override
    public String display(String prefix) {
        String totalString = name + ": (count=" + getCount() + ", size=" + getSize() + ")" + System.lineSeparator();

        for (Component component : children) {
            totalString = totalString + prefix + component.display(prefix + prefix);
        }
        return totalString;
    }

//*************************************
    @Override
    public Component search(String name) {
        for(Component component: children) {
            if (component.search(name) != null) {
                return component;
            }
        }
        return null;
    }
}

My goal is, when I apply the display method, every-time the component has children, the prefix in display method should increase by 1. To clarify, below is my test method

public class Test3 {

    public static void main(String[] args) {
        File holiday = new File("family-holiday",201);
        File wallpaper = new File("wallpaper", 421);
        Directory pictures = new Directory("pictures");
        Directory personal = new Directory("personal");
        Directory misc = new Directory("misc");
        Directory dog = new Directory("dog");
        dog.add(wallpaper);
        personal.add(holiday);
        personal.add(misc);
        pictures.add(personal);
        misc.add(dog);

        System.out.print(pictures.display("+"));
    }
}

The result of this should be

pictures: (count=2, size=622)
\+personal: (count=2, size=622)
\++family-holiday (201)
\++misc: (count=1, size=421)
\+++dog: (count=1, size=421)
\++++wallpaper (421)

However, due to the display method when component has children, it calls (prefix + prefix) which works until the 3rd directory/files, the prefix gets doubled every time instead of an increment of one. Below is the result I got

pictures: (count=2, size=622)
\+personal: (count=2, size=622)
\++family-holiday (201)
\++misc: (count=1, size=421)
\++++dog: (count=1, size=421)
\++++++++wallpaper (421)

I have tried multiple ways that I can think of below

  • Add prefix at the File display : This obviously did not work if there is director inside directory

  • Use static parameter to count number of method getting called, since the number of times prefix should be used depends on how many level the file / director is in there, that doesn't work with full count of the number of times used by the method.

  • Adding prefix at MANY MANY different places .. 如何在每次调用组件方法时增加字符串输入 Still did not work well. I can imagine it has to be the way I pass the prefix to when the loop is calling display again, but I can't figure out what it is ...

If you could please advise or guide on what I can do or what I should read on to help with this, that will be very helpful. I do apologise in advance if there is similar topics as I couldn't find them with my current knowledge of the keyword, if you could please guide me there then I'm very grateful

答案1

得分: 0

Sure, here's the translated code part:

@Override
public String display(int depth) {
    String prefix = '+'.repeat(depth);
    String totalString = name + ": (count=" + getCount() + ", size=" + getSize() + ")" + System.lineSeparator();

    for (Component component : children) {
        totalString = totalString + prefix + component.display(depth + 1);
    }
    return totalString;
}

...

System.out.print(pictures.display(1));
英文:

As I said, just pass the depth as an integer and construct the prefix within the display function.

    @Override
    public String display(int depth) {
        String prefix = '+'.repeat(depth);
        String totalString = name + ": (count=" + getCount() + ", size=" + getSize() + ")" + System.lineSeparator();

        for (Component component : children) {
            totalString = totalString + prefix + component.display(depth + 1);
        }
        return totalString;
    }

...

        System.out.print(pictures.display(1));

答案2

得分: 0

我看到你的代码中存在几个问题,但由于这不是 https://codereview.stackexchange.com,我不会在这里处理所有问题。

重要的一点:不要在循环中使用++=操作符连接String。请使用java.lang.StringBuilder来执行这个操作。

而不是将prefix加倍,你可以根据第一个字符和输入前缀的大小来计算新的前缀。以下只是Directory.display方法的示例:

@Override
public String display(String prefix) {
  StringBuilder totalString = new StringBuilder(name);
  totalString.append(" (count=").append(getCount());
  totalString.append(", size=").append(getSize()).append(")");
  totalString.append(System.lineSeparator());

  for (Component component : children) {
    totalString.append(prefix).append(component.display(prefix.substring(0, 1).repeat(prefix.length() + 1)));
  }
  return totalString.toString();
}

这样你可以保持你的接口与以前完全相同。尽管TimRoberts的答案可能更高效和性能更好,但不会保持你的接口不变。

英文:

I see several issues in your code but won't address all of them here as this is not https://codereview.stackexchange.com.

But important: don't concatenate String in a loop with the + or += operators. Use java.lang.StringBuilder for this.

Instead of doubling your prefix, you can calculate the new prefix from the first char and the size of the input prefix. Here is just the Directory.display method:

@Override
public String display(String prefix) {
  StringBuilder totalString = new StringBuilder(name);
  totalString.append(": (count=").append(getCount());
  totalString.append(", size=").append(getSize()).append(")");
  totalString.append(System.lineSeparator());

  for (Component component : children) {
    totalString.append(prefix).append(component.display(prefix.substring(0, 1).repeat(prefix.length() + 1)));
  }
  return totalString.toString();
}

This way you can keep your given interface exactly as before. Still @TimRoberts answer is probably more efficient and performant, but doesn't keep your interface the same.

huangapple
  • 本文由 发表于 2023年2月7日 02:49:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/75365429.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定