Replacing element inside a Collection by using regular expressions - java

I have a Collection of strings.
I need to replace some characters with given relevant characters.
I was tried this. But my code but doesn't work correctly.
public class MyPattern {
public static void main(String[] args)
{
String items;
Collection<String> arr = new ArrayList<String>();
arr.add("I00.30"); //Expected output: 100.30
arr.add("8B4.99"); //Expected output: 884.99
arr.add("B37.2B"); //Expected output: 837.28
arr.add("292.b4"); //Expected output: 262.64
arr.add("24|.7O"); //Expected output: 241.70
arr.add("B55.I4"); //Expected output: 855.14
arr.add("444.07"); //Expected output: 444.07
for(String item:arr)
{
System.out.println(item);
items = item.toUpperCase().replaceAll("l", "1")
.replaceAll("l", "1")
.replaceAll("i", "1")
.replaceAll("|", "1")
.replaceAll("G", "6")
.replaceAll("b", "6")
.replaceAll("B", "8")
.replaceAll("O", "0");
System.out.println(items);
}
}
}
The letters passed in the replaceAll() method has to be replaced in every item in the collection.
Is there any way to find the irrelevant character and replace it with the number (as shown in the code above) ?

Your code is resigning the variable item, it will not affect the list contents.
To be able to do that, you might change the type of variable arr to List. With that, you can iterate over it by using the traditional (index based) for loop.
List<String> arr = // initializing the list
for (int i = 0; i < arr.size(); i++) {
String item = replace(arr.get(i)); // method replace provided below
arr.set(i, item);
}
Another option is to use Java 8 replaceAll() method, which expects a function that will be applied to every element in the collection.
arr.replaceAll(str -> replace(str));
public static String replace(String source) {
return source.toUpperCase()
.replaceAll("[LI|]", "1")
.replaceAll("[GB]", "6")
.replace("O", "0");
}
Note that method replaceAll() that expect a regular expression is more expensive than replace(). Hence, when you don't need a regex, its better to use any flavor of replace() (with either char or String arguments).
Here you can benefit from replaceAll() by processing characters L, L and | in one go with a regular expression "[LI|]".
For more information on regular expressions take a look at this tutorial
There's also a minor issue in your code:
After toUpperCase() has been applied, it doesn't make sense to try to replace lowercase letters like 'l' or 'i'.
There's a clash "b", "6" and "B", "8".
I hope with all these hints you'll be able to manage to get it working.

Instead of using the for loop. You can use, stream.
For example, if you want to change i to 1 in every element, you can get it using the following code. And you want to
Collection<String> arr_new = arr.stream().map(String::toLowerCase).map(t->t.replaceAll("i",1)).map(String::toUpperCase);
Here, the first map converts the String to lower-case, the second map do replace what you need and the third map convert it to the upper case.
I hope this is what you are looking for.

Related

Will the java Splitter result list ever be empty?

I am trying to split a string using Splitter class. For example:
List<String> resultList = Splitter.on("|").splitToList(stringToSplit);
My question is: can resultList ever be empty?
I cannot think of any cases that it would be empty. But if I directly use resultList.get(0), it seems buggy. Can I directly call resultList.get(0) without worries?
Well, that depends on how you configure your splitter instance. Here you have to very similar examples, both as input take an empty string.
First case uses "raw" splitter returns a list with only one element -- an empty string:
#Test
public void shouldReturnOneEmptyStringForRegularSplitter() {
//given
String input = "";
Splitter splitter = Splitter.on(',');
//when
List<String> result = splitter.splitToList(input);
//then
assertThat(result).containsOnly("");
}
In the second example the input is the same, but splitter is additionally configured to omit empty strings from a resulting list, which as a result returns an empty list:
#Test
public void shouldReturnOneEmptyStringForCustomized() {
//given
String input = "";
Splitter splitter = Splitter.on(',').omitEmptyStrings();
//when
List<String> result = splitter.splitToList(input);
//then
assertThat(result).isEmpty();
}
The behavior is documented:
For separator-based splitters that do not use omitEmptyStrings, an input string containing n occurrences of the separator naturally yields an iterable of size n + 1. So if the separator does not occur anywhere in the input, a single substring is returned containing the entire input. Consequently, all splitters split the empty string to [""] (note: even fixed-length splitters).
Splitter has couple more options you could configure and change the result base on that.
In your case, if you only use Splitter.on("|") without any additional options, you're guaranteed to always have at least one value in resulting list.
You can use this without checking if empty or not
resultList.stream().findFirst().orElseGet(null)
this will return the first object in your list otherwise it will return null
Base on code of the method Splitter#splitToList here,
It will return an empty ArrayList in case the given string could not be split
(In your case, it happens if the string does not contain "|")
407 public List<String> splitToList(CharSequence sequence) {
408 checkNotNull(sequence);
409
410 Iterator<String> iterator = splittingIterator(sequence);
411 List<String> result = new ArrayList<String>();
412
413 while (iterator.hasNext()) {
414 result.add(iterator.next());
415 }
416
417 return Collections.unmodifiableList(result);
418 }
Thus, you have to ensure the result is not empty or an IndexOutOfBoundsException would be thrown when calling resultList.get(0)
how about checking that stringToSplit contains "|" before call Splitter.on.splitToList

Collections.replaceAll(List<T> list, T oldVal, T newVal) does not work with regex properly, Java

I'm solving the problem where I must find the longest string in the list and replace all other list items with that string:
The longest string in the list
Inside the given method you should:
1. find the longest string in the list
2. replace all list items with the found string
When I use regular expression "\\w+" the method does not work:
Collections.replaceAll(list, "\\w+", longestString);
When I replace the specific words by specifying them in a method argument - all works properly, e.g.:
Collections.replaceAll(list, "word", longestString);
Why is that? Where is my error?
Collections.replaceAll method does not support Regex. Probably you should use List.replaceAll method:
list.replaceAll(e -> longestString);
Here is the working example:
// Dummy Values
List<String> list = new ArrayList<>();
list.add("Hey");
list.add("World");
list.add("Bye");
String longestString = "World";
// Replacing every word with `longestString`
list.replaceAll(e -> longestString);
// Printing
System.out.println(list);
Output:
[World, World, World]

How to remove the brackets [ ] from ArrayList#toString()?

I have created an Array List in Java that looks something like this:
public static ArrayList<Integer> error = new ArrayList<>();
for (int x= 1; x<10; x++)
{
errors.add(x);
}
When I print errors I get it errors as
[1,2,3,4,5,6,7,8,9]
Now I want to remove the brackets([ ]) from this array list. I thought I could use the method errors.remove("["), but then I discovered that it is just boolean and displays a true or false. Could somebody suggest how can I achieve this?
Thank you in advance for your help.
You are probably calling System.out.println to print the list. The JavaDoc says:
This method calls at first String.valueOf(x) to get the printed object's string value
The brackets are added by the toString implementation of ArrayList. To remove them, you have to first get the String:
String errorDisplay = errors.toString();
and then strip the brackets, something like this:
errorDisplay = errorDisplay.substring(1, errorDisplay.length() - 1);
It is not good practice to depend on a toString() implementation. toString() is intended only to generate a human readable representation for logging or debugging purposes. So it is better to build the String yourself whilst iterating:
List<Integer> errors = new ArrayList<>();
StringBuilder sb = new StringBuilder();
for (int x = 1; x<10; x++) {
errors.add(x);
sb.append(x).append(",");
}
sb.setLength(sb.length() - 1);
String errorDisplay = sb.toString();
Note that this is not an array, just a String displaying the contents of the list. To create an array from a list you can use list.toArray():
// create a new array with the same size as the list
Integer[] errorsArray = new Integer[errors.size()];
// fill the array
errors.toArray(errorsArray );
EDIT: From an object-oriented perspective one could argue that errors and errorsDisplay conceptually belong together in a class, e.g:
public class Errors {
private final List<Integer> codes = new ArrayList<>();
public void add(int error) {
codes.add(error);
}
public Stream<Integer> get() {
return codes.stream();
}
#Override
public String toString() {
return codes.stream()
.map(Object::toString)
.collect(Collectors.joining(", "));
}
}
Short answer: System.out.println(errors.toString().substring(1, errors.toString().length() - 1))
Explanation: when you call System.out.println(obj) with an Object as a parameter, the printed text will be the result of obj.toString(). ArrayList.toString() is implemented in a way that makes it represent its content between brackets [] in a comma separated concatenation of each of the contained items (their .toString() representation as well).
It is not a good practice to rely on another class's toString() implementation. You should use your own way to format your result.
The brackets you see are just an automatic way to display a List in JAVA (when using System.out.println(list); for example.
If you do not want them to show when showing it, you can create a custom method :
public void showList(List<Integer> listInt)
{
for(int el : listInt)
{
System.out.print(el + ", ");
}
}
Then adjust this code to show this according to your liking !
The brackets are not actually within the list it's just a representation of the list. If any object goes into a String output the objects toString() method gets called. In case of ArrayList this method delivers the content of the list wrapped by this brackets.
If you want to print your ArrayList without brackets just iterate over it and print it.
There are not brackets inside your list.
This is just the way Java prints a list by default.
If you want to print the content of your list, you can something like this
for (Integer error : errors) {
System.out.format("%d ", error);
}
If you print your error list, it will internally call the toString() method of your list and this method add the brackets. There are a few possibilities. You can get the String via toString() method an remove the brackets from the String. Or you write your own method to print the List.
public static <T> void printList(List<T> list)
{
StringBuilder output = new StringBuilder();
for(T element : list)
output.append(element + ", ");
System.out.println(output);
}
String text = errors.toString().replace("[", "").replace("]", "");//remove brackets([) convert it to string
brackets is not a part of your array list, since as you've mentioned it's Integer typed
ArrayList<Integer>
when you print errors using
System.out.println(errors);
it's just formatting your data, just iterate over the array and print each value separately
System.out.println(error.toString().substring(1, error.toString().length()-1));
This worked for me
For that, you can use String.join method like below.
String.join(",",errors);
This is an ArrayList of Integer. This ArrayList can not contain a character like '['. But you can remove an Integer from it like this -
error.remove(3);
You can write like this.
String output = errors.toString().replaceAll("(^\\[|\\]$)", "");
You can simply remove all the brackets using replaceAll() method like this:-
System.out.println(errors.toString().replaceAll("[\\[\\]]", ""));
I was experimenting with ArrayList and I also wanted to remove the Square brackets after printing the Output and I found out a Solution. I just made a loop to print Array list and used the list method " myList.get(index) " , it works like a charm.
Please refer to my Code & Output below:
import java.util.ArrayList;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
ArrayList mylist = new ArrayList();
Scanner scan = new Scanner(System.in);
for(int i = 0; i < 5; i++) {
System.out.println("Enter Value " + i + " to add: ");
mylist.add(scan.nextLine());
}
System.out.println("=======================");
for(int j = 0; j < 5; j++) {
System.out.print(mylist.get(j));
}
}
}
OUTPUT
Enter Value 0 to add:
1
Enter Value 1 to add:
2
Enter Value 2 to add:
3
Enter Value 3 to add:
4
Enter Value 4 to add:
5
=======================
12345

How to convert Vector elements to comma separated String

I am having a Vector<String> containing some items. I want to search those items in database.
For that purpose I need to make a String consisting of comma separated items out of that Vector so that I can pass it to SQL Query.
I am doing something like this.
StringBuilder list = new StringBuilder("");
for (String items : itemList) {
if(its last element then) //How to check here
list.append(items);
else
list.append(items+",");
}
but that will return me the output like "item1,item2,item3,"
where as I want to omit the last comma (,) in case if it is last element of Vector.
I have checked Vector API and found this method lastElement() (which returns last element not boolean).
How can I check it in the loop or is there any smarter/efficient way to do it?
I would go with the String.join approach.
final List<String> itemList = Arrays.asList("item1", "item2", "item3");
final String commaSeparated = String.join(",", itemList);
System.out.println(commaSeparated); // -> item1,item2,item3
A nice and clean solution. Only available for Java 8.
This is a possible duplicate of Java: function for arrays like PHP's join()?
Don't reinvent the wheel! This has been done many many times, unit tested and maintained. so use them, don't make your own.
You can use Apache Commons StringUtils and use the join method on Iterable (which Vector is)
StringUtils.join(itemList, ", ")
Also, as pointed out by Tom in the comments of your question, in Java 8 you can use String.join()
Have a look at libraries like Google Guava
Joiner.on(",").useForNull("null").join(itemList)
Since you're using a StringBuilder, it's easier to just delete the last comma:
StringBuilder list = new StringBuilder("");
for (String items : itemList) {
list.append(items).append(',');
}
if ( list.length() > 0 ) {
list.setLength(list.length() - 1 );
}
Change your loop as below:
for (int i=0; i<itemList.size(); i++) {
list.append(itemList.get(i));
if(i != itemList.size() - 1) {
list.append(",");
}
Internally vector uses array and you are accessing element by index now instead of using advance for each loop.
There are several third party libraries that do the heavy lifting for you, like Apache Commons Lang's StringUtils:
String list = StringUtils.join(items, ',');
If you absolutely must do this yourself, I'd start with the first element and append a comma and an element for each succeeding element:
StringBuilder list = new StringBuilder();
Iterator<String> iter = items.iterator();
if (iter.hasNext()) {
// Special treatment for the first item
list.append(iter.next());
// The rest of the items
while (iter.hasNext()) {
list.append(',').append(iter.next());
}
}
Simply use,
StringUtils.join(itemList, ", ");

Iterating over split string

After looking for a while, it's still bugging me:
I have a simple code where I want to retrieve data looking like:
data1/data2/style…
and I want to separate the data at each /. So I have written:
MyData = data.split("/")
and then:
for (i = 0; i < myData.size; i++)
to iterate over the values. But I'm getting the following error:
no signature of method length for type argument: () values: []
so I'm assuming that myData is empty.
if you want to iterate using an integer, you should use MyData.size() in the for loop.
But it is a better idea to do:
String[] myData = data.split("/");
for (String s: myData) {
System.out.println(s);
}
to use each string of the array.
If the iteration only iterates once over your array, then it may be your string that has a problem. As a double check, you may do:
System.out.println(myData.size());
You may also want to add a breakpoint after the .split() and look using a debugger if the array really contains all the strings you're expecting it to contain.
I am having some trouble understanding your question, even with the translation :)
In the line
mesDonnees = maDonnee.split("/");
mesDonnees needs to be a String array (String[]) and you can loop through it like:
for (String str : mesDonnees) {
//... do somwething with str
}
You can rename str something in French if you like, I couldn't think of a suitable name

Categories

Resources