有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java函数将字符串数组转换为列表,然后在不丢失更改的情况下返回到旧的字符串数组

编辑:规则是我不能修改公式。这些方法必须是void,我必须将预初始化的数组传递给这些方法。这些都是未来任务本身的约束条件,这就是为什么我试图用这种方式来处理这个名字包程序

我试图写一个“名字袋”程序,既为了好玩,也为了将来的作业练习。目标是让用户拥有一个包。在这个袋子里,他们可以储存25个名字。他们可以一次添加一个名称,一次删除一个名称,对包进行排序,使名称按字母顺序排列,等等。基本数组练习。不过,由于我对Java不太熟悉,我遇到了一些问题。我有一个函数,它接受数组,将其转换为列表,尝试添加用户选择的名称,然后尝试将该列表转换回它曾经所在的数组。然后我有另一个函数,它试图显示数组中的所有内容

当我避免使用菜单、开关盒和方法时,此代码会起作用。我可以将东西存储到名称包中,并且可以显示名称,而不会出现任何问题,也不会显示空值。但我不明白为什么名字不会显示在下面的代码中。有没有一种方法可以在Java中获得某种通过引用传递的效果?有没有更好的方法来做这种节目?谢谢你的建议

这是我的代码:

import java.util.ArrayList;
import java.util.Scanner;
import java.util.Arrays;

public class nameBag {
    public static void main(String[] args) {

        String[] nameBag = new String[25];
        Scanner input = new Scanner(System.in);

        while (true){

            System.out.println("Welcome to the bag of names.");
            System.out.println("1. Add an item to the bag.");
            System.out.println("2. Display items in bag.");
            System.out.println("0. Exit program.");

            int userChoice = input.nextInt();
            switch (userChoice){
                    case 1:
                    addName(nameBag);
                    break;
                case 2:
                    displayNames(nameBag);
                    break;
                case 0:
                    System.out.println("See ya!");
                    System.exit(0);
            }
        }
    }

    public static void addName(String[] nameBag){
        ArrayList<String> nameList = new ArrayList<String>(Arrays.asList(nameBag));
        Scanner input = new Scanner(System.in);
        System.out.println("What name do you want to add to the pack?");
        String userSelection;
        userSelection = input.nextLine();
        nameList.add(userSelection);
        nameBag = nameList.toArray(nameBag);
    }

    public static void displayNames(String[] nameBag){
        for (String s : nameBag) {
            if (!(s == null)) {
                System.out.println(s);
            }
        }
    }
}

共 (6) 个答案

  1. # 1 楼答案

    没有简单的方法通过引用发送基于类的对象,所有类的传递方式都是将对它们的引用作为复制为值的参数传递

    为了避免这种情况,您可以使用一个Holder对象来保存指针,这样一来,作为引用发送的是指向Holder对象的指针,但其中保存的对象实际上是指向您想要操纵的对象的指针

    因此,与其说:

    public class nameBag 
    {
        public static void main(String[] args) 
        {
           String[] nameBag = new String[25];
    

    你应该:

    public class ArrayHolder
    {
        private String[] nameBag;
    
        public ArrayHolder(String[] nameBag)
        {
            this.setNameBag(nameBag); 
        }
    
        public String[] getNameBag()
        {
            return this.nameBag;
        }
    
        public void setNameBag(String[] nameBag)
        {
            this.nameBag = nameBag;
        }
        //by the way, if these functions break your limitations,
        //then it works even if nameBag is just a simple public variable
    }
    

    然后你可以:

    public class nameBag 
    {
        public static void main(String[] args) 
        {
           String[] nameBag = new String[25];
           ArrayHolder arrayHolder = new ArrayHolder(nameBag);
           ...
    

    但是你必须把ArrayHolder发送到你的函数中:

    public static void addName(ArrayHolder arrayHolder)
    {
        //everything is same here, just accessing nameBag directly
        Scanner input = new Scanner(System.in);
        System.out.println("What name do you want to add to the pack?");
        String userSelection = input.nextLine();
        ArrayList<String> nameList = new ArrayList<String>(Arrays.asList(arrayHolder.getNameBag()));
        nameList.add(userSelection);
        nameBag = nameList.toArray(new String[nameList.size()]);
    }
    

    但正如您最初所说,数组必须是参数,不能是您自己的ArrayHolder对象;有了这个前提,我想唯一的解决办法就是把它变成一个静态变量

  2. # 2 楼答案

    addName方法中的下一行在实际执行中没有任何影响。 nameBag=名字列表。toArray(姓名袋)

    原因是,您实际上是在更改局部变量“nameBag”以指向一个新数组。这对主函数中定义的变量没有影响

    要真正理解发生了什么,请将addName的变量名更改为其他名称。例如paramNameBag。你会立刻明白发生了什么。当您进行这样的更改时,您希望上面的一行实际上是指main方法中定义的变量。但是您不能在这里访问它,因为它是main方法的本地方法。由于您使用的是全静态方法,所以实现这一点的唯一方法是将nameBag声明移出并使其成为静态

    还有另一个快速而肮脏的解决方案。将addName签名更改为below,并从方法返回数组。然后可以将返回的数组重新分配给主变量

     public static String[] addName(String[] nameBag, String userSelection){
        .....
        .....
        return nameList.toArray(nameBag);
     }
    
    
    
        switch (userChoice){
                    case 1:
                    namesBag = addName(nameBag);
    

    这应该可以

    但我真的建议首先使用ArrayList,而不是array并来回转换为ArrayList

    祝你好运

  3. # 3 楼答案

    Java总是按值传递,所以没有按引用传递,但在大多数情况下,值是对对象的引用

    例如,如果向传递给方法的列表中添加元素,则可以在调用方方法中看到该元素,因为传递给该方法的值实际上是对列表的引用

    你的问题在于这种方法:

    public static void addName(String[] nameBag){
        ArrayList<String> nameList = new ArrayList<String>(Arrays.asList(nameBag));
        Scanner input = new Scanner(System.in);
        System.out.println("What name do you want to add to the pack?");
        String userSelection;
        userSelection = input.nextLine();
        nameList.add(userSelection);
        nameBag = nameList.toArray(nameBag);
    }
    

    在名为nameBag的主方法中有一个数组,这是参考(1)

    你叫你的addName(nameBag(1))(我将在括号中标记对象的引用)

    然后你会做你的第一行

    ArrayList<String> nameList = new ArrayList<String>(Arrays.asList(nameBag(1)));
    

    还是用同一个名字包。然后用ArrayList做很多事情,这是完全好的 但现在你知道了

    nameBag = nameList.toArray(nameList); //I assume a typo here
    

    您的nameBag将成为nameBag(2),因为您将把另一个数组引用放入同一个变量中,所以从现在起,您的方法中没有对nameBag(1)的任何引用。阻止此类编程错误的最简单方法是将方法参数声明为final

    使用nameBag可以为索引指定一个值,因此如果使用nameBag[1]=“foo”,调用方会看到该值,但不能重新指定该值,因为从那一刻起,您正在处理一个完全不同的对象

    你可以做的是要么不使用数组,要么使用列表,但鉴于这是一个数组练习,只需返回你在最后一行中创建的nameBag,并在main方法中重新设计你的数组

  4. # 4 楼答案

    试试这段代码,效果很好。你犯了几个错误,这就是它不起作用的原因。我保留了你的代码作为注释,这将便于理解

    记住这一点。这将有助于我希望: 1.尽量使用列表或集合而不是数组,因为数组不是动态大小的 2.默认情况下,树集将对内容进行排序 3.不需要时,不要将值传递给方法

    import java.util.ArrayList;
    import java.util.Scanner;
    import java.util.Arrays;
    import java.util.Set;
    import java.util.TreeSet;
    
    public class nameBag {
    static Set<String> nameBagSet = new TreeSet<String>();
    public static void main(String[] args) {
    
        //String[] nameBag = new String[25];
    
        Scanner input = new Scanner(System.in);
    
        while (true){
    
            System.out.println("Welcome to the bag of names.");
            System.out.println("1. Add an item to the bag.");
            System.out.println("2. Display items in bag.");
            System.out.println("0. Exit program.");
    
            int userChoice = input.nextInt();
            switch (userChoice){
                    case 1:
                    addName();
                    break;
                case 2:
                    displayNames();
                    break;
                case 0:
                    System.out.println("See ya!");
                    System.exit(0);
            }
        }
    
    
    
    }
    
    public static void addName(){
    //    ArrayList<String> nameList = new ArrayList<String>(Arrays.asList(nameBag));
    
    Scanner input = new Scanner(System.in);
    System.out.println("What name do you want to add to the pack?");
    String userSelection;
    userSelection = input.nextLine();
    nameBagSet.add(userSelection);
    //    nameList.add(userSelection);
    //    nameBag = nameList.toArray(nameBag);
     }
    
     public static void displayNames(){
     for (String s : nameBagSet) {
        if (!(s == null)) {
            System.out.println(s);
        }
    }
    

    } }

  5. # 5 楼答案

    由于没有遵循良好的编码惯例,程序中出现了两个错误

    1st displayNames(nameBag 
    

    你似乎已经在编辑中更正了

    第二个错误与理解java中的参数有关。不能将nameBag作为参数传递并向这些参数添加值。每次函数addName()结束执行时,这些值都会丢失。您可以在类变量下声明静态变量nameBag,并直接对其进行操作,而不是将其作为参数传递。这样,即使addName()displayName()函数结束执行(只要程序正在运行),您的更改也会反映出来。另外,你不需要任何退货类型。您可以直接访问全局列表变量

    import java.util.ArrayList;
    import java.util.Scanner;
    import java.util.Arrays;
    
    public class HelloWorld{
    
    static String[] nameBag; // NameBag is declared as class variable
    
    static{
    
        nameBag = new String[25]; //initialize nameBag
    
    }
    
        public static void main(String[] args) {
    
    
            Scanner input = new Scanner(System.in);
    
            while (true){
    
                System.out.println("Welcome to the bag of names.");
                System.out.println("1. Add an item to the bag.");
                System.out.println("2. Display items in bag.");
                System.out.println("3. Exit program.");
                  int userChoice=0;
                 try{
               userChoice = input.nextInt();
                 }
                 catch(Exception e){
                     e.printStackTrace();
    
                 }
                switch (userChoice){
                        case 1:
                        addName(); //No need to pass nameBag as a parameter
                        break;
                    case 2:
                        displayNames(); //No need to pass nameBag as a parameter
                        break;
                    case 3:
                        System.out.println("See ya!");
                        System.exit(0);
                }
            }
    
    
    
        }
    
    public static void addName(){
        //everything is same here, just accessing nameBag directly
        Scanner input = new Scanner(System.in);
        System.out.println("What name do you want to add to the pack?");
        String userSelection;
        userSelection = input.nextLine();
        ArrayList<String> nameList = new ArrayList<String>(Arrays.asList(nameBag));
        nameList.add(userSelection);
        nameBag = nameList.toArray(nameBag);
    }
    
    public static void displayNames(){
    //everything is same here, just accessing nameBag directly
        for (String s : nameBag) {
            if (!(s == null)) {
                System.out.println(s);
            }
        }
    }
    }
    
  6. # 6 楼答案

    在处理前检查输入是否为int类型,或者在处理输入前执行所需的异常处理

    使用Scanner的hasNextInt()验证输入是否为int

    Scanner input = new Scanner(System.in);
    while (!input.hasNextInt()) {
       System.out.println("Please enter int values only");
       input.nextLine();
    } 
    

    否则,如果未提供int,也可以执行一些异常处理来抛出异常

    try {
            Scanner input = new Scanner(System.in);
            int userChoice = input.nextInt();
        } catch (Exception e) {
            System.out.println("Please re-enter");
        }
    

    转换为数组

    Arrays.asList(string.toCharArray());
    

    如果你想把作为字符串数组返回

    ArrayList<String> myList = new ArrayList<String>();
    myList.add("value1");
    myList .add("value2");
    String[] myStringArray = new String[myList.size()];
    myStringArray = myList.toArray(myStringArray);