Applied Programming/Lists and Tuples/Java

lists.java

edit
/**
 * This program demonstrates file and list processing.
 * 
 * It creates a temporary file, adds data to the file, and reads the file
 * into a list of lists. It then provides a menu of options for displaying 
 * and searching the file data.
 * 
 * It will not run if the file already exists.
 * 
 * Input:
 *     None
 * 
 * Output:
 *     A temporary file and file contents.
 * 
 * References:
 *     https://www.tutorialspoint.com/java/java_list_interface.htm
 *     https://www.tutorialspoint.com/java/java_builtin_exceptions.htm
 *     https://www.tutorialspoint.com/javaexamples/string_compare.htm
 */

import java.util.*;

/**
 * Runs main program logic.
 */
class Main {
    public static void main(String[] args) {
        String FILENAME = "~file.txt";
    
        if(fileExists(FILENAME)) {
            System.out.println("File already exists.\n");
            System.exit(1);
        }

        createFile(FILENAME);
        List temperatures = readFile(FILENAME);
        deleteFile(FILENAME);
        
        while (true) {
            int choice = getChoice();
            switch (choice) {
                case 1:
                    displayTemperatures(temperatures, "Celsius");
                    break;
                case 2:
                    displayTemperatures(temperatures, "Fahrenheit");
                    break;
                case 3:
                    searchTemperatures(temperatures, "Celsius");
                    break;
                case 4:
                    searchTemperatures(temperatures, "Fahrenheit");
                    break;
                default:
                    throw new RuntimeException(
                        "Invalid option selected");
            }
        }
    }
    
    /**
     * Creates filename and adds temperature data to the file.
     * 
     * @param filename
     * 
     * Catches IOException and terminates the program.
    */
    private static void createFile(String filename) {
        try {
            java.io.File file = new java.io.File(filename);
            java.io.BufferedWriter writer = 
                new java.io.BufferedWriter(new java.io.FileWriter(file));
            float c;
            float f;
            
            writer.write("C,F\n");
            for(c = 0; c <= 100; c += 10) {
                f = c * 9 / 5 + 32;
                writer.write(c + "," + f + "\n");
            }
            writer.close();
        }
        catch(java.io.IOException e) {
            e.printStackTrace();
            System.exit(2);
        }
    }
    
    /**
     * Reads filename and displays each line.
     * 
     * @param filename
     * @return temperatures
     * 
     * Catches IOException and terminates the program.
    */
    private static List readFile(String filename) {
        try {
            java.io.File file = new java.io.File(filename);
            java.io.BufferedReader reader = 
                new java.io.BufferedReader(new java.io.FileReader(file));
            String line;

            line = reader.readLine();
            if (!line.trim().equals("C,F")) {
                throw new RuntimeException(
                    "Invalid header format found in " +
                    filename + ": " + line);
            }

            List temperatures = new ArrayList();
            while(true) {
                line = reader.readLine();
                if (line == null) {
                    break;
                }
                
                String fields[] = line.trim().split(",");
                if (fields.length != 2) {
                    throw new RuntimeException(
                        "Invalid record format found in " +
                        filename + ": " + line);
                }
                
                List record = new ArrayList();
                record.add(Float.parseFloat(fields[0]));
                record.add(Float.parseFloat(fields[1]));
                temperatures.add(record);
            }
            reader.close();
            
            if (temperatures.size() == 0) {
                throw new RuntimeException(
                    "No data found in " +
                    filename);
            }
            
            return temperatures;
        }
        catch(java.io.IOException e) {
            e.printStackTrace();
            System.exit(3);
            return null;
        }
    }
    
    /**
     * Deletes filename.
     * 
     * @param filename
    */
    private static void deleteFile(String filename) {
        java.io.File file;
        
        file = new java.io.File(filename);
        file.delete();        
    }
    
    /**
     * Determines whether or not filename exists.
     * 
     * @param filename
     * 
     * @return true or false
    */
    private static boolean fileExists(String filename) {
        java.io.File file;
        
        file = new java.io.File(filename);
        return file.exists();
    }
    
    /**
     * Displays menu and gets choice.
     * 
     * @return choice
     * 
     * Exits:
     *      If no choice is entered.
    */
    private static int getChoice() {
        Scanner scanner = new Scanner(System.in);
        String text = "";
        while (true) {
            try {
                System.out.println("Select from the following options or press <Enter> to quit:");
                System.out.println("1. Display table sorted by Celsius temperature.");
                System.out.println("2. Display table sorted by Fahrenheit temperature.");
                System.out.println("3. Search for Celsius temperature.");
                System.out.println("4. Search for Fahrenheit temperature.");
                text = scanner.nextLine();
                if (text.isEmpty()) {
                    System.exit(0);
                }
                int choice = Integer.parseInt(text);
                if (choice >= 1 && choice <= 4) {
                    System.out.println();
                    return choice;
                }
                System.out.println(text + " is not a valid choice.\n");
            }
            catch (NumberFormatException exception) {
                System.out.println(text + " is not a valid choice.\n");
            }
        }
    }

    /**
     * Sorts temperature list in ascending order by the given element.
     * 
     * @param temperatures
     * @param element
     * @return temperatures
    */
    private static void sortTemperatures(List temperatures, int element)
    {
        Collections.sort(temperatures, new Comparator<List>() {
            @Override
            public int compare(List l1, List l2) {
                Float f1 = (Float)l1.get(element);
                Float f2 = (Float)l2.get(element);
                if (f1 > f2) {
                    return 1;
                }
                else {
                    return -1;
                }
            }
        });
    }

    /**
     * Displays temperatures sorted in scale order.
     * 
     * @param  temperatures
     * @param  scale
     * @throws IllegalArgumentException if scale is invalid
    */
    private static void displayTemperatures(List temperatures, String scale) {
        int first_column = 0;
        int second_column = 1;
        
        if (scale == "Celsius") {
            sortTemperatures(temperatures, 0);
            System.out.println("C\tF");
        }
        else if (scale == "Fahrenheit") {
            sortTemperatures(temperatures, 1);
            System.out.println("F\tC");
            first_column = 1;
            second_column = 0;
        }
        else {
            throw new IllegalArgumentException("scale must be Celsius or Fahrenheit");
        }
        
        for(int i = 0; i < temperatures.size(); i++){
            List record = (List)temperatures.get(i);
            System.out.println(record.get(first_column) + "\t" + record.get(second_column));
        }
        System.out.println();
    }

    /**
     * Gets Fahrenheit or Celsius temperature.
     * 
     * @param  scale
     * @return temperature
     * @throws IllegalArgumentException if no temperature is entered.
    */
    private static float getTemperature(String scale) {
        assert scale == "Fahrenheit" || scale == "Celsius";
        Scanner scanner = new Scanner(System.in);
        while (true) {
            System.out.println("Enter " + scale + " temperature:");
            String text = scanner.nextLine();
            if (text.isEmpty()) {
                throw new IllegalArgumentException("No temperature entered");
            }
            try {
                float temperature = Float.parseFloat(text);
                System.out.println();
                return temperature;
            }
            catch (NumberFormatException exception) {
                System.out.println(text + " is not a valid " + scale + " temperature\n");
            }
        }
    }
    
    /**
     * Search temperatures for a scale temperature and display the nearest match.
     * 
     * @param  temperatures
     * @param  scale
     * @throws IllegalArgumentException if scale is invalid
    */
    private static void searchTemperatures(List temperatures, String scale) {
        float temperature = 0;
        int searchElement = 0;
        int displayElement = 1;
        String otherScale = "Fahrenheit";
        
        try {
            temperature = getTemperature(scale);
        }
        catch (Exception exception) {
            return;
        }
        
        if (scale == "Celsius") {
            // Use default values
        }
        else if (scale == "Fahrenheit") {
            searchElement = 1;
            displayElement = 0;
            otherScale = "Celsius";
        }
        else {
            throw new IllegalArgumentException("scale must be Celsius or Fahrenheit");
        }
        
        sortTemperatures(temperatures, searchElement);
        List last = (List)temperatures.get(0);
        List record = null;
        for(int i = 0; i < temperatures.size(); i++){
            record = (List)temperatures.get(i);
            if (temperature < (Float)record.get(searchElement))
            {
                break;
            }
            last = record;
        }
        
        if (temperature < (Float)last.get(searchElement)) {
            System.out.println(String.format(
                "%.1f° %s is less than %.1f° %s\n",
                temperature,
                scale,
                last.get(displayElement),
                otherScale));
        }        
        else if (temperature == (Float)last.get(searchElement)) {
            System.out.println(String.format(
                "%.1f° %s is %.1f° %s\n",
                temperature,
                scale,
                last.get(displayElement),
                otherScale));
        }        
        else if (temperature > (Float)record.get(searchElement)) {
            System.out.println(String.format(
                "%.1f° %s is greater than %.1f° %s\n",
                temperature,
                scale,
                last.get(displayElement),
                otherScale));
        }
        else {
            System.out.println(String.format(
                "%.1f° %s is between %.1f° %s and %.1f %s\n",
                temperature,
                scale,
                last.get(displayElement),
                otherScale,
                record.get(displayElement),
                otherScale));
        }
    }
}

Try It

edit

Copy and paste the code above into one of the following free online development environments or use your own Java compiler / interpreter / IDE.

See Also

edit