The title might be a little misleading but I am writing a piece of code that has this as the contents of the text file:
04/26/16 Sega 3D Classics Collection
07/14/16 Batman: Arkham Underworld
06/24/16 Tokyo Mirage Sessions #FE
Essentially I want them to be in alphabetical order and it should make a brand new file that looks like this:
Batman: Arkham Underworld
Sega 3D Classics Collection
Tokyo Mirage Sessions #FE
What I have tried is to use the indexOf() method to extract only the names of the list of games from my existing text file. I have also tried to store them in a new array to avoid confusion for the computer. The problem is that when I try to store the indexOf of the info array into a new array, the line gives an error of "cannot convert from int to string" and I am not sure on how to fix the error.
This is my code below:
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Scanner;
public class Main{
public static void main (String[]args) throws IOException{
File file = new File("releasedates.txt");
String []arr = input(file);
output(file,arr);
outputSort1(file, arr);
}
public static String[]input (File file) throws FileNotFoundException{
String[]arr = new String[3];
Scanner sc = new Scanner(file);
for(int i = 0; i < arr.length; i++){
arr[i] = sc.nextLine();
}
return arr;
}
public static void output(File file, String[] info) throws IOException{
FileWriter writer = new FileWriter("fileName.txt");
for(String aString:info){
writer.write(aString);
}
writer.close();
}
public static void sortByMonth(String[]info){
String temp;
for (int j = 0; j < info.length; j++) {
for (int i = j + 1; i < info.length; i++) {
if (info[i].compareTo(info[j]) < 0) {
temp = info[j];
info[j] = info[i];
info[i] = temp;
}
}
}
}
public static void outputSort1(File file,String[] info) throws IOException{
sortByMonth(info);
FileWriter writer = new FileWriter("fileNameSorted1.txt");
for(String aString:info){
writer.write(aString);
}
writer.close();
}
public static void sortByName(String[]info){
String[] names = new String[3];
for(int i = 0; i < info.length; i ++){
names[i] = info[i].indexOf(" " ,info.length);
}
String temp;
for (int j = 0; j < names.length; j++) {
for (int i = j + 1; i < names.length; i++) {
if (names[i].compareTo(names[j]) < 0) {
temp = names[j];
names[j] = names[i];
names[i] = temp;
}
}
}
}
}
You've declared names array as String[] so you can't assign integer to it. indexOf method returns integer.
public static void sortByName(String[]info) {
String[] names = new String[3]; //<-- declaration suggests store string
for (int i = 0; i < info.length; i++) {
names[i] = info[i].indexOf(" ", info.length);//<-you are assigning integer
}
I think what you are trying to do is like this:
names[i] = info[i].substring(info[i].indexOf(" "), info[i].length());
Use java.nio APIs for file implementations as java.io apis are outdated. Also, if you use Stream operations then the implementation becomes much easier:
public class Test {
public static void main(String[] args) throws Exception {
Path file = Path.of("e:\\releasedates.txt");
List<String> records = Files.readAllLines(file);
List<String> sortedByName = records.stream()
.map(s -> s.substring(s.indexOf(" "), s.length()))
.sorted(String::compareTo)
.collect(Collectors.toList());
System.out.println(sortedByName);
Files.write(Path.of("e:\\fileNameSorted.txt"), sortedByName);
List<String> sortedByDate = records.stream().sorted(Test::compareDates)
.map(s -> s.substring(s.indexOf(" "), s.length()))
.collect(Collectors.toList());
System.out.println(sortedByDate);
Files.write(Path.of("e:\\fileDateSorted.txt"), sortedByDate);
}
public static int compareDates(String d1, String d2) {
d1 = d1.substring(0, d1.indexOf(" "));
d2 = d2.substring(0, d2.indexOf(" "));
LocalDate ld1 = LocalDate.parse(d1,
DateTimeFormatter.ofPattern("MM/dd/yy"));
LocalDate ld2 = LocalDate.parse(d2,
DateTimeFormatter.ofPattern("MM/dd/yy"));
return ld1.compareTo(ld2);
}
}
Answer by #onkar ruikar is correct. indexOf returns int and you are trying to store it in String. I would like to extend his answer, where you can store the game/movie names in TreeSet instead of Array, so that by default it will be sorted in alphabetical order.
If you want to allow duplicate game/movie names, then you can use ArrayList and call Collections.sort(<array list>) method, which will sort the ArrayList in alphabetical order.
Here is the detailed answer of how can we sort Collections in Java: https://stackoverflow.com/a/8725470/3709922
Related
Using ReadInputCSVFromFile method to read the sample CSV from file and parse it to a String array after using split(",") function and pass it to a 2D array to read it fully.
PrintResultsForTesting method would be only for printing out the 2D array for visual overlook.
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.Scanner;
public class CSVReader {
public static String[][] readIntoArray;
public static String[][] myArray;
public static String[][] csvResults;
public static int countRow = 0;
public static int countColumn = 0;
public static void main(String[] args) {
csvResults = ReadInputCSVFromFile(myArray);
PrintResultsForTesting(csvResults);
}
public static void PrintResultsForTesting(String[][] csvResults) {
String[][] newMyArray = new String[myArray.length][myArray[0].length];
for (int i = 0; i < csvResults.length; ++i) {
for (int j = 0; j < csvResults[0].length; ++j) {
System.out.println(csvResults[i][j]);
}
}
}
public static String[][] ReadInputCSVFromFile(String[][] myArray) {
countRow = 0;
countColumn = 0;
Scanner scanner;
String inputLine;
String fileLocation;
fileLocation = "D://WorkSpace_Git//methods//iq-distribution//docs/SAP.csv";
try {
scanner = new Scanner(new BufferedReader(new FileReader(fileLocation)));
while (scanner.hasNext()) {
inputLine = scanner.nextLine();
String[] readIntoArray = inputLine.split(",");
// count rows and columns
++countRow;
countColumn = readIntoArray.length;
myArray = new String[countRow][countColumn];
}
for (int i = 0; i < countRow; ++i) {
for (int j = 0; j < countColumn; ++j) {
myArray[i][j] = readIntoArray[i][j];
}
}
System.out.println("Rows: " + countRow + '\n' + "Columns: " + countColumn);
scanner.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return myArray;
}
}
The error is:
Exception in thread "main" java.lang.NullPointerException at project.CSVReader.ReadInputCSVFromFile(CSVReader.java:52) at project.CSVReader.main(CSVReader.java:16) Process finished with exit code 1
After looking briefly at your code, I could spot a bug. When this method is called:
public static String[][] ReadInputCSVFromFile(String[][] myArray) {
myArray is null.
If you want to write to the array, you will need to instantiate the array first.
If you are using arrays actually you should know in advance its dimensions. If you do not know it, consider using some implementation of java.util.List - like java.util.ArrayList.
Another problem is exception handling. If the file is not found, then the exception is caught and you still call this method PrintResultsForTesting with unpredicatable results. Better to use a throws clause and stop the execution alltogether. So instead of the try catch in method ReadInputCSVFromFile just use a throws FileNotFoundException in this method.
package com.cp.javapractice;
import java.util.ArrayList;
import java.util.Scanner;
public class Cp {
public static void main(String args[]) {
ArrayList al = new ArrayList();
Scanner s = new Scanner(System.in);
String str = null;
str = new String();
System.out.println("Enter the string which you want to remove the duplicates");
str = s.nextLine();
String arr[] = str.split(" ");
for (int k = 0; k < arr.length; k++) {
al.add(arr[k]);
}
try {
for (int i = 0; i < arr.length; i++) {
for (int j = i + 1; j < arr.length; j++) {
if (arr[i].equalsIgnoreCase(arr[j])) {
al.remove(j);
}
}
}
System.out.println(al);
}
catch (Exception e) {
System.out.println(e);
}
}
}
I am going to replace the repeating words in particular given string from the user. So, I split the given string with space using split method and put in array as well as in arraylist.
After Iterate through array and checked the condition it is equal then I removed that in ArrayList. But While removing it shows Index out of bound Exception.
This code is working for small array size but shows exception while giving large number of array size.
I am having problem while I am giving the string with array size of 13 words.
Here is my full code.
for (int i = 0; i < al.size(); i++) {
for (int j = i + 1; j < al.size(); j++) {
if (al.get(i).equals(al.get(j)) {
al.remove(j);
}
}
}
The exception is because you are using arr.length instead of al.size(). For every removal, the size of the arraylist al decreases. So, you have to consider using size of arraylist instead of size of the array.
for (int i = 0; i < al.size(); i++) { // change arr.length to al.size()
for (int j = i + 1; j < al.size(); j++) { // change arr.length to al.size()
if (arr[i].equalsIgnoreCase(arr[j])) {
al.remove(j);
}
}
}
I would recommend you to check out HashSet and TreeSet which reduces your effort of removing duplicates.
Implementing in HashSet:
import java.util.Arrays;
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;
public class Cp {
public static void main(String args[]) {
Scanner s = new Scanner(System.in);
String str = null;
str = new String();
System.out.println("Enter the string which you want to remove the duplicates");
str = s.nextLine();
String arr[] = str.split(" ");
Set<String> ts = new HashSet<String>(Arrays.asList(arr)); // -> added only this line
System.out.println(ts);
}
}
The Problem is your 2nd loop. Is Starts at i+1. But i is from 0 to length -1. So the Last ein will be j=length-1+1 which is beyond Array length.
So Change the 1st for loop to:
for(int i=0;i < arr.length-2;i++)
I have two array lists like shown below,
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.*;
class Reader {
public static void main(String args[]) throws FileNotFoundException {
ArrayList<String> animal = new ArrayList<>();
animal.add("Dog");
animal.add("Cat");
animal.add("Mouse");
ArrayList<Integer> numbers = new ArrayList<>();
for (int i = 1; i <= 15; i++) {
numbers.add(i);
}
PrintWriter writer = new PrintWriter("animals.csv");
for (String ani : animal) {
writer.println(ani + ",");
}
writer.close();
}
}
I want the output to be like this in the .csv file.
Dog,1,2,3,4,5,
Cat,6,7,8,9,10,
Mouse,11,12,13,14,15,
When I use for-loops, the output of the array lists gets printed one below the other in the .csv file.
How do I format the array lists the way I desired, so it looks like this in Excel?
use writer.print() instead of writer.println()
Notice 'ln' in the method name you are using, which means print line.
Update: To also add numbers along with animal:
public static void main(final String[] args) throws FileNotFoundException {
ArrayList<String> animal = new ArrayList<>();
animal.add("Dog");
animal.add("Cat");
animal.add("Mouse");
ArrayList<Integer> numbers = new ArrayList<>();
for (int i = 1; i <= 15; i++) {
numbers.add(i);
}
PrintWriter writer = new PrintWriter("animals.csv");
List<String> row = new ArrayList<>();
int i = 0;
for (String ani : animal) {
row.add(ani);
for (int j = 0; j < 5; j++) {
row.add(String.valueOf(numbers.get(i++)));
}
writer.println(String.join(",", row));
row.clear();
}
writer.close();
}
Your writer method is printing a line. You need to use just print.
So writer.println(ani + ","); becomes writer.print(ani + ",");
Also, to add numbers as you asked you can do this as an alternative. This works as you said you have only 5 elements in each row after animal name.
PrintWriter writer = new PrintWriter("animals.csv");
int rowCounter = 0;
for (String ani : animals) {
writer.print(ani);
for (int i = rowCounter * 5; i < (rowCounter * 5 + 5); i++) {
writer.print("," + numbers.get(i));
}
writer.println();
rowCounter++;
}
writer.close();
Consider the case of a list of strings
example : list=['apple','bat','cow,'dog','applebat','cowbat','dogbark','help']
The java code must check if any element of string is a subset of another element and if it is then larger string element must be removed.
so in this case strings 'applebat','cowbat','dogbark, are removed.
The approach I have taken was to take two lists and iterate over them in the following way,
ArrayList<String> list1 = new ArrayList<String>(strings);
ArrayList<String> list2 = new ArrayList<String>(strings);
for(int i = 0; i<list1.size();i++)
{
String curr1 = list1.get(i);
for(int j = 0;j<list2.size();j++)
{
String curr2 = list2.get(j);
if(curr2.contains(curr1)&&!curr2.equals(curr1))
{
list2.remove(j);
j--;
}
}
}
IMPORTANT I have lists with the sizes of 200K to 400K elements.I would like to find a way to improve performance. I even tried hashsets but they were not much help.I am facing issues with the time taken by the program.
Can any one suggest any improvements to my code or any other approaches in java to improve performance??
import java.util.ArrayList;
import java.util.*;
// our main class becomes a file but the main method is still found
public class HelloWorld
{
public static void main(String[] args)
{
String[] strings = {"apple","bat","cow","dog","applebat","cowbat","dogbark","help"};
ArrayList<String> list1 = new ArrayList<String>(Arrays.asList(strings));
ArrayList<String> list2 = new ArrayList<String>(Arrays.asList(strings));
ArrayList<String> result = new ArrayList<String>(Arrays.asList(strings));
for(int i = 0; i<8;i++)
{
String curr1 = list1.get(i);
System.out.println(curr1);
int flag = 0;
for(int j = i+1;j<8;j++)
{
String curr2 = list2.get(j);
if((curr2.contains(curr1)&&!curr2.equals(curr1)))
{
result.remove(curr2);
}
}
}
System.out.println(result);
}
}
For full performance boost of huge list of words, I would think a combination of sort and a string searching algorithm, such as the Aho–Corasick algorithm, is what you need, assuming you're willing to implement such complex logic.
First, sort the words by length.
Then build up the Aho–Corasick Dictionary, in word length order. For each word, first check if a substring exists in the dictionary. If it does, skip the word, otherwise add the word to the dictionary.
When done, dump the dictionary, or the parallel-maintained list if dictionary is not easy/possible to dump.
I suppose set will be faster here.
You can easy do that with java8 stream api.
Try that:
private Set<String> delete() {
Set<String> startSet = new HashSet<>(Arrays.asList("a", "b", "c", "d", "ab", "bc", "ce", "fg"));
Set<String> helperSet = new HashSet<>(startSet);
helperSet.forEach(s1 -> helperSet.forEach(s2 -> {
if (s2.contains(s1) && !s1.equals(s2)) {
startSet.remove(s2);
}
}));
return startSet;
}
Do not delete any elements from set you are iterating for or you will have ConcurrentModificationException.
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Random;
public class SubStrRmove {
public static List<String> randomList(int size) {
final String BASE = "abcdefghijklmnopqrstuvwxyz";
Random random = new Random();
List<String> list = new ArrayList<>();
for (int i = 0; i < size; i++) {
int length = random.nextInt(3) + 2;
StringBuffer sb = new StringBuffer();
for (int j = 0; j < length; j++) {
int number = random.nextInt(BASE.length());
sb.append(BASE.charAt(number));
}
list.add(sb.toString());
sb.delete(0, sb.length());
}
return list;
}
public static List<String> removeListSubStr(List<String> args) {
String[] input = args.toArray(new String[args.size()]);
Arrays.parallelSort(input, (s1, s2) -> s1.length() - s2.length());
List<String> result = new ArrayList<>(args.size());
for (int i = 0; i < input.length; i++) {
String temp = input[i];
if (!result.stream().filter(s -> temp.indexOf(s) >= 0).findFirst().isPresent()) {
result.add(input[i]);
}
}
return result;
}
public static List<String> removeListSubStr2(List<String> args) {
String[] input = args.toArray(new String[args.size()]);
Arrays.parallelSort(input, (s1, s2) -> s1.length() - s2.length());
List<String> result = new ArrayList<>(args.size());
for (int i = 0; i < input.length; i++) {
boolean isDiff = true;
for (int j = 0; j < result.size(); j++) {
if (input[i].indexOf(result.get(j)) >= 0) {
isDiff = false;
break;
}
}
if (isDiff) {
result.add(input[i]);
}
}
return result;
}
public static void main(String[] args) throws InterruptedException {
List<String> list = randomList(20000);
Long start1 = new Date().getTime();
List<String> listLambda = removeListSubStr(list);
Long end1 = new Date().getTime();
Long start2 = new Date().getTime();
List<String> listFor = removeListSubStr2(list);
Long end2 = new Date().getTime();
System.out.println("mothod Labbda:" + (end1 - start1) + "ms");
System.out.println("mothod simple:" + (end2 - start2) + "ms");
System.out.println("" + listLambda.size() + listLambda);
System.out.println("" + listFor.size() + listFor);
}
}
I have tested it on small data and hope it helps you to find solution...
import java.util.ArrayList;
import java.util.Arrays;
public class Main {
public static void main(String[] args){
String []list = {"apple","bat","cow","dog","applebat","cowbat","dogbark","help","helpless","cows"};
System.out.println(Arrays.toString(list));
int prelenght = 0;
int prolenght = 0;
long pretime = System.nanoTime();
for(int i=0;i<list.length;i++){
String x = list[i];
prelenght = list[i].length();
for(int j=i+1;j<list.length;j++){
String y = list[j];
if(y.equals(x)){
list[j] = "0";
}else if(y.contains(x)||x.contains(y)){
prolenght = list[j].length();
if(prelenght<prolenght){
list[j] = "0";
}
if(prelenght>prolenght){
list[i] = "0";
break;
}
}
}
}
long protime = System.nanoTime();
long time = (protime - pretime);
System.out.println(time + "ns");
UpdateArray(list);
}
public static void UpdateArray(String[] list){
ArrayList<String> arrayList = new ArrayList<>();
for(int i=0;i<list.length;i++){
if(!list[i].equals("0")){
arrayList.add(list[i]);
}
}
System.out.println(arrayList.toString());
}
}
Output :
[apple, bat, cow, dog, applebat, cowbat, dogbark, help, helpless, cows]
time elapsed : 47393ns
[apple, bat, cow, dog, help]
so I'm trying to write a program that sorts the contents of a file typed in from the command line alphabetically. I'm having troubles with reading in the file and then copying it from an arrayList "myArrayList" to an array "myList" to be printed in my "main" here's my code:
import java.io.*;
import java.io.File ;
import java.util.*;
import java.util.Scanner ;
import java.io.FileNotFoundException ;
public class MergeSortLines {
public static void main(String[] args)
throws FileNotFoundException {
loadArray(args[0]) ;
}
public static String[] loadArray(String fileName)
throws FileNotFoundException {
String[] myList = null ;
ArrayList<String> myArrayList = new ArrayList<String>();
if ( (fileName != null) && (!fileName.equals("")) ) {
Scanner input = new Scanner(new File(fileName)) ;
while (input.hasNextLine()) {
String a = input.nextLine();
myArrayList.add(a);
}
myList = myArrayList.toArray(new String[] {});
System.out.println(Arrays.toString(myList));
}
return myList ;
}
public static void mergeSort(String[] a) {
if (a.length >= 2) {
String[] left = new String[a.length / 2];
String[] right = new String[a.length-a.length / 2];
for (int i = 0; i < left.length; i++)
{
left[i] = a[i];
}
for (int i = 0; i < right.length; i++)
{
right[i] = a[i + a.length / 2];
}
mergeSort(left);
mergeSort(right);
merge(a, left, right);
}
}
public static void merge(String[] result, String[] left, String[] right) {
int i1 = 0;
int i2 = 0;
for (int i = 0; i < result.length; i++) {
if (i2 >= right.length || (i1 < left.length &&
left[i1].compareToIgnoreCase(right[i2])<0)) {
result[i] = left[i1];
i1++;
} else {
result[i] = right[i2];
i2++;
}
}
}
}
it compiles correctly but I get a NoSuchElementException error code when I run it. My questions are, did I do the while loop correctly for the scanner? How do I utilize toArray() correctly? and finally, if I have the wrong idea, what is the correct way to copy the file to an array? Thanks I appreciate any help whatsoever!
EDIT
Thanks to HoverCraft Full of Eels, I got the contents of the file displaying properly, now it won't sort alphabetically when it worked with names I put in the code from when I started testing it! any ideas?
To answer my own question, I neglected to call the methods to execute them so that the mergeSort would sort my list properly