【问题标题】:Understanding ArrayLists and Objects了解 ArrayList 和对象
【发布时间】:2018-05-15 08:49:33
【问题描述】:

假设我有以下Class Product

public class Product {
    // Variables.
    private String name;      // Name  
    private Double price;     // Price

    Product() {}    // Default constructor with no parameters.

    Product(String name, Double price) {    // Constructor with parameters.
        this.name = name;
        this.price = price;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Double getPrice() {
        return price;
    }
    public void setPrice(Double price) {
        this.price= price;
    }
    public String toString() {    // Overriding "toString()".
        return "\nName: " + this.name + "\nPrice: " + this.price;
    }


public boolean equals(Object obj) {    // Overriding equals()
   if(this == obj) {
      return true;
   }
   if(obj == null || obj.getClass() != this.getClass()) {
      return false;
   }
   Product product = (Product) obj;
   return this.name.equals(product.name)&& this.price.equals(product.price);
}
    }

现在,假设我的Main.class 中有一个ArrayList,而我的Main 看起来像这样:

import java.util.*;
    import java.io.*;
    public class Main {
        private static BufferedReader r = new BufferedReader (new InputStreamReader(System.in));
        private static String readln() throws IOException{
            return r.readLine();
        }
        private static long readInput() throws IOException{    // Use this to read input for the menu options.
            return Integer.valueOf(readln());
        }
        public static void menu(){    // Menu
            System.out.println("-------------------------" +
                    "\nAdd new product(1)" +
                    "\nSearch for product(2)" +
                    "\nDelete product(3)" +
                    "\nShow all products(4)" +
                    "\nReturn the number of products(5)" +
                    "\nExit(-1)" +
                    "\n-------------------------");
        }

        public static void main (String args[]) throws IOException{
            // This is the ArrayList for the "Product".
            ArrayList<Product> products = new ArrayList<Product>();
            int option = 0;
            do {
                menu();
                option = (int)readInput();
                switch (option){
                    case 1:{
                        System.out.println("Insert product name: ");
                        String name= readln();
                        System.out.println("Insert product price: ");
                        Double price = Double.parseDouble(readln());
                        products.add(new Product(name, price));
                        break;
                    }
                    case 2:{
                        System.out.println("Insert product name: ");
                        String name= readln();
                        System.out.println("Insert product price: ");
                        Double price= Double.parseDouble(readln());
                        if ((products.contains(new Product (name, price)))){
                            System.out.println("Works!");
                        }

                        break;
                    }
                    case 3:{

                        break;
                    }
                    case 4:{

                        break;
                    }
                    case 5:{
                        System.out.println("Number of products: " + products.size());
    //This prints with no problems, therefor the objects DO exist in the ArrayList.
                        break;
                    }
                }
            }while((option > 0) && (option < 6));
        }
    }

根据this,为了在ArrayList中插入一个对象,你需要这样写“ArrayListName.add(new ObjectName(param1, param2));”或者你可以创建一个名为object1的对象,然后将它与ArrayListName.add(object1);添加到我的情况,据我了解,我将对象插入到 ArrayList 但这些对象并不真正存在,因为如果我尝试使用覆盖的 toString() 方法,它不会打印任何内容。 如果我理解错了,为什么不打印?根据this,我的方法是正确的。

如果我正确理解this,对象不需要变量来指向它们,但如果你像我一样直接将它们插入ArrayList你应该怎么做获取对象的索引位置? 因为在我的例子中equals() 比较对象,所以你不能用它来搜索ArrayList。你也不能尝试像“products.contains(name, price);”这样的东西,因为.contains()使用equals()

我也在考虑做类似this 的事情,但它只有在你想创建一个新的Class 而不是像product1 这样的对象时才有用,就我而言。我也放弃了它,因为forName() 一直说它找不到Class,因为我找不到原因。

“删除”选项怎么样?它会和“搜索”一样吗?

编辑:对于equals()最后一行,也可以放:

if( (this.price.equals(product.getPrice())) && (this.name.equals(product.getName())) ) {
            return true;
        }

【问题讨论】:

  • 一次问一个问题怎么样?你在哪里打电话toString()
  • 这是打印数组列表第一个元素的示例:System.out.println(products.get(0))。它将调用您的自定义 toString() 方法。我猜你想在用户选择第四个菜单选项时循环播放每个产品并打印它们。
  • 您还需要覆盖docs.oracle.com/javase/8/docs/api/java/lang/… 以比较对象,请检查此答案:stackoverflow.com/questions/16069106/…
  • @MuratK。我不。 “.....因为如果我尝试使用被覆盖的 toString() 方法......”
  • @Oneiros 当我尝试从ArrayList 打印东西时,它可以工作,但问题是,当你没有指向它的变量时,你将如何搜索它以查找对象,假设您也不知道该对象的索引?

标签: java object arraylist


【解决方案1】:

为了让它工作,你还应该重写你的 equals 方法来编译 people 对象 overriding equals method 中的字段

您的参数化构造函数中可能存在错误。它应该看起来像:

Product(final String name, final Double price) {    // Constructor with parameters.
    this.name = name;
    this.price = price;
}

最后一句话阻止我们改变传入参数的值。

根据上面的文章实现应该是

@Override
public boolean equals(Object obj) {    // Overriding "equals()".
    // at first check if objects are the same -> your code
    if (this == obj) {
        return true;
    }

    // secondly we chack if objects are instances of the same class if not return false
    if (obj != null && this.getClass() != obj.getClass()) {
        return false;
    }

    // then compare objects fields. If fields have the same values we can say that objects are equal.
    Product product = (Product) obj;
    return this.name.equals(product.name) && this.price.equals(product.price);
}

为了处理字段中的空值,我们可以编写额外的检查。

使用新实现的 equals 方法来搜索列表中的元素,您可以将新的产品实例传递给包含方法

而不是做

products.contains(name, price);

试试

products.contains(new Product(name, price))

要从列表中删除元素,您可以先找到元素的索引并使用remove方法。

products.remove(products.indexOf(new Product(name, price)))

【讨论】:

  • 我尝试将equals() 更改为public boolean equals(String name, Double price) { if ((this.name == name) &amp;&amp; (this.price == price)) { return true; } return false; }public boolean equals(Product obj) { if (this==obj) { return true; } return false; },但没有成功。例如,当我尝试输入主要的 if (products.contains(new Product(name, price))){ System.out.println("Works"); } 时,它没有打印任何内容。
  • 我已经编辑了我的答案,为您提供 euqals 方法示例。
  • 我输入了return this.name == product.name &amp;&amp; this.price == product.price;,因为否则,它表示它无法解析符号“名称”和“价格”,但我仍然一无所获。这很奇怪。不过,我非常感谢您抽出宝贵时间帮助我。
  • 您的 equals 方法签名应类似于 public boolean equals(Object obj)
  • 确实如此。该方法没有错误,但是这个if (products.contains(new Product(name, price))){ System.out.println("Works"); } sill 没有打印“Works”,是if 错误吗?
【解决方案2】:

实际上,这不是理解使用ArrayList 的好例子。首先,这个集合不适合产品列表。是的,您可以使用它,但Map 更好。我不认为你正在学习Java。如果是这样,我更喜欢使用Map 而不是List

此外,我建议避免使用选项编号。至少使用 命名常量,但使用 OOP 更好。例如。您可以使用enum,其中每个元素都是一个菜单选项。

例如如下所示。

public class Main {
    public static void main(String... args) {
        List<Product> products = readProducts();
        // final list of products
    }

    private static List<Product> readProducts() {
        Map<String, Product> products = new LinkedHashMap<>();

        try (Scanner scan = new Scanner(System.in)) {
            while (true) {
                MenuItem.show();
                MenuItem menuItem = MenuItem.parseOption(scan.nextInt());

                if (menuItem == MenuItem.EXIT)
                    break;

                menuItem.action(products, scan);
            }
        }

        return products.isEmpty() ? Collections.emptyList() : new ArrayList<>(products.values());
    }

    private enum MenuItem {
        ADD_NEW_PRODUCT(1, "Add new product") {
            @Override
            public void action(Map<String, Product> products, Scanner scan) {
                System.out.println("Insert product name: ");
                String name = scan.next();

                System.out.println("Insert product price: ");
                double price = scan.nextDouble();

                if (products.containsKey(name))
                    products.get(name).setPrice(price);
                else
                    products.put(name, new Product(name, price));
            }
        },
        SEARCH_FOR_PRODUCT(2, "Search for product"),
        DELETE_PRODUCT(3, "Delete product") {
            @Override
            public void action(Map<String, Product> products, Scanner scan) {
                System.out.println("Insert product name: ");
                String name = scan.next();

                products.remove(name);
            }
        },
        SHOW_ALL_PRODUCTS(4, "Show all products"),
        RETURN_THE_NUMBER_OF_PRODUCTS(5, "Return the number of products") {
            @Override
            public void action(Map<String, Product> products, Scanner scan) {
                System.out.println("Number of products: " + products.size());
            }
        },
        EXIT(-1, "Exit");

        private final int option;
        private final String title;

        MenuItem(int option, String title) {
            this.option = option;
            this.title = title;
        }

        public void action(Map<String, Product> products, Scanner scan) {
        }

        public static MenuItem parseOption(int option) {
            for (MenuItem menuItem : values())
                if (menuItem.option == option)
                    return menuItem;
            return EXIT;
        }

        public static void show() {
            System.out.println("-------------------------");

            for (MenuItem menuItem : values())
                System.out.printf("%s(%d)\n", menuItem.title, menuItem.option);

            System.out.println("-------------------------");
        }
    }
}

【讨论】:

    猜你喜欢
    • 2018-09-07
    • 1970-01-01
    • 1970-01-01
    • 2013-12-10
    • 2017-10-21
    • 2015-12-28
    • 2011-09-27
    • 2013-02-09
    • 2015-06-12
    相关资源
    最近更新 更多