Given a string with repeating pattern here:
String s = NameJJ,ABC/firstname,120, NameBB,ABC/secondname,100,NameCC,ABC/thirdname,150,NameJJ,ABC/firstname,200,NameBB,ABC/secondname,300,NameCC,ABC/thirdname,500
Essentially I want way where when NameJJ and firstname are beside each other like at top it stores value beside them which is arraylist1 = [120,200].
Essentially I want way where all field with NameBB and secondname are beside each other to store the value beside them which is arraylist2 = [100,300].
Essentially I want way where all field with NameJJ and thirdname are beside each other to store the value beside them which is arraylist3 = [150,500].
I was trying to do this to say if string contains NameJJ and contains firstname should filter out value beside it but I'm confused on how I would do that, this is the code :
if (s.contains(NameJJ) && s.contains(firstname))
Pattern reg = Pattern.compile(",");
ArrayList<String> SANR = reg.splitAsStream(s)
.filter(role -> role.contains(""))
.map(String::trim)
.collect(Collectors.toCollection(ArrayList::new));
CodePudding user response:
Your String s
holds the complete data so if (s.contains(NameJJ) && s.contains(firstname))
will always be true
.
You have to split the blocks first, then look at the values.
Your data block contains 3 data each so that's the number you have to divide by in loop condition and multiply with in array access
String s = "NameJJ,ABC/firstname,120, NameBB,ABC/secondname,100,NameCC,ABC/thirdname,150,NameJJ,ABC/firstname,200,NameBB,ABC/secondname,300,NameCC,ABC/thirdname,500";
String[] split = s.split(",");
List<Integer> first = new ArrayList<>();
List<Integer> second = new ArrayList<>();
List<Integer> third = new ArrayList<>();
for (int i = 0; i < split.length / 3; i ) {
// first data block is Name..
// second block is firstname/secondname/thirdname
// third block hold the number you want
if (split[3 * i].trim().equals("NameJJ") && split[3 * i 1].trim().equals("ABC/firstname")) {
first.add(Integer.parseInt(split[3 * i 2].trim()));
} else if (split[3 * i].trim().equals("NameBB") && split[3 * i 1].trim().equals("ABC/secondname")) {
second.add(Integer.parseInt(split[3 * i 2].trim()));
} else if (split[3 * i].trim().equals("NameCC") && split[3 * i 1].trim().equals("ABC/thirdname")) {
third.add(Integer.parseInt(split[3 * i 2].trim()));
}
}
System.out.println(first);
System.out.println(second);
System.out.println(third);
Output is
[120, 200]
[100, 300]
[150, 500]
CodePudding user response:
As I've answered in a previous question of yours, whenever you're having a certain pattern repeating itself, you should use a regex to extract the sub-bits of your pattern.
Streams are not designed to keep track of a "first" or "last" element. They're mainly stateless operations, with a few exceptions for distinct
, sorted
and similar. Stateless operations start their execution even before the previous one has finished its computation. This is why they have no recollection of a first or last result and also why we cannot use them for this kind of tasks.
What you could do is to employ 3 regex to match your pattern for nameJJ, nameBB and nameCC, and use capturing groups to identity and extract every desired sub-bit.
The following 3 regex can be used to match your patterns:
(\w )JJ,(\w )\/(\w ),(\d )
(\w )BB,(\w )\/(\w ),(\d )
(\w )CC,(\w )\/(\w ),(\d )
Here is a snippet of the code implementation:
public class Main {
public static void main(String[] args) {
String s = "NameJJ,ABC/firstname,120, NameBB,ABC/secondname,100,NameCC,ABC/thirdname,150,NameJJ,ABC/firstname,200,NameBB,ABC/secondname,300,NameCC,ABC/thirdname,500";
List<Integer> listNameJJ = getList("(\\w )JJ,(\\w )\\/(\\w ),(\\d )", s);
List<Integer> listNameBB = getList("(\\w )BB,(\\w )\\/(\\w ),(\\d )", s);
List<Integer> listNameCC = getList("(\\w )CC,(\\w )\\/(\\w ),(\\d )", s);
System.out.println(listNameJJ);
System.out.println(listNameBB);
System.out.println(listNameCC);
}
public static List<Integer> getList(String regex, String str) {
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(str);
List<Integer> list = new ArrayList<>();
while (matcher.find()) {
list.add(Integer.valueOf(matcher.group(4)));
}
return list;
}
}
Here is also a link to test the code above:
CodePudding user response:
Here is another example,
public class Application {
public static void main(String[] args) throws NumberFormatException {
String st1 = "NameJJ,ABC/firstname,120, NameBB,ABC/secondname,100,NameCC,ABC/thirdname,150,NameJJ,ABC/firstname,200,NameBB,ABC/secondname,300,NameCC,ABC/thirdname,500";
String st2 = "NameKK,ZXY/kname,510, NameQQ,HLM/kname,210, NameKK,ZXY/kname,210,";
// Test 1
System.out.println(getValues("NameJJ", "firstname", st1));
// Test 2
System.out.println(getValues("NameKK", "kname", st2));
}
static List<Integer> getValues(String str1, String str2, String inputString) {
Pattern p = Pattern.compile("-?\\d (,\\d )*?\\.?\\d ?");
List<String> value = new ArrayList<String>();
Matcher m = p.matcher(inputString);
while (m.find()) {
value.add(m.group());
}
List<String> key = List.of(inputString.split("\\d "));
List<Integer> result = new ArrayList<Integer>();
for (int i = 0; i < value.size(); i ) {
if (key.get(i).trim().contains(str1) && key.get(i).trim().contains(str2)) {
result.add(Integer.parseInt(value.get(i).trim()));
}
}
return result;
}
}
Console O/P:
[120, 200]
[510, 210]