Modify existing line in file - Java [duplicate] - java

This question already has answers here:
Modify a .txt file in Java
(12 answers)
Closed 8 years ago.
I need some help or code examples to update an existing line.
File contents:
Heinrich: 30
George: 2020
Fred: 9090129
Say if I wanted to update (write) George's value to say 300, how would I achieve this?
EDIT: Or would it be better off just using YAML?
Thanks.

Here is a way to do it, try it. In this example the file is C:/user.txt and i change the value of George by 1234
public class George {
private static List<String> lines;
public static void main (String [] args) throws IOException{
File f = new File("C:/user.txt");
lines = Files.readAllLines(f.toPath(),Charset.defaultCharset());
changeValueOf("Georges", 1234); // the name and the value you want to modify
Files.write(f.toPath(), changeValueOf("George", 1234), Charset.defaultCharset());
}
private static List<String> changeValueOf(String username, int newVal){
List<String> newLines = new ArrayList<String>();
for(String line: lines){
if(line.contains(username)){
String [] vals = line.split(": ");
newLines.add(vals[0]+": "+String.valueOf(newVal));
}else{
newLines.add(line);
}
}
return newLines;
}
}
This is a working solution, but i think there is some other way more efficient.

Related

Get List of Integers from array of Strings

I would like to make my code look more efficient. Currently I got something like this:
private static String[] getAllFilesFromDirectory(String path) {
File file = new File(path);
String fileNamePattern = file.getName() + ".*\\.[0-9]*\\.GOOD";
File dir = new File(file.getParent());
String[] files = dir.list((currDir, currName) -> currName.matches(fileNamePattern));
return files;
}
private static List<Integer> getAllFileNumbers(String path) {
String[] files = getAllFilesFromDirectory(path);
List<Integer> fileNumbers = new ArrayList<>();
for (String currentFile : files) {
fileNumbers.add(extractFileNumber(currentFile));
}
return fileNumbers;
}
private static Integer extractFileNumber(String fileName) {
return Integer.parseInt(fileName.split("\\.")[2]);
}
First thing first. To getAllFileNumbers method I am passing path to directory, after that I am getting array of files in this directory with specific pattern. And from every file I need to extract number.
Example:
test.txt.1.fail
test2.txt.2.good
test3.pdf.1.good
Here I am returning list of following numbers : 1, 2, 1.
What I would like to change? Probably use stream api instead of foreach loop.
First idea was something like this:
Arrays.stream(files).map(this::extractFileNumber).collect(Collectors.toList());
But because the methods are static i cant use it like this.
Obviously I could move extractFileNumber inside of lambda but I would like to keep my method separately.
Maybe someone has other ideas, please feel free to post any ideas. Cheers!
Use stream api can make it shorter, suppose extractFileNumber is in class Main:
return Stream.of(files).map(Main::extractFileNumber).collect(Collectors.toList());

How to word count a set of files within a directory using Java 8 in lambda form [duplicate]

This question already has answers here:
Word count with java 8
(2 answers)
Improving the Java 8 way of finding the most common words in "War and Peace"
(2 answers)
Closed 5 years ago.
I'm working on a assignment in which the program reads a directory and gets the number of files in the directory. However, the program also has to perform a word count within each file. Moreover, the program must use Java 8 Streams and use Lambda syntax.
The questions:
How would you use to count the words within a set of undetermined files in a directory? I can't just type a specific file name, though the program knows what directory to look in.
Would you use FileStream? a Map? BOTH?
This is what I've done so far. However, it only counts the files in the directory and outputs the result:
fileCatch8.java :
public class fileCatch8 {
public static void main(String args[]) {
List<String> fileNames = new ArrayList<>();
try {
DirectoryStream<Path> directoryStream = Files.newDirectoryStream
(Paths.get("files"));
for (Path path : directoryStream) {
fileNames.add(path.toString());
}
} catch (IOException ex) {
}
System.out.println("Count: "+fileNames.size() + " files");
}
}
wordCount8 :
public class wordCount {
public static Map<String, Integer> countJava8Style(String input) {
return Pattern.compile("\\W+")
.splitAsStream(input)
.collect(Collectors.groupingBy(String::toLowerCase,
Collectors.summingInt(s -> 1)));
}
}

Better way to replace a set of signs with strings [duplicate]

This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 5 years ago.
I need to make a simple code, which get a string, and an array of String, and replace the ? signs with each element of array.
Here is the test case in junit:
#Test
public void QueryFitterTest() {
ArrayList<String> args=new ArrayList<String>();
args.add("Bad code");
args.add("The code is buggy");
String res = QueryMaker.queryFitter("insert into vulnerability (name,descirption) values(?,?)",args);
String correctQuery="insert into vulnerability (name,descirption) values(Bad code,The code is buggy)";
assertEquals(correctQuery, res);
}
and here is the code:
public static String queryFitter(String query, ArrayList<String> args){
String[] colapsedQuery = query.split("");
int parmNum=0;
for(int i=0;i<colapsedQuery.length;i++){
if(colapsedQuery[i]=="?"){
colapsedQuery[i]=args.get(parmNum);
parmNum++;
}
}
query=concatenator(colapsedQuery);
return query;
}
public static String concatenator(String[] colapsedQuery){
String delimiter = "";
String result = String.join(delimiter, colapsedQuery);
System.out.println("query is: "+result);
return result;
}
The code is working fine but
I don't like my approach, is there an easier way to do it?
There are 2 issues:
1- My code cannot pass the test, it returns the query without any
change.
query is: insert into vulnerability (name,descirption) values(?,?)
2-
I don't like my approach, is there an easier way to do it?
Well, the good news is that your JUnit test discovered a bug in your program. The other good news is that the answer to both of your questions is the same. Just fix your code in the method queryFitter.
Try the following code:
public static String queryFitter(String query, ArrayList<String> args){
for(int i=0;i<args.size();i++){
query = query.replaceFirst("\\?",args.get(i));
}
return query;
}
Almost forgot to tell you. You don't need concatenator method either.

I can't use toUpperCase() method on a String parameter, what could be wrong? [duplicate]

This question already has answers here:
toUpperCase in Java does not work [duplicate]
(5 answers)
Closed 6 years ago.
I use Eclipse IDE to program for java.
I wrote a class to show whether a name is in a CuncurrentHashMap, my IDE does not show me any error, yet whenever I run my program, I do not get my desired output. My desired output is to have the queries name "Jerry" capitalised. I am only learning the advance principles in java, I am familiar with the basic concepts but I am open to any correction or criticism you have towards my coding style below.
package learnJavaPackages;
import java.util.Scanner;
import java.util.concurrent.ConcurrentHashMap;
public class AddEmployee {
private String newEmployeeName;
private int empID=0;
ConcurrentHashMap<String, String> hashHandler = new ConcurrentHashMap<String, String>();
Scanner inputHere = new Scanner(System.in);
public void AddNewEmployee(){
System.out.print("Enter a new employee here: " );
newEmployeeName = inputHere.nextLine();
empID++;
String empIDstring = Integer.toString(empID);
newEmployeeName = newEmployeeName+empIDstring;
hashHandler.put(newEmployeeName, empIDstring);
}
public void showAddStatus(){
System.out.println(newEmployeeName +", has been added to the company");
}
public void showIsEmployeeIn(String isEmployee) {
isEmployee.toUpperCase();
if(hashHandler.containsKey(isEmployee)){
System.out.println(isEmployee +" is in the Company.");
}
else{
System.out.println(isEmployee +" is not in the company");
}
}
}
main method:
AddEmployee addEmpRef = new AddEmployee();
addEmpRef.AddNewEmployee();
addEmpRef.showAddStatus();
addEmpRef.showIsEmployeeIn("Jerry");
output:
Enter a new employee here: Isaac
Isaac1, has been added to the company
Jerry is not in the company
.toUpperCase() returns a brand new instance of String, which you don't assign to any variable. Just do:
isEmployee = isEmployee.toUpperCase();
String is immutable. Thus sEmployee.toUpperCase() does not change the sEmployee object. Instead it returns a new String. Use
sEmployee = sEmployee.toUpperCase();
Strings are immutable. As a result, all "mutating" methods return the updated String instead, and you need to pick that up.
isEmployee = isEmployee.toUpperCase();

How to re-dimension an array as long as i want [duplicate]

This question already has answers here:
Resize an Array while keeping current elements in Java?
(12 answers)
Closed 9 years ago.
I'd like to know if I can re-dimension an array as long as I want. I tried to do it and it seems there aren't any problems. I created an array with these steps
//step 1
String parole[];
//step 1
parole = new String[1];
parole[0] = "ciao";
//step 1
parole = new String[2];
parole[1] = "buongiorno";
I ask this beacuse there something in my mind that tells me that i can't do it. Maybe i read something somewhere someplace...
Of course you can create a new array object and assign it to an array reference.
But if you expected that parole[0] would still have "ciao" in it after your last step, you're wrong.
Yes you can, but you need to copy the first array into a new one.
Check this sample code:
public class ArrayCp {
public static void main(String[] args)
{
String[] primoArray = new String[1];
primoArray[0] = "Ciao";
// Copio il primo array nel secondo cambiandone la dimensione (secondo parametro)
String [] secondoArray = Arrays.copyOf(primoArray, 2);
secondoArray[1] = "Buona Sera";
for(String s : secondoArray) {
System.out.println("Elemento: " + s );
}
}
}
However is better going with an ArrayList:
ArrayList<String> theArr = new ArrayList<String>();
theArr.add("Ciao");
theArr.add("Buona Sera");
theArr.add("Buona Notte");
and get back to a simple array with
String [] resArray = theArr.toArray(new String[theArr.size()]);
Making a "new String[]" is just that, making a NEW string array. This means that any data you previously had in the reference is overwritten by the "new" object. (If you had other references to the string[] it wouldn't be lost however)
So, in short, no, you cannot "re-dimension" an array.
In your case, it is probably best to use an ArrayList, which provides for dynamic resizing (and is much easier to work with).
I agree with #BigMike
You should try ArrayList because it has built in methods for capacity which is far better than we doing it manually.
It does the work in amortized time which will be hard for us to achieve.
Refer this for more details.

Categories

Resources