java 我做了一个程序,应该给我两个“最好的手机”从一个文本文件中的手机列表,但只显示一个?

dgsult0t  于 2023-11-15  发布在  Java
关注(0)|答案(2)|浏览(105)

这是一个链接到我的Java项目:https://github.com/Mundanest/Java-files/tree/main/Lab%207
(This这是我第一次使用github,因为我不知道如何链接java项目文件夹,所以我可能搞砸了)(代码也在底部)
它有四个类:

  • 一个用于打印,FindBestPhone.java
  • 一个用于创建Phone对象,Phone.java
  • 一个用于将电话添加到各种列表,PhoneList.java
  • 另一个用于解析文本,PhoneParser.java

主要目的是从“phone-data.txt”中的一长串电话中找到两个最好的电话。
(one手机具有最高的电池容量和另一个具有最大的屏幕尺寸)
我得到了一个示例文本文件“phone-data-short.txt”,其中最好的手机是三星Galaxy S8 Plus华为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());
}


但似乎什么都不管用
注意:我不确定它是否是最好的手机是如何计算的,因为这是提供给我的 backbone 代码。
(the 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对象类:

/*
 * 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;
    }

}


x1c 0d1x的数据
控制台打印:
[电话@2ed94a8b]
当我运行代码时。
我还做了一个发现,我做了一个测试文本文件,并填写了4个测试手机:



并在控制台上给出了这个:
[电话@38082d64,电话@dfd3711,电话@42d3bd8b]
出于某种原因,我只接了3个电话,而不是4个,这可能就是我的问题所在。

mf98qq94

mf98qq941#

对我来说,这是相当混乱.为什么不能最好的手机都有最大的屏幕尺寸和最大的电池容量以及?这是优先于一个手机从另一个手机对屏幕尺寸和电池容量?它不应该是可配置的(在某种程度上),以适应特定的需求?
尝试下面的小可运行代码(阅读代码中的注解)。请确保使用numberOfBestPhonesToFindprecedence成员变量的值:

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;
    }
}

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

mklgxw1f

mklgxw1f2#

这行代码(在类PhoneParser的方法parse中)将始终返回“false”。

if (scanner.hasNextDouble() && scanner.hasNextInt()) {

字符串
您需要将其设置为嵌套的if,即

if (scanner.hasNextDouble()) {
    double screenSize = scanner.nextDouble();
    if (scanner.hasNextInt()) {
        int batteryCapacity = scanner.nextInt();
        return new Phone(model, screenSize, batteryCapacity);
    }
}


最初,bestPhones(在类PhoneList中)是空的。因此,文件“phone-data.txt”的第一行必须添加到bestPhones,因为没有其他手机可以比较,因此它必须是“最佳手机”。您的代码不处理这种情况。
方法dominates(在类Phone中)没有实现方法注解中所述的条件。它应该是:

return (this.getScreenSize() > other.getScreenSize()  &&  getBatteryCapacity() >= other.getBatteryCapacity()) ||
       (this.getBatteryCapacity() > other.getBatteryCapacity()  &&  getScreenSize() >= other.getScreenSize());


为了完整起见,这里是所有四个类的代码,包括上面描述的更改。
Phone

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()  &&  getBatteryCapacity() >= other.getBatteryCapacity()) ||
               (this.getBatteryCapacity() > other.getBatteryCapacity()  &&  getScreenSize() >= other.getScreenSize());
    }
}


PhoneLIst

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);
        if (bestPhones.isEmpty()) {
            bestPhones.add(phone);
        }
        else {

            // 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

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()) {
                    double screenSize = scanner.nextDouble();
                    if (scanner.hasNextInt()) {
                        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 phoneList = 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) {
                    phoneList.addPhone(phone);
                }
            }
        }
        return phoneList;
    }
}


FindBestPhones

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) {
        try {
            PhoneList phoneList = PhoneParser.parseFile(PHONES_FILE);

            // Get the best phones from the phone list
            Collection<Phone> bestPhones = phoneList.getBestPhones();

            // Print the model names of the best phones
            System.out.println("Best Phones:");
            for (Phone phone : bestPhones) {
                System.out.println(phone.getModel());
            }
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }
}


这是我得到的输出:

Best Phones:
Oukitel K10
Xiaomi Mi Max 2 64GB
Doogee BL12000
Asus ZenFone 3 Ultra ZU680KL (4GB RAM), 64GB

相关问题