Reputation:
I am trying to compare lines from a text file in Java. For example, there is a text file with these lines:
temp1 am 32.5 pm 33.5
temp2 am 33.5 pm 33.5
temp3 am 32.5 pm 33.5
temp4 am 31.5 pm 35
a b c d e
a is the name of the line, b is constant(am), c is a variable, d is constant(pm), e is another variable.
It will only compare the variables -> temp1(c) to temp2(c), temp1(e) to temp2(e) etc.
When there are two or more lines with the same c(s) and e(s), it will throw FormatException.
From the example text file above, because temp1's c is the same as temp3's c and temps1's e is the same as temp3's e, it will throw FormatException.
This is what I have so far:
public static Temp read(String file) throws FormatException {
String line = "";
FileReader fr = new FileReader(fileName);
Scanner scanner = new Scanner(fr);
while(scanner.hasNextLine()) {
String line = scanner.nextLine();
System.out.println(line);
}
scanner.close();
if () {
throw new FormatException("Error.");
How can I make this?
Upvotes: 0
Views: 1828
Reputation: 48258
If I got your question right then you need to check line by line in order to find duplicates using c and e as criteria
this means, line n must be compared against all the other lines, if repeated then exception...
Define a class that represent the element c and e of every line...
class LinePojo {
private String c;
private String e;
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((c == null) ? 0 : c.hashCode());
result = prime * result + ((e == null) ? 0 : e.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
LinePojo other = (LinePojo) obj;
if (c == null) {
if (other.c != null)
return false;
} else if (!c.equals(other.c))
return false;
if (e == null) {
if (other.e != null)
return false;
} else if (!e.equals(other.e))
return false;
return true;
}
@Override
public String toString() {
return "(c=" + c + ", e=" + e + ")";
}
public LinePojo(String c, String e) {
this.c = c;
this.e = e;
}
}
then a list of that class where every line will be inserted and /or check if an element is there or not..
List<LinePojo> myList = new ArrayList<LinePojo>();
then iterate line by line
while(scanner.hasNextLine()) {
String line = scanner.nextLine();
String[] lineInfo = line.split(" ");
LinePojo lp = new LinePojo(lineInfo[2], lineInfo[4]);
if (myList.contains(lp)) {
throw new IllegalArgumentException("there is a duplicate element");
} else {
myList.add(lp);
}
}
Upvotes: 0
Reputation: 2102
Here you got an example that basically includes:
try-with-resource
statementFirst of all I would make a simple POJO representing a line info:
public class LineInfo {
private String lineName;
private String am;
private String pm;
public LineInfo(String lineName, String am, String pm) {
this.lineName = lineName;
this.am = am;
this.pm = pm;
}
// getters and setters
}
Second I would need a pattern to validate each line and extract data from them:
// group 1 group 2 group3 group 4 group 5
// v v v v v
private static final String LINE_REGEX = "(\\w+)\\s+am\\s+(\\d+(\\.\\d+)?)\\s+pm\\s+(\\d+(\\.\\d+)?)";
private static final Pattern LINE_PATTERN = Pattern.compile(LINE_REGEX);
Third I would rework the read
method like this (I return void
for simplicity):
public static void read(String fileName) throws FormatException {
// collect your lines (or better the information your lines provide) in some data structure, like a List
final List<LineInfo> lines = new ArrayList<>();
// with this syntax your FileReader and Scanner will be closed automatically
try (FileReader fr = new FileReader(fileName); Scanner scanner = new Scanner(fr)) {
while (scanner.hasNextLine()) {
final String line = scanner.nextLine();
final Matcher matcher = LINE_PATTERN.matcher(line);
if (matcher.find()) {
lines.add(new LineInfo(matcher.group(1), matcher.group(2), matcher.group(4)));
} else {
throw new FormatException("Line \"" + line + "\" is not valid.");
}
}
// recursive method
compareLines(lines, 0);
} catch (final IOException e) {
e.printStackTrace();
// or handle it in some way
}
}
private static void compareLines(List<LineInfo> lines, int index) throws FormatException {
// if there are no more lines return
if (index == lines.size()) {
return;
}
final LineInfo line = lines.get(index);
for (int i = index + 1; i < lines.size(); i++) {
final LineInfo other = lines.get(i);
// do the check
if (line.getAm().equals(other.getAm()) && line.getPm().equals(other.getPm())) {
throw new FormatException(String.format("Lines #%d (%s) and #%d (%s) does not meet the requirements.",
index, line.getLineName(), i, other.getLineName()));
}
}
// do the same thing with the next line
compareLines(lines, index + 1);
}
Upvotes: 0
Reputation: 44965
You will need to split your lines to extract your variables and a Set
to check for duplicates as next:
Set<String> ceValues = new HashSet<>();
while(scanner.hasNextLine()) {
String line = scanner.nextLine();
String[] values = line.split(" ");
if (!ceValues.add(String.format("%s %s", values[2], values[4]))) {
// The value has already been added so we throw an exception
throw new FormatException("Error.");
}
}
Upvotes: 3
Reputation: 2950
As I don't want to do your homework for you, let me get you started:
while(scanner.hasNextLine()) {
String line = scanner.nextLine();
String[] partials = line.split(" ");
String a = partials[0];
//...
String e = partials[4];
}
I'm splitting the line over a space
as this is the only thing to split over in your case. This gives us 5 seperate strings (a through e). You will need to save them in a String[][]
for later analysis but you should be able to figure out for yourself how to do this.
Try playing around with this and update your question if you're still stuck.
Upvotes: 1