我制作了一个程序,应该从文本文件中的手机列表中向我发送两部“最佳手机”,但只显示一部?

问题描述 投票:0回答:1

这是我的java项目的链接:https://github.com/Mundanest/Java-files/tree/main/Lab%207

(这是我第一次使用github,因为我不知道如何链接java项目文件夹,所以我可能搞砸了)(代码也在底部)

它有4个班级:

  • 用于打印,FindBestPhone.java

  • 用于创建 Phone 对象,Phone.java

  • 用于将电话添加到各种列表,PhoneList.java

  • 还有一个用于解析文本的,PhoneParser.java

主要目标是从“phone-data.txt”中的一长串手机中找到两台最好的手机。

(一部手机电池容量最高,另一部手机屏幕尺寸最大)


我收到了一个示例文本文件“phone-data-short.txt”,其中最好的手机是Samsung Galaxy S8 PlusHuawei Mate 10 Pro

我的问题是,当我尝试打印两部手机(来自phone-data.txt)时,它只打印一部手机。

我不确定我是否尝试错误地打印它们,或者是否妨碍我在计算最佳手机后存储列表的方式。

我最好的猜测是 PhoneList.java 中的“getBestPhones”方法返回错误,或者我的主要“FindBestPhones”错误地请求最好的手机。

我尝试更换返回方式:

return Collections.unmodifiableList(allPhones);

与:

return allPhones;

在 getBestPhones 方法中

以及我如何打印它:

System.out.println(bestPhones);

与:

for (Phone phone : bestPhones) {
    System.out.println(phone.getModel());
}

但似乎没有任何效果


注意:我不确定是否是最好的手机是如何计算的,因为这是提供给我的框架代码。

(addPhone()和phoneIsDominated()方法已经存在)

我也无法在我的主目录中打印手机的名称,但没有获得两部最好的手机更是一个问题。

我对 Java 还很陌生,所以我可能错过了一些明显的东西。

编辑(代码):

我的主课:

import java.io.IOException;
import java.util.Collection;

public class FindBestPhones {
    public static String PHONES_FILE = "phone-data.txt";

    public static void main(String[] args) {
        // TODO: use the parseFile() method FROM PhoneParser.JAVA to get the phone data from the file

        // TODO: print the model names of all the best phones: getBestPhones() from PhoneList.java

        // TODO: handle I/O failures by printing an error message, that might occur in parseFile()


        
        try {
            PhoneList phoneList = PhoneParser.parseFile(PHONES_FILE);
            // Get the best phones from the phone list
            Collection<Phone> bestPhones = phoneList.getBestPhones();

            System.out.println(bestPhones); 
            
            //
            PhoneList testlist = PhoneParser.parseFile("phone-test.txt");
            Collection<Phone> testcoll = testlist.getAllPhones(); 
            System.out.println(testcoll);
            
            
        } catch (IOException e) {
            e.printStackTrace();
        }




    }
} 

我的自定义电话对象类:

/*
 * Phone — a model class representing a smart phone. A phone has a model name, a
 * screen size, and a battery capacity. */
public class Phone {
    private final String model;
    private final double screenSize;
    private final int batteryCapacity;
    
    public Phone(String model, double screenSize, int batteryCapacity) {
        // : Ensure the screenSize and batteryCapacity are positive
        // by throwing an IllegalArgumentException otherwise
        
        //TASK 1: 
        if (screenSize <0 || batteryCapacity <=0) {
            throw new IllegalArgumentException("Screen size and/or battery capacity must not be positive");
        }
        
        this.model = model;
        this.screenSize = screenSize;
        this.batteryCapacity = batteryCapacity;
    }

     // Gets the phone's model name.
    public String getModel() {
        return model; 
    }
    
     // Gets the phone's diagonal screen size (in inches).
    public double getScreenSize() {
        return screenSize;
    }
    
     // Gets the phone's battery capacity (in mAh).
    public int getBatteryCapacity() {
        return batteryCapacity;
    }
    
     /* Determines whether this phone "dominates" another phone, meaning
     * this phone is better in one criterion, and at least as good in the
     * other criterion. */
    
    public boolean dominates(Phone other) {
        // : implement this method
        // Task 2:
        return (this.getScreenSize() > other.getScreenSize() || 
                this.getBatteryCapacity() > other.getBatteryCapacity());

        
    }
}

我的电话列表类:

/*
  PhoneList — a model class representing a list of phones. There is 
  an addPhone method to add a phone to the list, a getAllPhones to get a list of all
  phones, and a getBestPhones method to get a list of just the ‘best’ phones.
 */


import java.util.*;

public class PhoneList {
    private final List<Phone> allPhones = new ArrayList<>();
    private final Set<Phone> bestPhones = new HashSet<>();
    
    /*
     * Adds a phone to the list.
     */
    public void addPhone(Phone phone) {
        allPhones.add(phone);
        
        // remove from bestPhones if dominated by the new phone
        Iterator<Phone> iter = bestPhones.iterator();
        while(iter.hasNext()) {
            Phone other = iter.next();
            if(phone.dominates(other)) {
                iter.remove();
            }
        } 
        
        // only add the new phone to bestPhones if it's not dominated
        if(!phoneIsDominated(phone)) {
            bestPhones.add(phone);
        }
    }
    
    /*
     * Determines whether a phone is dominated by any other phone.
     */
    public boolean phoneIsDominated(Phone phone) {
        // only need to compare with the undominated phones
        for(Phone other : bestPhones) {
            if(other.dominates(phone)) {
                return true;
            }
        }
        return false;
    }
    
    /*
     * Gets all phones. The list returned is unmodifiable.  
     */
    public List<Phone> getAllPhones() {
        // : return an unmodifiable view of the list
        // Task 3.1:
        //return allPhones;
        return Collections.unmodifiableList(allPhones);
        //return allPhones;
    }
    
    /*
     * Gets all phones which are not dominated by another phone. The
     * collection returned is unmodifiable.  
     */
    public Collection<Phone> getBestPhones() {
        // : return an unmodifiable view of the set
        //Task 3.2:
        return Collections.unmodifiableSet(bestPhones);
        //return bestPhones;
        

    }
}

我的PhoneParser类:

/*
 * PhoneParser — a helper class which can parse phone data from a string, and load
 * all the phone data from a text file.
 */

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.Scanner;

public class PhoneParser {
    /*
     * Parses a phone data string, in the following format:
     * 
     *     model screenSize batteryCapacity
     *     
     * The model name is encoded with underscores instead of spaces.
     */
    public static Phone parse(String data) {
        // : parse the phone data string, and return a Phone object.
        // you may use string manipulation, a regex, or a Scanner
        //Task 4:
        try (Scanner scanner = new Scanner(data)){
            // set delimiter to split on spaces
            scanner.useDelimiter(" ");

            if (scanner.hasNext()) {
                String model = scanner.next().replace("_"," ");
                if (scanner.hasNextDouble() && scanner.hasNextInt()) {
                    double screenSize = scanner.nextDouble();
                    int batteryCapacity = scanner.nextInt();
                    return new Phone(model, screenSize, batteryCapacity);
                }

            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        // Returns null if parsing fails
        return null;
    }

    /*
     * Returns a PhoneList by parsing a text file containing the phone data.
     */
    public static PhoneList parseFile(String filename) throws IOException {
        // : create a PhoneList TASK 5:
        PhoneList phoneList1 = new PhoneList();

        // : create a BufferedReader to read from the file TASK 5:
        try (BufferedReader reader = new BufferedReader(new FileReader(filename))) {

            // : for each line, parse it as a Phone and add it to the list TASK 5:
            String line;
            while ((line = reader.readLine()) != null) {
                Phone phone = parse(line);
                if (phone != null) {
                    phoneList1.addPhone(phone);
                }   
            }
        }
        return phoneList1;
    }

}

控制台打印:

[电话@2ed94a8b]

当我运行代码时。

我还发现了,我制作了一个测试文本文件并填充了4个测试手机:

并在控制台中给出了这个:

[电话@38082d64,电话@dfd3711,电话@42d3bd8b]

由于某种原因只拿起 3 部手机而不是 4 部,这可能就是我的问题所在。

java oop filereader hashset system.out
1个回答
0
投票

对我来说,这相当令人困惑。为什么最好的手机不能同时拥有最大的屏幕尺寸和最大的电池容量?在屏幕尺寸和电池容量方面,一部手机与另一部手机相比,哪一个优先?难道它不应该是可配置的(在某种程度上)来满足特定的需求吗?

尝试下面的小可运行代码(阅读代码中的注释)。请务必使用

numberOfBestPhonesToFind
precedence
成员变量的值:

public class GetBestPhoneDemo {

    /* Will Hold the max Screen size of a phone found 
       that matches desired precedence:           */
    double maxScreenSize;
    
    /* Will Hold the max Battery Capacity of a phone 
       found that matches desired precedence:     */
    int maxBatteryCapacity;
    
    // The number of "Best Phones" this app is to acquire:
    int numberOfBestPhonesToFind = 2;

    /* 0  = Both Screen Size & Battery Capacity take equal precedence. 
       1  = Screen Size takes more precedence than Battery Capacity.
       2  = Battery Capacity takes more precedence than Screen Size.  
       3  = Screen Size takes full precedence.
       4  = Battery Capacity takes full precedence.         
       5+ = Nothing is displayed.                             */
    int precedence = 0;
    
    /* Internally used counter to keep track of 
       the number of best phones acquired:   */
    int phoneCount = 0;

    /* List Interface of String to hold whatever file
       lines that are deemed to be "Best Phones":  */
    java.util.List<String> bestPhonesList = new java.util.ArrayList<>();
    
    // Will hold the currently processed "Best Phone" data Line:
    String currentBestPhone = "";
    
    
    
    // The `main()` method - Application entry point....
    public static void main(String[] args) {
        /* App started this way to avoid the need for statics
           unless we really want them:        */
        new GetBestPhoneDemo().startApp(args);
    }

    private void startApp(String[] args) {
        java.io.File dataFile = new java.io.File("Phone-Data-List.txt"); // OR "Phone-Data-Short.txt"
        while (phoneCount < numberOfBestPhonesToFind) {
            maxScreenSize = Double.MIN_VALUE;
            maxBatteryCapacity = Integer.MIN_VALUE;
            String bestPhone = "";
            
            // 'Try With Resources' used here to auto-close reader:
            try (java.util.Scanner reader = new java.util.Scanner(dataFile)) {
                String line = "";
                while (reader.hasNextLine()) {
                    line = reader.nextLine();
                    line = line.trim();
                    /* Skip blank lines (should there be any) and skip past 
                       any phone that is already in the `bestPhoneList`  */
                    if (line.isEmpty() || bestPhonesList.contains(line)) {
                        continue;
                    }
                    
                    // Split the currently read in data line...
                    String[] lineParts = line.split("\\s+");
                    
                    // Get the Battery Capacity from data line:
                    int batCap = Integer.parseInt(lineParts[lineParts.length - 1]);
                    
                    // Get the Screen Size from data line:
                    double scrnSize = Double.parseDouble(lineParts[lineParts.length - 2]);
                    
                    // Set a possible best phone based on the desired precedence:
                    if (precedence == 0 && (scrnSize >= maxScreenSize && batCap >= maxBatteryCapacity)) {
                        setBestPhone(scrnSize, batCap, line);
                    } 
                    else if (precedence == 1 && (scrnSize > maxScreenSize && batCap >= maxBatteryCapacity)) {
                        setBestPhone(scrnSize, batCap, line);
                    } 
                    else if (precedence == 2 && (scrnSize >= maxScreenSize && batCap > maxBatteryCapacity)) {
                        setBestPhone(scrnSize, batCap, line);
                    } 
                    else if (precedence == 3 && scrnSize > maxScreenSize) {
                        setBestPhone(scrnSize, batCap, line);
                    }
                    else if (precedence == 4 && (batCap > maxBatteryCapacity)) {
                        setBestPhone(scrnSize, batCap, line);
                    } 
                }
            }
            catch (java.io.FileNotFoundException ex) {
                System.err.println(ex.getMessage());
                return;
            }
            
            /* Add the determined "Best Phone" to the `bestPhonesList` 
               List providing it isn't already in there:        */
            if (!bestPhonesList.contains(currentBestPhone)) {
                bestPhonesList.add(currentBestPhone);
                phoneCount++; // Increment the phone count aquired, by 1:
            }
            
            // Read the file again to get another best phone (if needed).
        }
                
        // Display the Best Phones in Console Window:
        for (String str : bestPhonesList) {
            System.out.println(str);
        }
    }

    private void setBestPhone(double screenSize, int batteryCapacity, String bestPhone) {
        maxScreenSize = screenSize;
        maxBatteryCapacity = batteryCapacity;
        currentBestPhone = bestPhone;
    }
}

你可能需要稍微调整一下,但是,也许你可以从中得到一些东西。

© www.soinside.com 2019 - 2024. All rights reserved.