Trouble Sorting an array list - java

Is there a better way to sort this, to get the correct order? Thanks
import java.io.*;
import java.util.*;
public class JpgDirToHtm
{
public static void main(String[] args) throws FileNotFoundException
{
Scanner kb = new Scanner(System.in);
System.out.print("Enter the path of the folder whose contents you wish to insert into an html file: ");
String path = kb.nextLine();
File folder = new File(path);
File[] listOfFiles = folder.listFiles();
ArrayList<String> htmlTextList = new ArrayList<String>();
for (int i = 0; i < listOfFiles.length; i++)
{
if (listOfFiles[i].isFile())
{
htmlTextList.add(listOfFiles[i].getName() );
}
}
Collections.sort(htmlTextList);
System.out.println(htmlTextList);
}
}
This is what it prints
[1.jpeg, 10.jpg, 11.jpeg, 12.jpeg, 13.jpeg, 14.jpeg, 16.jpg, 17.jpg, 18.jpg, 19.jpg, 2.jpeg, 20.jpg, 21.jpg, 22.jpg, 23.jpg, 24.jpg, 25.jpg, 3.jpg, 5.jpg, 7.jpeg, 9.jpg]
I need 2.jpeg to come after 1.jpeg et cetera.
Sorry, there is probably a simple fix but I haven't found anything on google. I am new to programming.
Everything else works really well. The whole program can take thousands of photos and automatically place them, sized correctly, in html web pages at a given number of photos per page that you can set. If any one is interested in having the rest of the code I will post it.

Write your own comparator:
Collections.sort(list, new Comparator<String>() {
#Override
public int compare(String o1, String o2) {
String filename1 =o1.substring(0,o1.indexOf("."));
String filename2 =o2.substring(0,o2.indexOf("."));
return Integer.valueOf(filename1).compareTo(Integer.valueOf(filename2));
}
});
This will convert the filename to an integer and compare it.
But take care, it only works if your filenames are numbers!

You would have to write your own comparator and take care of the scenario of the flie starting with a number or a string:
public class JpgDirToHtm
{
public static void main(String[] args) throws FileNotFoundException
{
Scanner kb = new Scanner(System.in);
System.out.print("Enter the path of the folder whose contents you wish to insert into an html file: ");
String path = kb.nextLine();
File folder = new File(path);
File[] listOfFiles = folder.listFiles();
ArrayList<String> htmlTextList = new ArrayList<String>();
for (int i = 0; i < listOfFiles.length; i++)
{
if (listOfFiles[i].isFile())
{
htmlTextList.add(listOfFiles[i].getName() );
}
}
Collections.sort(htmlTextList, new Sortbyname());
System.out.println(htmlTextList);
}
}
class Sortbyname implements Comparator<String>
{
// Used for sorting in ascending order of
// roll name
public int compare(String a, String b)
{
String tempA = a.split("\\.")[0];
String tempB = b.split("\\.")[0];
try
{
return Integer.parseInt(tempA)-Integer.parseInt(tempB);
}
catch (Exception e)
{
return a.compareTo(b);
}
}
}
The code catches any exceptions with formatting the number and just falls back to String compare.

Related

Read integers from file and save two integers per index in a ArrayList

I have research about what I am trying to accomplish. This is my code, and here the main function is to read a file.txt which has integers separated by white spaces and they will be read one by one. However, I want to know... How Can I stored the integers inside a ArrayList, But in each index of the ArrayList there will be two integers instead of one, as usual?
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;
public class ReadFile {
public static void main(String[] args) {
int[] arr = readFile("address.txt");
System.out.println("The memory block generated is:");
System.out.println(Arrays.toString(arr));
}
// access this method in FIFO
public static int[] readFile(String file) { // this main method
try { // try and catch
File f = new File(file);
#SuppressWarnings("resource")
Scanner r = new Scanner(f); // read the file with scanner
int count = 0; // count for the integers
while(r.hasNextInt()) { // while keep reading
count++;
r.nextInt();
}
int[] array = new int[count];
#SuppressWarnings("resource")
Scanner readAgain = new Scanner(f); // read again
ArrayList<ArrayObjects> blockMem = new ArrayList<>(); // array size * we can use dynamic array
for(int i = 0; i < count; i++) {
// i want to iterate and save them
}
return array;
} catch(Exception fnf) {
System.out.println(fnf.getMessage() + "The file could not be open, try again");
System.exit(0);
}
return null;
} // method closed
}`
Create a new class with two integers.
class TwoIntegers{
int one,two;
TwoIntegers(int data1,int data2){
one = data1;
two = data2;
}
}
Now create an Arraylist of objects of type TwoIntegers
ArrayList<TwoIntegers> blockMem = new ArrayList<TwoIntegers>();
//now you can iterate and insert integers you need
blockMem.add(new TwoIntegers(1,2));
blockMem.add(new TwoIntegers(3,4));

Creating array from reading a file

I have a file with the following:
5
212:Float On:Modest Mouse
259:Cherub Rock:Smashing Pumpkins
512:Won't Get Fooled Again:The Who
417:Teen Age Riot:Sonic Youth
299:PDA:Interpol
I need to create a array but I need to take into account the integer it starts with, then read the rest as strings taking into account the initial line containing only an integer. I've made the method to read the file and print, just don't know how to split it up.
An example of how to do it:
String s = "212:Float On:Modest Mouse"; // your input - a line from the file
String[] arr = s.split(":");
System.out.println(arr[0]); // your int
// The rest of the array elements will be the remaining text.
// You can concatenate them back into one string if necessary.
you can read file using Scanner
readlines = new Scanner(filename);
while(readlines.hasNextLine())
{
String line = readlines.nextLine();
String[] values = line.split(":");
int firstColumn = -1;
if (values.length > 0) {
try {
firstColumn = Integer.parseInt(values[0]);
} catch (NumberFormatException ex) {
// the value in the first column is not an integer
}
}
}
I've grown a habit of reading the entire file into a List, then handling the List in memory. Doing this is not the only option.
Once I have the file read in, I look at the first line to know how many tracks to expect in the remaining file. I then would loop through the remaining List to either get the number of tracks from the first line or until I reach the end of the list, in the event that the number of tracks (from the first line) exceeds the actual amount of tracks that are in the file.
As I go through the tracks I would use substring to break the line apart, and convert just the first part.
Update
Base on your comment, I've updated to use split instead of substring. Then some basic alignment formatting for output
public static void main(String[] args) throws Exception {
String yourFile = "path to your file.txt";
List<String> yourFileLines = new ArrayList<>(Files.readAllLines(Paths.get(yourFile)));
// You know the first line is suppose to be the number of tracks so convert it to a number
int numberOfTracks = Integer.valueOf(yourFileLines.get(0));
// Either go to the number of tracks or till the end of file
List<Track> tracks = new ArrayList<>();
for (int i = 1; (i <= numberOfTracks && i < yourFileLines.size()); i++) {
String currentFileLine = yourFileLines.get(i);
String[] currentFileLinePieces = currentFileLine.split(":");
Track currentTrack = new Track();
currentTrack.TrackTime = Integer.valueOf(currentFileLinePieces[0]);
currentTrack.TrackTitle = currentFileLinePieces[1];
currentTrack.TrackArtist = currentFileLinePieces[2];
tracks.add(currentTrack);
}
System.out.println(String.format("%-20s\t\t%-20s\t\t%-20s", "TITLE", "ARTIST", "TIME"));
System.out.println(String.format("%-20s\t\t%-20s\t\t%-20s", "-----", "------", "----"));
for (Track currentTrack : tracks) {
System.out.println(currentTrack);
}
}
public static class Track {
public int TrackTime;
public String TrackTitle;
public String TrackArtist;
#Override
public String toString() {
return String.format("%-20s\t\t%-20s\t\t%-20d", TrackTitle, TrackArtist, TrackTime);
}
}
Results:
Here's an example using a Scanner, and breaking everything into methods. You should be able to use List and ArrayList. Results are the same.
public static void main(String[] args) throws Exception {
String yourFile = "data.txt";
List<String> yourFileLines = readFile(yourFile);
if (yourFileLines.size() > 0) {
// You know the first line is suppose to be the number of tracks so convert it to a number
int numberOfTracks = Integer.valueOf(yourFileLines.get(0));
List<Track> tracks = getTracks(numberOfTracks, yourFileLines);
printTracks(tracks);
}
}
public static List<String> readFile(String pathToYourFile) {
List<String> yourFileLines = new ArrayList();
try {
File yourFile = new File(pathToYourFile);
Scanner inputFile = new Scanner(yourFile);
while(inputFile.hasNext()) {
yourFileLines.add(inputFile.nextLine().trim());
}
} catch (Exception e) {
System.out.println(e);
}
return yourFileLines;
}
public static List<Track> getTracks(int numberOfTracks, List<String> yourFileLines) {
List<Track> tracks = new ArrayList();
// Either go to the number of tracks or till the end of file
for (int i = 1; (i <= numberOfTracks && i < yourFileLines.size()); i++) {
String currentFileLine = yourFileLines.get(i);
String[] currentFileLinePieces = currentFileLine.split(":");
Track currentTrack = new Track();
currentTrack.TrackTime = Integer.valueOf(currentFileLinePieces[0]);
currentTrack.TrackTitle = currentFileLinePieces[1];
currentTrack.TrackArtist = currentFileLinePieces[2];
tracks.add(currentTrack);
}
return tracks;
}
public static void printTracks(List<Track> tracks) {
System.out.println(String.format("%-20s\t\t%-20s\t\t%-20s", "TITLE", "ARTIST", "TIME"));
System.out.println(String.format("%-20s\t\t%-20s\t\t%-20s", "-----", "------", "----"));
for (Track currentTrack : tracks) {
System.out.println(currentTrack);
}
}
public static class Track {
public int TrackTime;
public String TrackTitle;
public String TrackArtist;
#Override
public String toString() {
return String.format("%-20s\t\t%-20s\t\t%-20d", TrackTitle, TrackArtist, TrackTime);
}
}

Method in another Class not returning anything

I'm working on a project that creates a Hangman game. The GameManager Class should call the getRandomAnswer method from the AnswerBank Class, which should return a random answer of two nouns from a file called noun_noun.txt (I've placed this file in the first level of the project folder). However, whenever I try to test the code, the console produces nothing after typing "yes" when prompted. Can anyone help?
public class GameManager {
private ArrayList<String> puzzleHistory;
private int numPuzzlesSolved;
private AnswerBank bank;
public GameManager(String fn) throws IOException{
numPuzzlesSolved = 0;
puzzleHistory = new ArrayList<String>();
this.bank = new AnswerBank(fn);
}
public static void main(String[] args) throws IOException {
GameManager obj = new GameManager("noun_noun.txt");
obj.run();
}
public void run() throws FileNotFoundException{
Scanner scan = new Scanner(System.in);
System.out.println("Would you like to play Hangman? Please type 'yes' or 'no'.");
String inputAns = scan.next();
if(inputAns.equalsIgnoreCase("no")){
System.exit(0);
}
else if(inputAns.equalsIgnoreCase("yes")){
System.out.println(bank.getRandomAnswer());
}
else{
System.out.println("Invalid response!");
}
scan.close();
}
}
public class AnswerBank {
private ArrayList<String> listStrings;
private File gameFile;
public AnswerBank(String fileName) throws IOException{
File gameFile = new File(fileName);
this.gameFile = gameFile;
this.listStrings = new ArrayList<String>();
}
public String getRandomAnswer() throws FileNotFoundException{
Scanner fileScan = new Scanner(gameFile);
int totalLines = 0;
while(fileScan.hasNextLine()){
totalLines++;
}
for(int i = 0; i < totalLines; i++){
this.listStrings.add(fileScan.nextLine());
}
int randInt = (int)(Math.floor ( Math.random() * totalLines));
String randAns = listStrings.get(randInt);
fileScan.close();
return randAns;
}
}
puzzleHistory and numPuzzlesSolved will be used later, so please ignore those. Thanks in advance for any help.
The problem is at here:
while (fileScan.hasNextLine()) {
totalLines++;
}
You file scanner never move position in the file, so it will keep scan the first line, and since first line is not empty, this is an infinite loop here.
A simple fix here is to count while reading words at the same time:
public String getRandomAnswer() throws FileNotFoundException {
Scanner fileScan = new Scanner(gameFile);
int totalLines = 0;
while (fileScan.hasNext()) {
totalLines++;
this.listStrings.add(fileScan.nextLine());
}
int randInt = (int) (Math.floor(Math.random() * totalLines));
String randAns = listStrings.get(randInt);
fileScan.close();
return randAns;
}
Hope it helps.

Unknown Issue with Word Percentage program

I've been working on an assignment for quite sometime now. The program compiles fine, but when ran, the driver class does not produce any results. The program I'm writing extends another class and is used to find the average word length of a text file as well as how often words with one letter, two letters, three letters, etc appear (any word that is 15 or greater letters is grouped).
Here is the class of which mine extends:
public abstract class FileAccessor{
String fileName;
Scanner scan;
public FileAccessor(String f) throws IOException{
fileName = f;
scan = new Scanner(new FileReader(fileName));
}
public void processFile() {
while(scan.hasNext()){
processLine(scan.nextLine());
}
scan.close();
}
protected abstract void processLine(String line);
public void writeToFile(String data, String fileName) throws IOException{
PrintWriter pw = new PrintWriter(fileName);
pw.print(data);
pw.close();
}
}
Here is my work:
import java.util.Scanner;
import java.io.*;
public class WordPercentages extends FileAccessor{
int[] length1 = new int[15];
double[] percentages = new double[15];
int totalWords = 0;
double average = 0.0;
public WordPercentages(String s)throws IOException{
super(s);
}
public void processLine(String file){
super.fileName=file;
while(super.scan.hasNext()){
totalWords+=1;
String s = super.scan.next();
if (s.length() < 15){
length1[s.length()]+=1;
}
else if(s.length() >= 15){
length1[15]+=1;
}
}
}
public double[] getWordPercentages(){
for(int j = 1; j < percentages.length; j++){
percentages[j] += length1[j];
percentages[j]=(percentages[j]/totalWords)*100;
}
return percentages;
}
public double getAvgWordLength(){
for(int j = 1; j<(percentages.length); j++){
average+=((j*(percentages[j])/totalWords));
}
return average;
}
}
And here is the driver class:
import java.util.Scanner;
import java.io.IOException;
public class WordPercentagesDriver{
public static void main(String[] args) throws IOException{
try{
String fileName;
Scanner scan = new Scanner(System.in);
System.out.println("Enter a text file name to analyze:");
fileName = scan.nextLine();
System.out.println("Analyzed text: " + fileName);
WordPercentages wp = new WordPercentages(fileName);
wp.processFile();
double [] results = wp.getWordPercentages();
printWordSizePercentages(results);
System.out.printf("average word length: %4.2f",wp.getAvgWordLength());
}
catch(Exception e)
{
System.out.println(e);
}
}
public static void printWordSizePercentages(double[] data){
for(int i = 1; i < data.length; i++)
if (i==data.length-1)
System.out.printf("words of length " + (i) + " or greater: %4.2f%%\n",data[i]);
else
System.out.printf("words of length " + (i) + ": %4.2f%%\n",data[i]);
}
}
I've tried placing a text file with known results in the same folder, everything complies, I then type in the name of the text file (including the .txt) and unfortunately nothing happens. Any help would be greatly appreciated.
NOTE: The FileAccessor Class and the Driver class were both provided by my instructor, so any source of error would come from the WordPercentage class.
Just ran the code, It looks like your code is throwing a "FileNotFoundExeption". What you have to do to fix this is place the file that you are looking for into the workspace you are working in. You can either save the txt file into your workspace or specify where the txt file is located. Example: C:Programs/documents/Alice...
good luck!

Changing a String into an int

I have an array of string objects that was read from a file. Some of these strings I need to use as ints. I wrote a method to read the file but now I just don't know how to get the numbers from the file, here is the file
29,,
Chute,1,0
Chute,2,0
Chute,3,0
Chute,4,0
Chute,5,0
Chute,6,0
Chute,7,0
Chute,8,0
Chute,9,0
Chute,0,1
Chute,0,2
Chute,0,3
Chute,9,1
Chute,9,2
Chute,9,3
Ladder,0,5
Ladder,1,5
Ladder,2,5
Ladder,3,5
Ladder,4,5
Ladder,5,5
Ladder,6,5
Ladder,7,5
Ladder,8,5
Ladder,9,5
Ladder,9,6
here is my method
public void readBoard(String file)throws FileNotFoundException
{
File clboard = new File ("myBoard.csv");
Scanner x = new Scanner(clboard);
while(x.hasNext())
{
String c = x.nextLine();
String [] myboard =c.split(",");
}
}
Try
int numOne = Integer.parseInt(myboard[1]);
int numTwo = Integer.parseInt(myboard[2]);
immediately after your split line.
String [] myboard = c.split(",");
if (myboard.length < 3) {
// error message
} else {
int i1 = Integer.parseInt(myboard[1]);
int i2 = Integer.parseInt(myboard[2]);
}
You might also want to add a try/catch to handle NumberFormatException (which occurs when you try to convert something that isn't a number).
public void readBoard(String file)throws FileNotFoundException
{
File clboard = new File ("myBoard.csv");
Scanner x = new Scanner(clboard);
while(x.hasNext()) {
List<Integer> number = new ArrayList<Integer>();
String c = x.nextLine();
String [] myboard =c.split(",");
for (String candid8 : myboard) {
try {
number.add(Integer.parseInt(candid8));
} catch (NumberFormatException e) {
}
}
}
}
Your numbers will now be in the number object, which is a List. If it's a more complex grammar, look into jflex, as that seems to be the recommendation of Google.

Categories