Reputation:
I have a string that is a concatenation of smaller strings of the form refNum orderNum
, as in a string that contains a reference number and the amount of items on an order e.g. BRICK1 10
. The larger concatenated string is a number of these smaller string pieced together and using a pound sign to divide them e.g. #BRICK1 10#BRICK2 20#BRICK3 30
.
When I use String.split() I'd like the result to be an array that has divided the larger string into its smaller elements so BRICK1 10
, BRICK2 20
and BRICK3 30
, however when I actually try to split the string using "#" as a delimiter I get a fourth string at the start of the array that is empty.
I'm not sure why this is happening, how do I prevent it?
My long string is produced using this method
public String getAllOrders()
{
String orderDetails = "";
for(BrickOrder o : orderList)
{
String order = "#" + o.getReferenceNumber() + " " + o.getNumberOfBricks();
System.out.println("ORDER: " + order);
orderDetails = orderDetails.concat(order);
}
return orderDetails;
}
Whilst the split method is used within a test class, here.
@Test
public void testFullOrderListReturnedCorrectly()
{
sys.createOrder(10);
sys.createOrder(100);
sys.createOrder(1000); //Create three orders
String orderList = sys.getOrders(); //Return full order list
System.out.println(orderList);
String[] orders = orderList.split("#");
System.out.println(orders.length);
}
Upvotes: 1
Views: 1890
Reputation: 425428
Use regex to safely (ie if any exist) remove all leading #
chars, then split:
String[] ordersPairs = orderList.replaceAll("^#*", "").split("#+");
By splitting on "#+"
, empty orders are also ignored/discarded.
Upvotes: 0
Reputation: 1667
how do I prevent it?
By placing delimiter between the parts you want to get with split.
Imagine, you want to split a stick in two.
How do you do it? Where would be the point of application of force?
Option one: ---V---
Option two: V---V--- (looks familiar?)
The former gives you two sticks, obviously, and the latter would give you an empty piece of stick in the beginning. It just doesn't exist in a real world, while an empty string happen to exist in Java.
Check String#split documentation, it says exactly that:
Splits this string around matches of the given regular expression.
Upvotes: 0
Reputation: 2642
Try this (Java 8+ is required):
import java.util.Arrays;
...
String s = "#BRICK1 10#BRICK2 20#BRICK3 30";
String[] tokens = Arrays.stream(s.split("#")).filter(t -> !t.isEmpty()).toArray(String[]::new);
Upvotes: 0
Reputation: 358
I believe the issue is because of the "#" that you are appending to the start of the order string.
The way split works is, it will break the order string at every "#", and the first "#" is encountered right at the beginning of the order string, and hence that is an empty.
Depending on your requirement, either you can avoid appending this "#" at the start, or you remove the "#" before spiting, or you ignore the element of the spitted array.
Hope this clarifies.
Upvotes: 1
Reputation: 22353
That's what split
does. It splits your string by using the delimiter and keeps the string, even if its empty, if it's not the last string.(trailing empty strings are excluded)
You could use a regex instead and a Pattern match. But in this case I'd recommend to just check your orderList
before you split it and remove the #
if it's the first character:
String[] orders;
if (orderList.charAt(0) == '#') {
orders = orderList.substring(1).split("#");
} else {
orders = orderList.split("#");
}
Upvotes: 1
Reputation: 5063
You get an empty string at the start of the array because the string you are splitting starts with you chosen delimiter (#
). You can prevent it by removing it from the beginning before splitting (using method String.substring(int)
for example).
Example solution:
String[] orders = orderList.substring(1).split("#");
Upvotes: 1