String Split and save into ArrayList in JAVA7 [closed] - java

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed last year.
Improve this question
I have a string wherein I need to split it and store in an ArrayList as seen below; All these using Java7.
The below is the input for my program;
String inputStr = "ABC:DONE:07JAN90:1234:00001111:U:1234567:9632587:4561230:EC:IN:4815263:3621547:0314783)";
What I am trying to achieve here is an ArrayList as seen below after its grouped.
"List" : [
{
1234567,
4815263
},
{
9632587,
3621547
},
{
4561230,
0314783
}
]
I have a sample code written but that doesn't seem to group the elementB into the list. How can we do the grouping of both the elements into a List.
Sample Code:
String splitStringNeeded = "ABC:DONE:07JAN90:1352:00009279:U:1234567:9632587:4561230:EC:GB:4815263:3621547:0314783)";
String[] vElements = splitStringNeeded.split(":");
String[] grpV = Arrays.copyOfRange(vElements, 6,10 );
String[] grpT = Arrays.copyOfRange(vElements, 12, vElements.length);
List<String> groupedV = Arrays.asList(grpV);
List<String> groupedT = Arrays.asList(grpT);
for(String splitV : groupedV){
for(String splitT : groupedT){
System.out.println(splitV);
System.out.println(splitT);
break;
}
}
I am getting the below output where elementB does not change but repeats itself. Can someone please guide
"List" : [
{
1234567,
4815263
},
{
9632587,
4815263
},
{
4561230,
4815263
}
]
We can consider even the below inputs:
ABC:DONE:07JAN90:1352:00009279:U:1234567:9632587:0:EC:GB:4815263:3621547
ABC:DONE:07JAN90:1352:00009279:U:1234567:0:0:EC:GB:4815263

I have just modified the nested for loop in your sample code to a single for loop
Of course there are few un-knows such as Does your Source string always follow same pattern as you have displayed The length of the lists groupedV and groupedT are they always of same length etc. which is not considered
String splitStringNeeded = "ABC:DONE:07JAN90:1352:00009279:U:1234567:9632587:4561230:EC:GB:4815263:3621547:0314783";
/* Additional code for dynamic allocation of indexes
int indexU = splitStringNeeded.indexOf("U:");
int indexOfGb = splitStringNeeded.indexOf("EC:GB:");
System.out.println("Index of U "+indexU);
System.out.println("Index of GB "+indexOfGb);
String sub1 = splitStringNeeded.substring(indexU+2, indexOfGb-1);
System.out.println("Substring 1 = "+sub1);
String sub2 = splitStringNeeded.substring(indexOfGb+6, splitStringNeeded.length());
System.out.println("Substring 2 = "+sub2);
//Additional code for dynamic allocation of indexes
*/
String[] vElements = splitStringNeeded.split(":");
String[] grpV = Arrays.copyOfRange(vElements, 6, 9);
String[] grpT = Arrays.copyOfRange(vElements, 11, vElements.length);
List<String> groupedV = Arrays.asList(grpV);
List<String> groupedT = Arrays.asList(grpT);
if(groupedV.size() == groupedT.size()) {
for(int i=0; i<groupedV.size(); i++){
System.out.println(groupedV.get(i));
System.out.println(groupedT.get(i));
}
}
/*for (String splitV : groupedV) {
for (String splitT : groupedT) {
if (!splitV.equals("0")) {
System.out.println(splitV);
System.out.println(splitT);
break;
}
}
}*/
I have added the commented code to dynamically pick the index values instead of hard coding like 6,10,12
if you un-comment the first commented block the output will be like below
Index of U 31
Index of GB 57
Substring 1 = 1234567:9632587:4561230
Substring 2 = 4815263:3621547:0314783
1234567
4815263
9632587
3621547
4561230
0314783

Related

Parsing csv data into object with different column length

I am new to Java and practicing parsing csv file into the object. I've tried but cannot figure it out.
The file looks like this:
[0], [1], [2], [3] , [4] , [5] , [6] , [7] , [8] , [9]
class, gender, age, bodyType, profession, pregnant, isYou ,species, isPet, role
scenario:green, , , , , , , ,
person, female, 24, average , , FALSE , , , , passenger
animal, male , 4, , , FALSE , , dog , TRUE , pedestrian
scenario:red
person, male , 16, athletic, boxer , FALSE , TRUE , , , passenger
person, female, 25, athletic, doctor , TRUE , FALSE , , , pedestrian
I need to parse it by any number of passengers and pedestrians with any scenarios. Finally, add these scenarios into an ArrayList for analyzing.
What I think is to:
loop through each line, stops when reaches to the next scenario:red, adds the passengers and the pedestrians to the Character ArrayList. (I've done adding, but don't how to stop).
Create a scenario using constructor scenario(ArrayList<Character> passenger, ArrayList<Character> pedestrians, boolean redOrGreen);
The ArrayList scenarios add the created scenarios.
What I've done is put everything together instead of separate them. Any help or hint is highly appreciated.
Thanks for this community who helped me, here is what I've got so far.
public void loadCsv() throws IOException {
String csvFile = "config.csv";
String line = "";
String csvSplit = "\\s*,\\s*";
Scenario scenario = new Scenario();
Person person = new Person();
Animal animal = new Animal();
ArrayList<Scenario> scenaios = new ArrayList<Scenario>();
ArrayList<String> csvContents = new ArrayList<String>();
ArrayList<Character> passengers = new ArrayList<Character>();
ArrayList<Character> pedestrians = new ArrayList<Character>();
try (BufferedReader csvReader = new BufferedReader(new FileReader(csvFile));) {
String headerLine = csvReader.readLine(); //get rid of the header
//add each line to the arrayList
while ((line = csvReader.readLine()) != null) {
csvContents.add(line);
}
for(String csvLine : csvContents) {
String[] data = csvLine.split(csvSplit); // split by comma and remove redundant spaces
if (data.length == NO_OF_FIELD) { //check and avoid indexOutOfBoundException
String clazz = data[0].toLowerCase();// cannot use word "class" as a variable
if (clazz.startsWith("scenario") && data.length == 1) {
scenario = new Scenario();
scenario.setLegalCrossing(clazz.endsWith("green"));
continue;
}
else if ("person".equals(clazz) && data.length ==10) {
person = loadCsvPerson(data);
addCharacter(person, data);
}
else if ("animal".equals(clazz) && data.length ==10) {
animal = loadCsvAnimal(data);
addCharacter(animal, data);
}
}
}
}
//passenger and pedestrians are in position
System.out.println("passengers: " + passengers);
System.out.println("pedestrians: " + pedestrians);
if (null != scenario) {
scenario.setPassengers(passengers);
scenario.setPedestrians(pedestrians);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
If it is possible to change the csv file format, I would add scenario type column (and scenario id or name if required), so you can work with csv file as a result set from database when you join tables (scenario + passenger + pedestrian) and return plain rows.
With this approach you will be able to delegate parsing to any csv library and do your logic (group by scenario id/name/type) separately. With surrogate rows you have (scenario:green...) you have to write your custom parser.
For example, you can use univocity to simply parse file into your model (even using annotations) and iteratively group it and handle.
Or if you need to work with existing file format do something like that:
if (clazz.startsWith("scenario") && data.length == 1) {
// collect existing scenario before starting processing new one
if (scenario != null) {
scenario.setPassengers(passengers);
scenario.setPedestrians(pedestrians);
passengers = new ArrayList();
pedestrians = new ArrayList();
scenarios.add(scenario);
}
// now start new group (scenario)
scenario = new Scenario();
scenario.setLegalCrossing(clazz.endsWith("green"));
continue;
}
Following things need to be addressed in your code:
Strive to avoid using the name of a class which is already used by the standard library (and especially when it is in the default package, java.lang) e.g. there is already a class Character in Java library and therefore you should use a different name for your custom class.
Use continue to skip the line, scenario:red
for(String csvLine : csvContents) {
if(csvLine.equals("scenario:red")){
continue;
}
String[] data = csvLine.split(csvSplit); // split by comma and remove redundant spaces
if (data.length == NO_OF_FIELD) {
//..
}
//..
}
If you have already defined final int NO_OF_FIELD = 10, you can use the same instead of using the value 10 directly i.e. you should use NO_OF_FIELD instead of 10 in the following code:
if (data.length == NO_OF_FIELD) { //check and avoid indexOutOfBoundException
String clazz = data[0].toLowerCase();// cannot use word "class" as a variable
//...
else if ("person".equals(clazz) && data.length ==10) {
However, you also need to understand that && data.length ==10 is unnecessary here as you have already checked data.length == NO_OF_FIELD in the enclosing if condition.
I couldn't understand the rest of your points. If you clarify them, I'll be able to help you further.
I need to add the previous scenario in the second round.
Since the last set of data won't be captured, I need to set another new scenario to add it in. Thanks for the art sir.
Character character = null;
try (BufferedReader csvReader = new BufferedReader(new FileReader(csvFile));) {
String headerLine = csvReader.readLine(); //get rid of the header
//add each line to the arrayList
while ((line = csvReader.readLine()) != null) {
csvContents.add(line);
}
final int NO_OF_FIELDS = 10;
for(String csvLine : csvContents) {
String[] data = csvLine.split(csvSplit); // split by comma and remove redundant spaces
String clazz = data[0].toLowerCase();// cannot use word "class" as a variable
if (clazz.startsWith("scenario") && data.length == 1) {
// adding scenario after one set of data
// i.e second round adding the first round data
if (passengers.size() != 0 && pedestrians.size() != 0) {
Scenario scenario = new Scenario();
scenario.setPassengers(passengers);
scenario.setPedestrians(pedestrians);
scenarios.add(scenario);
}
passengers = new ArrayList<Character>();
pedestrians = new ArrayList<Character>();
if (clazz.endsWith("green")) {
scenario.setLegalCrossing(true);
System.out.println("green light");
}
else if (clazz.endsWith("red")){
scenario.setLegalCrossing(false);
System.out.println("red light");
}
continue;
}
//...
Scenario scenario = new Scenario();
scenario.setPassengers(passengers);
scenario.setPedestrians(pedestrians);
scenarios.add(scenario);
scenario.setPassengers(passengers);
scenario.setPedestrians(pedestrians);
Audit audit = new Audit();
audit.setScenario(scenarios);

Json parsing: Iterating through the values?

I'm trying to use json.simple to get things from this json file:
"Main": {
"Part1":{
"Length": 2,
"Flags": 2,
"Sequence": 4
},
"Part2":{
"Length": 2,
"Type":2,
"Main_Dest":4,
"Main_Source":4,
"Sequence":4,
"Data": {
"1":12,
"2":24
},
"Blank": 8
}
}
Basically, I want to reach the "Type" value in Part2, and on the way add all values. Meaning in the end I want to have the sum 10 (length+flags+sequence+length) and the number 2 for the value "Type". My main problem here is that I have to do it generically, so I can't just collect the values by name because they might change or additional values could be added. Only the value "Type" will always be called exactly that.
What I've done so far is this:
private static void parseJson() {
String path = "...config.json";
boolean count = false;
int sum = 0;
try {
FileReader reader = new FileReader(path);
JSONParser jsonParser = new JSONParser();
JSONObject jsonObject = (JSONObject) jsonParser.parse(reader);
jsonObject.entrySet();
JSONObject main = (JSONObject) jsonObject.get("Main");
for (Iterator iterator = main.keySet().iterator(); iterator.hasNext();){
String key = (String) iterator.next();
//this is where I'm stumped. Do I keep going into the JSONObject until I get to a value?
if (count){
sum += (int) sahara.get(key);
}
if (key.equals("Type")){
count = true;
}
}
System.out.println(skip);
} catch (Exception e) {
}
}
Obviously I don't really know what I'm doing with this. How do I iterate the lowest level in the json file?
As a little side question, which Json parser libraries should I use if I might sell my software? In other words, which doesn't cause licensing issues?
You can iterate over keys recursively, but you can't calculate sum, result will be unpredictable.
jsonObject.keySet not guarantee returns the keys in the same order as they appears in file.
Use the stream API for Json.
I have added the missing curly braces to fix your input.
{
"Main": {
"Part1":{
"Length": 2,
"Flags": 2,
"Sequence": 4
},
"Part2":{
"Length": 2,
"Type":2,
"Main_Dest":4,
"Main_Source":4,
"Sequence":4,
"Data": {
"1":12,
"2":24
},
"Blank": 8
}
}
}
This examples shows how to use the stream API.
// -*- compile-command: "javac -cp javax.json-1.0.jar q43737601.java && java -cp .:javax.json-1.0.jar q43737601"; -*-
import java.io.FileReader;
import javax.json.Json;
import javax.json.stream.JsonParser;
class q43737601
{
public static void main (String argv[]) throws Exception
{
String path = "config.json";
int sum = 0;
JsonParser p = Json.createParser (new FileReader (path));
while (p.hasNext()) {
JsonParser.Event e = p.next();
switch (e) {
case VALUE_NUMBER:
sum += Integer.parseInt(p.getString());
break;
case KEY_NAME:
if ("Type".equals(p.getString()))
System.out.println(sum);
break;
}
}
}
}
If you run it, it displays 10. The example sums up all numbers up to a key called "Type".
I tried the above example with OpenJDK. It was necessary to follow the steps explained in this answer. I had to set the class path (-cp) in the compile command.

How I transfer file details to Vector?

I splited the file to String lines and put them in array indexes.
String fileString = readfromfile(fileEvents);
String[] fileLines = fileString.split("\n");
assuming this is the first index in fileLines:
14 57 9 2 www.buytickets.com
this is the constructor:
Orders (int EventID, int SoldtoCustomerID, int SoldtoEmployeesID, int NumberOfTickets, String URL)
the vector instance:
Vector<Orders> myOrders = new Vector<Orders>();
how do I transfer this line to first index in the vecotr so it would be like this:
(14,57,9,2,www.buytickets.com)
thank you :)
If we assume that there won't be any invalid entries the following should do the job:
Vector<Orders> myOrders = new Vector<Orders>();
for (String line : fileLines) {
String[] tokens = line.split("\\s+")
Orders o = new Orders(
Integer.valueOf(tokens[0]),
Integer.valueOf(tokens[1]),
Integer.valueOf(tokens[2]),
Integer.valueOf(tokens[3]),
tokens[4])
myOrders.add(o)
}

Search element in arraylist

How can I search element in arraylist and display it? Example is the user wants to search the code A25 Then it will print the whole content on that arraylist that he search only and the output is A25 CS 212 Data Structures 3.
Subject CS212 = new Subject("A25","\t\tCS 212","\t\tData Structures\t\t\t\t",units);
Subject IT312 = new Subject("A26","\t\tIT 312","\t\tData Base Management System 2\t\t",units);
Subject IT313 = new Subject("A27","\t\tIT 312","\t\tData Base Management System 2\t\t",units);
Subject CS313 = new Subject("A29","\t\tCS 313","\t\tDigital Designt\t\t\t\t",units);
Subject Disc = new Subject("A30","\t\tIT 212","\t\tDiscrete Structurest\t\t",units);
Subject A31 = new Subject("A31","\t\tIT 212","\t\tDiscrete Structurest\t\t",units);
Subject Engl3 = new Subject("984","\t\tEngl 3","\t\tSpeech and oral Communicationt\t\t",units);
Subject Theo3 = new Subject("582","\t\tTheo 3","\t\tChrist and Sacramentst\t\t",units);
Subject Stat = new Subject("470","\t\tStata1","\t\tProbablility and Statisticst\t\t",units);
Subject Dota = new Subject("999","\t\tDota 2","\t\tDota Guide\t\t\t\t",units);
ArrayList<Subject> arrList = new ArrayList<Subject>();
arrList.add(CS212);
arrList.add(IT312);
arrList.add(IT313);
arrList.add(CS313);
arrList.add(Disc);
arrList.add(A31);
arrList.add(Engl3);
arrList.add(Theo3);
arrList.add(Stat);
arrList.add(Dota);
//User input that he wants to search
for(int i = 0; i < 3; i++,num++)
{
System.out.print("\t\t"+num +". ");
codeNo[i] = scan.next();
String output = Character.toUpperCase(codeNo[i].charAt(0)) + codeNo[i].substring(1);
codeNo[i] = output;
}
// This is what I tried but it doesn't work Idk why
for (Subject s : arrList) {
for(int i =0; i < codeNo.length; i++)
if (s.equals(codeNo[i])) {
System.out.println("\t\t\t"+s);
}
}
public Subject(String codeNo, String subjectID, String title , int unit)
{
//Constructor . .
}
//Desired output
Code to search
A25
A26
A27
output
A25 CS 212 Data Structures 3
A26 IT 312 Data Base Management System 2 3
A27 IT 312 Data Base Management System 2 3
You are trying to search an arraylist of subjects, you need to write a small function to compare the code string to the corresponding string of the class. You can do this by adding this to your subject class.
Example :
#Override
public boolean equals(String code) {
return code.equals(this.<compare to member>);
}
and change the compare to member that needs to match the code that you match.
EDIT : Easier way to do is to just change your existing code to :
if (s.code.equals(codeNo[i])) //assuming your code class member is a public string

Need to Re Design existing logic for dynamic input

I have a method getFormattedValue(List<String> dataHeaders, List<String> data) that returns String value based contents of dataHeaders and data list. dataHeaders list can have 10 distinct values and based on value at particular index output string formation changes.
Below code was working fine tiil the time when dataHeaders contents are received in specific order , but lately this order is changing many atimes. As this input is received from other app/ system, i do not have control over order of elements. Hence i want to update my code so that it works correctly even after input order is altered.
If 1'st element of dataHeaders list is "OPERATION_NAME" then i need not take any action, but if "OPERATION_NAME" comes at 2'nd index in dataHeaders list then i need to do special formatting to output value. And so on....
My Pain is that i receive 10 dataHeaders. Please suggest me any good approach to handle this issue. I am posting my code below, suggestions are welcome.
import java.util.ArrayList;
import java.util.List;
public class ValueGenerator {
public String getFormattedValue(List<String> dataHeaders, List<String> data){
String formattedOutValue=null;
if(dataHeaders!=null && data!=null &&
dataHeaders.size() == data.size()){
if(dataHeaders.get(0).equals("OPERATION_NAME")){
formattedOutValue=data.get(0); // Add no spaces
}else if(dataHeaders.get(1).equals("OPERATION_NAME")){
formattedOutValue=data.get(1)+" "; // Add 4 blank spaces
}else if(dataHeaders.get(2).equals("OPERATION_NAME")){
formattedOutValue=data.get(2)+" "; // Add 6 blank spaces
}
}
//likewise i want to avoid redundant if - else if check
return formattedOutValue;
}
}
I assume that you want data.get(2) in the case of dataHeaders.get(2) and not data.get(1)
Basically you just need to find the index of the string OPERATION_NAME in dataHeaders and use it for data. The simplest way is to iterate over the list dataHeaders with an index and stop when you find it.
If you need to handle more strings then you could use a Map to map the strings you want to evaluate to their indices, this could look like this:
final static Map<Integer, String> formatByIndexMap;
static {
formatByIndexMap = new HashMap<>();
formatByIndexMap.put(0, "");
formatByIndexMap.put(1, " ");
formatByIndexMap.put(2, " ");
// and so on
formatByIndexMap.put(9, "----format for 10----");
}
public String getFormattedValue(List<String> dataHeaders, List<String> data){
String formattedOutValue = null;
if (dataHeaders != null && data != null &&
dataHeaders.size() == data.size()) {
Map<String, Integer> dhm = new HashMap<>();
for(int i = 0; i < dataHeaders.size(); i++) {
dhm.put(dataHeaders.get(i), i);
}
Integer operationNameIndex = dhm.get("OPERATION_NAME");
if(operationNameIndex != null) {
formattedOutValue = data.get(operationNameIndex.intValue()) +
formatByIndexMap.get(operationNameIndex);
}
}
return formattedOutValue;
}
The format map formatByIndexMap is defines as final static.
An for some basic testing:
#Test
public void getFormattedValue() {
List<String> data = Arrays.asList("operation", "foo", "bar");
List<String> dataHeaders;
String formated;
dataHeaders = Arrays.asList("OPERATION_NAME", "FOO_NAME", "BAR_NAME");
formated = getFormattedValue(dataHeaders, data);
Assert.assertEquals("operation", formated); // no spaces
dataHeaders = Arrays.asList("FOO_NAME", "OPERATION_NAME", "BAR_NAME");
formated = getFormattedValue(dataHeaders, data);
Assert.assertEquals("foo ", formated); // four spaces
dataHeaders = Arrays.asList("FOO_NAME", "BAR_NAME", "OPERATION_NAME");
formated = getFormattedValue(dataHeaders, data);
Assert.assertEquals("bar ", formated); // six spaces
dataHeaders = Arrays.asList("FOO_NAME", "BAR_NAME", "", "", "", "", "",
"", "", "OPERATION_NAME");
data = Arrays.asList("operation", "foo", "bar", "", "", "", "",
"", "", "tail");
formated = getFormattedValue(dataHeaders, data);
// ----format for 10----
Assert.assertEquals("tail----format for 10----", formated);
}

Categories

Resources