In Java, I want to extract the differences from one comma-separated string when compared to another.
e.g
The string I want to extract the differences from: 1,hello,fire,dog,green
The string I am comparing with : 1,hello,water,dog,yellow
So the result of the function would give me a arraylist of [3,fire] and[5,green] as those items are different than the items in the second string, which are 'water' and 'yellow'. The numbers are the index positions of each item detected to be a difference. The other items match and are not considered.
First, you can create your own Pair class (based on Creating a list of pairs in java), doesn't have to be template.
Then Do something like this:
Split the two strings:
List<String> toCompareSplit= Arrays.asList(toCompare.split(","));
List<String> compareWithSplit= Arrays.asList(compareWith.split(","));
Iterate the lists:
List<Pair> diffList= new ArrayList<Pair>();
for (int i= 0; i < toCompareSplit.size; i++){
if (!toCompareSplit.get(i).equals(compareWithSplit.get(i))){
Pair pair= new Pair(i+1, toCompareSplit.get(i));
diffList.add(pair);
}
}
If the lists aren't in the same size you can run to the end of the shortest one etc.
Why not just loop through by splitting the strings.
public static List<String> compareStrings(String str1, String str2) {
String[] arrStr1 = str1.split(",");
String[] arrStr2 = str2.split(",");
List<String> strList = new ArrayList<String>();
for(int index = 0; index < arrStr1.length; ++index) {
if (!arrStr1[index].equals(arrStr2[index])) {
strList.add("[" + index + "," + arrStr1[index] + "]");
}
}
return strList;
}
Beaware of index out of bounds exception..!!
var left = "1,hello,fire,dog,green";
var right = "1,hello,water,dog,yellow";
var result = left.Split(',').Zip(right.Split(','), Tuple.Create).Where(x => x.Item1 != x.Item2).ToArray();
Using C#, this will return an array of tuples of the different elements. Sorry I don't have a compiler to hand so may be some small syntax errors in there.
Related
I've been trying to convert my string array list to a string array so I can print it but have been unable to do so.
This is the class I have, randomQuestion which takes in an array list from the gameQuestions method in the same class.
I have never tried to convert an array list using a loop before hence the difficulty, I was able to convert it fine with the code
String[] questions = data1.toArray(new String[]{});
But I need it to loop through using a for loop to store it in an array which I can then print one at a time once a question is answered successfully.
The error I'm receiving from netbeans is cannot find symbol
Symbol:methodtoArray(String[]) for the .toArray portion below.
public String[] randomQuestion(ArrayList data1) {
Collections.shuffle(data1);
for (int question = 0; question < 10; question++) {
ranquestions = data1.get(question).toArray(new String[10]);
}
return ranquestions;
}
Any help would be greatly appreciated.
You can use List.toArray(). Class List has a method:
<T> T[] toArray(T[] a);
Assuming you have an ArrayList<String>, you can use String.join(delimiter, wordList) in order to concatenate all the elements to a single String:
public static void main(String[] args) {
// example list
List<String> words = new ArrayList<String>();
words.add("You");
words.add("can");
words.add("concatenate");
words.add("these");
words.add("Strings");
words.add("in");
words.add("one");
words.add("line");
// concatenate the elements delimited by a whitespace
String sentence = String.join(" ", words);
// print the result
System.out.println(sentence);
}
The result of this example is
You can concatenate these Strings in one line
So using your list, String.join(" ", data1) would create a String with the elements of data1 delimited by a whitespace.
The question is how to create an array with only 10 elements of the list, if I understood correctly.
Streams (Java 8):
String[] ranquestions = data1.stream()
.limit(10)
.toArray(String[]::new);
Loop (based on question, avoiding unnecessary changes):
String[] ranquestions = new String[10];
for(int question = 0; question < 10; question++) {
ranquestions[question] = data1.get(question);
}
always assuming List<String> data1, if not some conversion is needed.
Example:
String[] ranquestions = data1.stream()
.limit(10)
.map(String::valueOf)
.toArray(String[]::new);
or, loop case:
ranquestions[question] = String.valueOf(data1.get(question));
You can do:
private String[] randomQuestions(ArrayList data){
Collections.shuffle(data);
return (String[]) data.toArray();
}
If you are sure you are getting a list of string (question) you can instead
private String[] randomQuestions(List<String> data){
Collections.shuffle(data);
return (String[]) data.toArray();
}
Edit 1
private static String[] randomQuestions(ArrayList data){
Collections.shuffle(data);
String[] randomQuestions = new String[data.size()];
for(int i=0; i<data.size(); i++){
randomQuestions[i] = String.valueOf(data.get(i));
}
return randomQuestions;
}
Background:
I am working on a scraping project using Selenium that gets data from tables on webpages in our Test and Production environments and then stores the data into two separate Array List of String type (one for test/prod). The data are numbers (double) and there are 3 columns and anywhere from 13-16 rows of data. It varies because I am pulling data from over 145 countries and each table is different.
Please not that that this is just an example. The code that I present here is not the Selenium Script I am running.
Issue:
The issue lies when I am trying to convert the data from the two Array Lists that I have into two 2 dimensional arrays. I have worked with very basic 2d arrays before, but only created them off of user input.
Based on the research I have done before, the syntax for converting an ArrayList to an array is:
ArrayList<String> b = new ArrayList<>();
b.add("1.50");
b.add("3.12");
b.add("5.25%");
b.add("2.16");
b.add("4.36");
b.add("7.76%")
//This is just a snippet, remember the list would have anywhere from 13-16
indices.
String[] x = b.toArray();
But how do I convert that same list into an 2 dimensional array in the format of
1.50 3.12 5.25%
2.16 4.36 7.76%
starting a new line every third index?
You have to loop the List and add the items to a new one unless you find value with a percentage (%) in it. Then, you create a new List. This solution is based on the % character appearance, not the fixed size of a gap between elements to split which might be an advantage.
List<List<String>> outer = new ArrayList<>();
List<String> inner = new ArrayList<>();
for (String s: b) {
inner.add(s);
if (s.contains("%")) {
outer.add(inner);
inner = new ArrayList<>();
}
}
The List<List<String>> outer will contain these values:
[[1.50, 3.12, 5.25%], [2.16, 4.36, 7.76%]]
To convert the structure from List<List<String>> to String[][], you can use java-stream or a simple for-loop approach iterating and filling the array.
String[][] array = outer.stream()
.map(a -> a.stream().toArray(String[]::new)) // List<String> to String[]
.toArray(String[][]::new); // List<String[]> to String[][]
A typical for loop should do:
List<List<String>> accumulator = new ArrayList<>();
for (int i = 0; i < b.size(); i+=3) {
List<String> temp = new ArrayList<>(b.subList(i, i + 3));
accumulator.add(temp);
}
accumulator now looks like:
[[1.50, 3.12, 5.25%], [2.16, 4.36, 7.76%]]
note that the above assumes you'll always a list that is a multiple of three, if that it not the case then you can handle it as follows:
List<List<String>> accumulator = new ArrayList<>();
for (int i = 0; i < b.size(); i+=3) {
List<String> temp = b.stream().skip(i).limit(3).collect(toList());
accumulator.add(temp);
}
if you strictly require the result to be a String[][] then you can get it as follows:
String[][] strings =
accumulator.stream()
.map(l -> l.toArray(new String[0]))
.toArray(String[][]::new);
You can iterate over your list an add the entries manually in an 2d-array:
String[][] array = new String[b.size()/3][3];
for (int i = 0; i < b.size(); i++) {
int row = i / 3;
int col = i % 3;
array[row][col] = b.get(i);
}
System.out.println(Arrays.deepToString(array));
I have the below three elements :
play_full_NAME=556677
pause_full_NAME=9922
stop_full_NAME=112233
A string "abc" returns all the above three elements one by one from a particular piece of code.
I am trying to add all three elements in a list separated by a colon ":"
Sample output :
play_full_NAME=556677:pause_full_NAME=9922:stop_full_NAME=112233
My attempt:
List<String> list = new ArrayList<String>();
list.join(":",abc)
Please help with a better way to handle this.
Your understanding about List is little flawed. Comma is only printed for representation purposes.
To join strings with colon, you can do the following
List<String> list = Arrays.asList("play_full_NAME=556677",
"pause_full_NAME=9922",
"stop_full_NAME=112233");
String joinedString = String.join(":", list);
Did you really understood the List well?
In fact, there is no separator, each item / value is stored as different "object".
So you have some amount of independent values- Strings in this case, what can you see on screenshot bellow, or if you will do System.out.println(someList); it will call override of method toString() which is inherited from Object class , which is root parent class of all classes in Java.
So its absolutely nonsense to add some split character between each items in List, they are split already, you can access each item by get(int position) method.
So if you want to print each item of list "by yourself", can be done like follows:
for (int i = 0; i < someList.size(); i++) {
System.out.println(i + " = " + someList.get(i));
}
/* output will be
1 = 1 item
2 = 2 item
3 = 3 item
4 = 4 item
*/
If you want to implement custom method for printing "your list" then you can extend eg. ArrayList class and override toString method, but better and more trivial approach will be prepare some method in some utils to get formatted String output with context of List- eg. (notice there will be ; after last element)
public static String getFormatStringFromList(ArrayList<String> data) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < data.size(); i++) {
sb.append(data.get(i) + ";");
}
return sb.toString();
//eg. 0 item;1 item;2 item;3 item;4 item;
}
To avoid last separator you can do eg. simple check
public static String getFormatStringFromListWitoutLastSeparator(List<String> someList) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < someList.size(); i++) {
sb.append(someList.get(i));
if(i < someList.size() -1) {
sb.append(";");
}
}
return sb.toString();
//0 item;1 item;2 item;3 item;4 item
/*
someList[0] = 0 item
someList[1] = ;
someList[2] = 1 item
someList[3] = ;
{etc..}
*/
}
The best approach to get String from list will be like #krisnik advised:
String joinedString = String.join(":", list);
You would need to add the colon elements separately if you want them to be within your list.
For example:
List<String> list = new ArrayList<String>();
list.add(abc);
list.add(":");
list.add(def);
list.add(":");
and so on.
I would recommend against this, however, as you can simply format the output string using String.format or a StringBuilder when you need it.
I have an ArrayList that contains a number of Strings, I want to be able to iterate through the ArrayLists contents searching for a string containing a semicolon. When the semicolon is found I then want to delete all of the Strings including and after the semicolon string.
So;
this, is, an, arra;ylist, string
Would become:
this, is, an
I feel like this is a very simple thing to do but for some reason (probably tiredness) I can't figure out how to do it.
Here's my code so far
public String[] removeComments(String[] lineComponents)
{
ArrayList<String> list = new ArrayList<String>(Arrays.asList(lineComponents));
int index = 0;
int listLength = list.size();
for(String str : list)
{
if(str.contains(";"))
{
}
index++;
}
return lineComponents;
}
This becomes trivial with Java 9:
public String[] removeComments(String[] lineComponents) {
return Arrays.stream(lineComponents)
.takeWhile(s -> !s.contains(";"))
.toArray(String[]::new);
}
We simply form a Stream<String> from your String[] lineComponents and take elements until we find a semicolon. It automatically excludes the element with the semicolon and everything after it. Finally, we collect it to a String[].
First of all I think you are confusing arrays and arraylists. String[] is an array of strings while ArrayList<String> is an arraylist of strings. Take into account that those are not the same and you should read Array and ArrayList documentation if needed.
Then, to solve your problem following the ArrayList approach you can go as follows. Probably it's not the optimum way to do it but it will work.
public List<String> removeComments(List<String> lineComponents, CharSequence finding)
{
ArrayList<String> aux = new ArrayList<String>();
for(String str : lineComponents)
{
if(str.contains(finding))
break;
else
aux.add(str);
}
return aux;
}
This example is just for performance and bringing back my old favorite arraycopy:
public String[] removeComments(String[] lineComponents) {
int index = -1;
for (int i = 0; i < lineComponents.length; i++) {
if ( lineComponents[i].contains(";") ) {
index = i;
break;
}
}
if (index == -1) return lineComponents;
return Arrays.copyOf(lineComponents, index);
}
I am new to java. I have done python before and concatenating elements of two lists or arrays seemed easy with loop. But how to do the same with java??? For example, I have a multidimensional array:
//codes
String [][] nameAry={{"Mr.","Mrs.","Ms."},{"Jones","Patel"}};
//The output I am expecting :
Mr. Jones, Mrs. Jones, Ms, Jones, etc.
// I can do it by handpicking elements from indices, as shown in oracle documentation, but what I am looking for is a loop to do the job instead of doing:
//code
System.out.println(nameAry[0][0]+", "+nameAry[1][0]);
`
////So, is there a way to put it the way I do in python,i.e.,:
x=["Mr.","Mrs.","Ms."]
y=["Jonse","patel"]
names-[a+b for a in x for b in y]
///this gives me the following result:
['Mr.Jonse', 'Mr.patel', 'Mrs.Jonse', 'Mrs.patel', 'Ms.Jonse', 'Ms.patel']
//So, is there something like this in Java???
You can just use loops with index variables to access your array. Here I'm using i to loop through the first dimension and j for the second dimension of the string array, while assembling each pair and adding it to a list.
The part with the ArrayList is just for convenience, you can also return the strings or add them to a different data structure. Hope that helps.
Edit: Explanations
ArrayList<String> list = new ArrayList<String>();
String [][] nameAry={{"Mr.","Mrs.","Ms."},{"Jones","Patel"}};
for(int i = 0;i<nameAry[0].length;i++) {
for(int j =0;j<nameAry[1].length;j++) {
list.add(nameAry[0][i]+nameAry[1][j]);
}
}
Here's a solution using streams.
String [][] nameAry={{"Mr.","Mrs.","Ms."},{"Jones","Patel"}};
List<String> list = Arrays.stream(nameAry[0])
.flatMap(x -> Arrays.stream(nameAry[1])
.map(y -> x + y))
.collect(Collectors.toList());
list.forEach(System.out::println);
Note that the flatMap method is used here. It is used to turn each element of the first subarray into a new stream. The new stream is created by .map(y -> x + y) i.e. concatenating the names to the honorifics. All the new streams are then joined.
I think the use of a 2D array here as input is wrong.
You have correctly used 2 arrays as inputs in your Python example.
So just do the same in Java.
Cartesian product method:
public String[] cartesianProduct(String[] first, String[] second) {
String[] result = new String[first.length * second.length];
int resIndex=0;
for (int i=0; i < first.length; i++) {
for (int j=0; j < second.length; j++) {
result[resIndex] = first[i] + second[j];
resIndex++;
}
}
}
Method main:
public static void main(String[] args) {
String[] nameArr = {"Jones","Patel"};
String[] prefixArr = {"Mr.","Mrs.","Ms."};
String[] result = cartesianProduct(prefixArr, nameArr);
// Here you can print the result
}