Why am I getting NoSuchElement Exception? - java

I'm getting the following errors and having troubles with fixing it. Any help is appreciated! Before anyone jumps saying that my code needs to look "cleaner" please know I'm brand new to this and still learning.
When running my Game.java it's giving me this...
Exception in thread "main" java.util.NoSuchElementException: No line found
at java.base/java.util.Scanner.nextLine(Scanner.java:1651)
at ItemGenerator.textFileReaderSpecialItems(ItemGenerator.java:71)
at ItemGenerator.<init>(ItemGenerator.java:22)
at Game.<init>(Game.java:9)
at Game.main(Game.java:16)
This is the code around these lines
ItemGenerator.java
58 public void textFileReaderSpecialItems(String x) {
59
60 try {
61
62 Scanner fileSc = new Scanner(new File(x));
63
64 while(fileSc.hasNext() && fileSc != null) {
65
66 String s1;
67 String s2;
68 String s3;
69
70 s1 = fileSc.nextLine();
71 s2 = fileSc.nextLine();
72 s3 = fileSc.nextLine();
73
74 itemsList.add(new Items(s1, s2, s3));
75 }
76
77 fileSc.close();
78
79 } catch (FileNotFoundException e) {
80
81 System.out.println("\nError: " + e + "\nProgram exiting...\n");
82 System.exit(0);
83
84 }
85
87 }
3 public Game() {
4
5 LocationGenerator newLocationGenerator = new LocationGenerator("Locations.txt");
6 MainCharacterGenerator newMainCharacter = new MainCharacterGenerator("MainCharacter.txt");
7 CharacterGenerator newCharacter = new CharacterGenerator("Characters.txt", "Jabberwocky.txt");
8 ItemGenerator newItem = new ItemGenerator("Items.txt", "SpecialItems.txt");
9 newLocationGenerator.startLocation();
10
11 }
12
13 public static void main(String[] args) {
14
15 Game game = new Game();
16
17 }
Any help would be appreciated! Learning curve for me!
Labeled all my information

The following will ensure your list is filled when the input file is valid:
public void textFileReaderSpecialItems(String x) {
try {
Scanner fileSc = new Scanner(new File(x));
int lineCount = 0;
List<String> lineBuffer = new ArrayList<>();
while (fileSc.hasNextLine()) {
lineBuffer.add(fileSc.nextLine());
lineCount++;
if (lineBuffer.size() % 3 == 0) {
itemsList.add(new Items(lineBuffer.get(0), lineBuffer.get(1), lineBuffer.get(2)));
lineBuffer.clear();
}
}
System.out.println(itemsList);
fileSc.close();
} catch (FileNotFoundException e) {
System.err.println("\nError: " + e + "\nProgram exiting...\n");
System.exit(1);
}
}
Note that method names should be verb-based, not noun-based. So, something like fillSpecialItems. Also, only return an exit code of zero on success. Use System.err for errors. Later, you will use System.err.printf maybe. Note the format character for a line separator is "%n". What you used ("\n") is OS-specific. Really, if you're not using logging (which you should in real-world, professional apps) you should always use e.printStackTrace() for exceptions - you want the maximum info possible.

Related

How do i store bluetooth input data received from Arduino in a array?

Arduino sends data from a sensor via bluetooth. I want to store the data in a array to operate with them.
This part obtains the data from the characteristic
private void broadcastUpdate(final String action, final BluetoothGattCharacteristic characteristic) {
final Intent intent = new Intent(action);
Log.v("AndroidLE", "broadcastUpdate()");
final byte[] data = characteristic.getValue();
//Log.v("AndroidLE", "data.length: " + data.length);
if (data != null && data.length > 0) {
final StringBuilder stringBuilder = new StringBuilder(data.length);
for(byte byteChar : data) {
stringBuilder.append(String.format("%02X ", byteChar));
//Log.v("AndroidLE", String.format("%02X ", byteChar));
}
intent.putExtra(EXTRA_DATA, new String(data) + "\n" + stringBuilder.toString());
Log.v("AndroidLE", new String(data));
Log.v("AndroidLE", stringBuilder.toString());
//intent.putExtra(EXTRA_DATA, new String(data));
//intent.putExtra(EXTRA_DATA, stringBuilder.toString());
}
sendBroadcast(intent);
}
the data has these formats in logcat
2020-10-18 14:27:07.434 32292-32292 V/AndroidLE: 415
419
418
418
34 31 35 0D 0A 34 31 39 0D 0A 34 31 38 0D 0A 34 31 38 0D 0A
2020-10-18 14:27:07.446 32292-32339 V/AndroidLE: broadcastUpdate()
2020-10-18 14:27:07.448 32292-32339 V/AndroidLE: 417
417
2020-10-18 14:27:07.449 32292-32339 V/AndroidLE: 34 31 37 0D 0A 34 31 37
private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)) {
updateConnectionState(true);
} else if (BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) {
updateConnectionState(false);
clearUI();
} else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) {
// Show all the supported services and characteristics on the user interface.
connect_caracterist_ard(mBluetoothLeService.getSupportedGattServices());
} else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) {
**storage_vect(intent.getStringExtra(BluetoothLeService.EXTRA_DATA));**
}
}
};
Any idea how to perform this function?
Maybe i should start by modifying the format in the broadcastUpdate, but I don't understand that well.
Thanks
You already receive your data as Bytearry, but your code takes each byte, converts it to the corresponding Hex value and stores the result in a string.
Modify your broadcastUpdate to this:
private void broadcastUpdate(final String action,
final BluetoothGattCharacteristic characteristic) {
final Intent intent = new Intent(action);
final byte[] data = characteristic.getValue();
if (data != null && data.length > 0) {
intent.putExtra(EXTRA_DATA, data);
}
sendBroadcast(intent);
}
This gets rid of the Stringbuilder and only adds the raw data to the Intent. If you receive data from multiple different characteristics you should also add intent.putExtra(EXTRA_CHAR, characteristic.getUuid().toString());. This enables you to handle data from other characteristics differently.
You can receive the data in your onReceive function by calling intent.getByteArrayExtra(BluetoothLeService.EXTRA_DATA)

Spring Batch- Read Footer in fixed length file

I wanted to validate the number of records in the file be equal to the number mentioned in the footer row.
is there any inbuilt functionality within spring batch to read fixed-width file footer row?
I tried to use the custom fieldset mapper to validate the number of records to be same as mentioned in the footer row.
new FlatFileItemReaderBuilder<FieldSet>()
.name("personItemReader")
.resource(fileName)
.fixedLength()
.columns(getRange())
.names(getNames())
.fieldSetMapper(new PassThroughFieldSetMapper())
.linesToSkip(1)
.build();
public class PersonFileReader implements ItemStreamReader<Person> {
private final ItemStreamReader<FieldSet> itemStreamReader;
private int recordCount = 0;
private int expectedRecordCount = 0;
private StepExecution stepExecution;
private final Logger logger = LoggerFactory.getLogger(PersonFileReader.class);
public PersonFileReader(#Qualifier("flatFileReader") ItemStreamReader itemStreamReader) {
this.itemStreamReader = itemStreamReader;
}
#Override
public Person read() throws Exception {
return process(itemStreamReader.read());
}
//code removed
#AfterStep
public ExitStatus afterStep(StepExecution execution) {
if (recordCount == expectedRecordCount) {
return execution.getExitStatus();
} else {
return ExitStatus.STOPPED;
}
}
private Person process(FieldSet fieldSet) {
Person result = null;
if (fieldSet != null) {
if (fieldSet.getFieldCount() > 1) {
logger.info("fieldSet", fieldSet.getFieldCount());
result = Person.builder()
.name(fieldSet.readString(0))
.lastName(fieldSet.readString(1))
.age(fieldSet.readInt(2))
.salary(fieldSet.readDouble(3))
.houseNumber(fieldSet.readInt(4))
.line1(fieldSet.readString(5))
.line2(fieldSet.readString(6)).build();
recordCount++;
} else {
expectedRecordCount = fieldSet.readInt(0);
if (expectedRecordCount != this.recordCount) {
this.stepExecution.setTerminateOnly();
}
}
}
return result;
}
}
But this fails to read the footer with an exception.
ogg.springframework.batch.item.file.FlatFileParseException: Parsing error at line: 6 in resource=[file [D:\Data\Study\spring-batch\batch-process\src\main\resources\static\file1.txt]], input=[4]
Caused by: org.springframework.batch.item.file.transform.IncorrectLineLengthException: Line is shorter than max range 66
Sample File.
Name lastName age salary HouseNo AddLine1 AddLine2
Andrew Green 25 26000 10 Avenue Glasgow
Ben Brown 32 28500 11 Avenue Glasgow
Celia Black 29 28000 12 Avenue Glasgow
Steve Pink 41 52000 13 Avenue Glasgow
4

Trouble with scanner, cant manage to read in TSP-file

I'm currently trying to read in coordinates from a TSP-file, they usually look something like this:
NAME: berlin52
TYPE: TSP
COMMENT: 52 locations in Berlin (Groetschel)
DIMENSION: 52
EDGE_WEIGHT_TYPE: EUC_2D
NODE_COORD_SECTION
1 565.0 575.0
2 25.0 185.0
3 345.0 750.0
4 945.0 685.0
5 845.0 655.0
6 880.0 660.0
7 25.0 230.0
8 525.0 1000.0
9 580.0 1175.0
10 650.0 1130.0
11 1605.0 620.0
12 1220.0 580.0
13 1465.0 200.0
14 1530.0 5.0
15 845.0 680.0
16 725.0 370.0
17 145.0 665.0
18 415.0 635.0
19 510.0 875.0
20 560.0 365.0
21 300.0 465.0
22 520.0 585.0
23 480.0 415.0
24 835.0 625.0
25 975.0 580.0
26 1215.0 245.0
27 1320.0 315.0
28 1250.0 400.0
29 660.0 180.0
30 410.0 250.0
31 420.0 555.0
32 575.0 665.0
33 1150.0 1160.0
34 700.0 580.0
35 685.0 595.0
36 685.0 610.0
37 770.0 610.0
38 795.0 645.0
39 720.0 635.0
40 760.0 650.0
41 475.0 960.0
42 95.0 260.0
43 875.0 920.0
44 700.0 500.0
45 555.0 815.0
46 830.0 485.0
47 1170.0 65.0
48 830.0 610.0
49 605.0 625.0
50 595.0 360.0
51 1340.0 725.0
52 1740.0 245.0
EOF
What I want to do is to read all the nodes, their two coordinates and create a node from this. I would like to store them in an arraylist storing lists, like:
ArrayList<String[]>
My code is currently looking like this:
package group12.TSP.tree;
import java.io.File;
import java.util.*;
public class Tree {
ArrayList<String[]> storing = new ArrayList<String[]>();
public Tree() throws Exception{
File file = new File("C:/Users/joaki/Desktop/burma14.tsp");
Scanner sc = new Scanner(file);
storing = new ArrayList<String[]>();
String nextValue = null;
//sc.reset();
sc.useDelimiter(" ");
while (sc.hasNextLine()) {
sc.nextLine();
while(sc.hasNextDouble()) {
nextValue = sc.nextLine();
//st.replaceAll("\\s+","")
//nextValue = nextValue.replace(" ", "");
storing.add(nextValue.split(""));
continue;
}
}
sc.close();
}
public static ArrayList<String[]> returnScanner() throws Exception {
Tree tree = new Tree();
return tree.storing;
}
public static void main(String[] args) throws Exception{
ArrayList<String[]> storedValues = returnScanner();
String[] firstLine = storedValues.get(0);
String[] secondLine = storedValues.get(1);
for(int i = 0; i < firstLine.length; i++) {
System.out.println(firstLine[i]);
}
}
}
This doesnt make the things I want it to do, but I dont understand how to implement it, I guess it could just copy the coordinates to a text-file but I want it to work for all sorts of TSPS. Thanks in advance!
made a few changes here. I read up to "NODE_COORD_SECION" then start parsing ans storing the lines. Instead of splitting on "" I split on " " and store the values.
public class Tree {
ArrayList<String[]> storing;
public Tree() throws Exception {
File file = new File("C:/Users/joaki/Desktop/burma14.tsp");
Scanner sc = new Scanner(file);
storing = new ArrayList<String[]>();
String nextValue = null;
while (sc.hasNextLine()) {
String line = sc.nextLine();
if("NODE_COORD_SECTION".equals(line)){
while (sc.hasNextLine()) {
nextValue = sc.nextLine();
storing.add(nextValue.trim().split(" "));
}
}
}
sc.close();
}
public static ArrayList<String[]> returnScanner() throws Exception {
Tree tree = new Tree();
return tree.storing;
}
public static void main(String[] args) throws Exception {
ArrayList<String[]> storedValues = returnScanner();
String[] firstLine = storedValues.get(0);
String[] secondLine = storedValues.get(1);
for (int i = 0; i < firstLine.length; i++) {
System.out.println(firstLine[i]);
}
}
}
My output:
1
565.0
575.0
Use the scanner to move to the next line until it encounters the phrase "NODE_COORD_SECTION". Then the subsequent lines are you data lines. They all conform to the format so you can use split to get the 2nd and third elements.
Stop reading and storing in your array when you reach a line which states "EOF".
How much do you care about the header of the TSP file? If you want to store this information and check that it is correct against the data in the file, rather than just running to the line "NODE_COORD_SECTION" you would want to look for the line: "DIMENSION" and store the value as an int. Then check this value against your final total in your ArrayList "storing"

Grouping strings using regex

I have string like this "7.51B, 8.01B, 7.02E, 7.52E, 8.02E,
7.01D, 7.51D, 8.01D, 8.54E, 9.04E, 9.54E, 10.04E, 10.54E, 11.04E" . I would like to group this string based on 1B , 2E , 1D , 4E using regex . Any help ?
Example:
Input
String s1 = "7.51B, 8.01B, 7.02E, 7.52E, 8.02E, 7.01D, 7.51D, 8.01D, 8.54E, 9.04E, 9.54E, 10.04E, 10.54E, 11.04E"
output:
1B - 7.51B, 8.01B
2E - 7.02E, 7.52E, 8.02E
1D - 7.01D, 7.51D, 8.01D
4E - 8.54E, 9.04E, 9.54E, 10.04E, 10.54E, 11.04E
Like already mentioned in the coments above the easiest way is to split and filter by ending. Example:
public static void main(String[] args){
String s = "7.51B, 8.01B, 7.02E, 7.52E, 8.02E, 7.01D, 7.51D, 8.01D, 8.54E, 9.04E, 9.54E, 10.04E, 10.54E, 11.04E";
String[] keys = {"1B","2E","1D","4E"};
Map<String, List<String>> map = new TreeMap<>();
for(String k :keys){
map.put(k, Arrays.stream(s.split(",")).filter(e->e.endsWith(k)).collect(Collectors.toList()));
}
System.out.println(map);
}

How to redraw print console info in java?

I want to do a terminal Graphic lib for funny and have seem many cool responsity, such as, asciimoo/drawille.
Using \r can redraw current line but how about former line?
For example, I have output three line(perhaps shouldn't use \n):
print("00000\n")
print("0 0\n")
print("00000\n")
//output
00000
0 0
00000
at next frame(eg. after 0.1s), I want redraw the second and third line. Hope result as:
00000
00 00
00 00
how to do this in terminal?
This will set up a console that has different states based on what the user enters. For now I just have the ability to go up ("w") or go down ("s")
public static void main(String[] args) {
HashMap<Integer, HashMap<String, String>> consoleStates = CreateConsoleStates();
String input = "default";
Scanner userInput = new Scanner(System.in);
do {
//draw default state of board
if(input.equals("default") || input.equals("w") || input.equals("s"))
printConsole(input, consoleStates);
//get input from user until they exit
input = userInput.nextLine().replaceAll("\n", "");
} while (!input.equals("exit"));
}//main method
public static HashMap<Integer, HashMap<String, String>> CreateConsoleStates()
{
HashMap<Integer, HashMap<String, String>> consoleStates = new HashMap<>();
HashMap<String, String> line1, line2, line3;
line1 = new HashMap<>();
line1.put("default", "00000");
line1.put("w", "00000");
line1.put("s", "00 00");
line2 = new HashMap<>();
line2.put("default", "0 0");
line2.put("w", "00 00");
line2.put("s", "00 00");
line3 = new HashMap<>();
line3.put("default", "00000");
line3.put("w", "00 00");
line3.put("s", "00000");
consoleStates.put(1, line1);
consoleStates.put(2, line2);
consoleStates.put(3, line3);
return consoleStates;
}
public static void printConsole(String state, HashMap<Integer, HashMap<String, String>> consoleStates)
{
//adding this will make it seem like a brand new console as suggested in another answer
//System.out.println("\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
//each number corresponds to the line in the console
System.out.println(consoleStates.get(1).get(state));
System.out.println(consoleStates.get(2).get(state));
System.out.println(consoleStates.get(3).get(state));
}
}
Output looks like:
00000
0 0
00000
s
00 00
00 00
00000
w
00000
00 00
00 00
e
00000
0 0
00000
exit
Note: that I'm using the standard wsad controls that most games have. I recommend it. w for up, a for left, s for down and d for right. Also i display the default state whenever an incorrect key is pressed and "exit" is used to exit the game.

Categories