I was wondering if it is possible to compare recursively strings within a file using comparator and replace a string based on an element within it. I have some data:
331028124,24,7912,CF,1,1
331028124,24,7631,2B,2,1
331028124,24,5909,1B,3,1
331028124,24,8394,P,3,2
331028124,24,7245,LF,4,1
331028124,17,9194,SS,1,1
I would like to get
331028124,24,7912,CF,1,1
331028124,24,7631,2B,2,1
331028124,24,8394,P,3,2
331028124,24,7245,LF,4,1
331028124,17,9194,SS,1,1
Effectively what this should do is compare two strings say 331028124,24,5909,1B,3,1
and 331028124,24,8394,P,3,2
and then replace the first string with the second string because of a higher number in the last value of the string...
So far I have:
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class BattingOrder {
String game_ID;
String team_ID;
String player_ID;
String position;
String battingOrder;
String subOrder;
public BattingOrder(String game, String team, String player, String place,
String batter, String sub) {
game_ID = game;
team_ID = team;
player_ID = player;
position = place;
battingOrder = batter;
subOrder = sub;
}
@Override
public String toString() {
return game_ID + "," + team_ID + "," + player_ID + "," + position + ","
+ battingOrder;
}
public static void main(String[] args) throws IOException {
FileInputStream fstream = new FileInputStream(
"BatterInfo.txt");
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
List<BattingOrder> sortList = new ArrayList<BattingOrder>();
for (String line; (line = br.readLine()) != null;) {
String delims = "[,]";
String[] parsedData = line.split(delims);
sortList.add(new BattingOrder(parsedData[0], parsedData[1],
parsedData[2], parsedData[3], parsedData[4], parsedData[5]));
}
System.out.println("Before Sort");
for (BattingOrder order : sortList) {
System.out.println(order);
}
Collections.sort(sortList, new Comparator<BattingOrder>() {
@Override
public int compare(BattingOrder one, BattingOrder two) {
if (one.game_ID.equals(two.game_ID)
|| one.team_ID.equals(two.team_ID)
|| one.battingOrder.equals(two.battingOrder)) {
return one.subOrder.compareTo(two.subOrder);
} else {
return one.team_ID.compareTo(two.team_ID);
}
}
});
System.out.println("After Sort");
for (BattingOrder order : sortList) {
System.out.println(order);
}
br.close();
}
}
Output:
Before Sort
331028124,24,7912,CF,1,1
331028124,24,7631,2B,2,1
331028124,24,5909,1B,3,1
331028124,24,8394,P,3,2
331028124,24,7245,LF,4,1
331028124,17,9194,SS,1,1
After Sort
331028124,24,7912,CF,1,1
331028124,24,7631,2B,2,1
331028124,24,7245,LF,4,1
331028124,24,5909,1B,3,1
331028124,17,9194,SS,1,1
331028124,24,8394,P,3,2
I want:
331028124,24,7912,CF,1,1
331028124,24,7631,2B,2,1
331028124,24,8394,P,3,2
331028124,24,7245,LF,4,1
331028124,17,9194,SS,1,1
What am I doing wrong?
In order to treat BattingOrder
objects the same on certain fields (but still determine who has better ranking)
You must override the equals
method as well as the hashCode
as well as put an identifier
/**
* Different BattingOrders who share these 3 fields
* will get the same identifier
*/
public String identifier() {
return game_ID +"-" + team_ID + "-" + battingOrder;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof BattingOrder) {
BattingOrder b = (BattingOrder) obj;
if (this.game_ID.equals(game_ID) && this.team_ID.equals(b.team_ID) && this.battingOrder.equals(b.battingOrder)) {
return true;
}
}
return false;
}
@Override
public int hashCode() {
int hash = 5;
hash = 59 * hash + Objects.hashCode(this.game_ID);
hash = 59 * hash + Objects.hashCode(this.team_ID);
hash = 59 * hash + Objects.hashCode(this.battingOrder);
return hash;
}
Also I made BattingOrder
implement Comparable
@Override
public int compareTo(BattingOrder o) {
if (this.identifier().equals(o.identifier())) {
return this.subOrder.compareTo(o.subOrder);
} else if (this.game_ID.equals(o.game_ID) && this.team_ID.equals(o.team_ID)) {
return this.battingOrder.compareTo(o.battingOrder);
} else {
return o.team_ID.compareTo(this.team_ID);
}
}
Now in your main
you set up some Set
Collection where you keep track of your BattingOrder
objects
I am using:
HashMap<String,BattingOrder> players = new HashMap<>();
Where the Key is the BattingOrder's identifier
and the Value is the BattingOrder
Now for-each line you are reading
do the following:
String[] parsedData = s.split(",");
BattingOrder bo = new BattingOrder(parsedData[0], parsedData[1],parsedData[2], parsedData[3], parsedData[4], parsedData[5]);
if(players.containsKey(bo.identifier())) {
BattingOrder inMap = players.get(bo.identifier());
if(bo.compareTo(inMap) > 0) {
players.put(bo.identifier(), bo);
}
} else {
players.put(bo.identifier(), bo);
}
Once you have read all the lines:
Convert your HashMap
into a List
List<BattingOrder> battingOrderList = new ArrayList<>(players.values());
Collections.sort(battingOrderList);
Here is the code and main tester
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.