I have a String as below,
String str = "ID1_RELID1, ID2_RELID2,ID3_RELID3";
I want to convert it into two Strings as below,
String ids = "'ID1','ID2','ID3'";
String relids = "'RELID1','RELID2','RELID3'";
ie spliting each value by _ and joing with comma.
I tried below code,
String str = "ID1_RELID!, ID2_RELID2,ID3_RELID3";
Map<String, String> map = Arrays.stream(str.split(","))
.collect(toMap(e -> e.split("_")[0], e -> e.split("_")[1]));
String ids = map.keySet().stream().map(e -> "'" + e + "'").collect(joining(","));
String relids = map.values().stream().map(e -> "'" + e + "'").collect(joining(","));
Its working fine but can we do it in min possible iterations ??
This is a bit off-topic answer because according to the question header a "stream" must be used which doesn't hold here. However, this approach is fast and memory friendly because there is no need to reserve memory for temporary arrays or maps.
String str = "ID1_RELID1,ID2_RELID2,ID3_RELID3";
StringTokenizer tok = new StringTokenizer(str, ",_");
StringBuilder[] sbs = new StringBuilder[] {new StringBuilder(),new StringBuilder()};
for(int i = 0; tok.hasMoreTokens(); i++) {
sbs[i%2].append(i > 1 ? ",'" : "'").append(tok.nextToken()).append("'");
}
String ids = sbs[0].toString();
String relids = sbs[1].toString();
Not sure you really need to stream here. May be a regex
and two StringBuilder
s?
public static void main(String[] args) {
String str = "ID1_RELID1, ID2_RELID2,ID3_RELID3";
StringBuilder left = new StringBuilder();
StringBuilder right = new StringBuilder();
Pattern p = Pattern.compile("(\\w+)_(\\w+)(,?)");
Matcher m = p.matcher(str);
while (m.find()) {
left.append("'").append(m.group(1)).append("'").append(",");
right.append("'").append(m.group(2)).append("'").append(",");
}
if (left.length() > 0) {
left.setLength(left.length() - 1);
right.setLength(right.length() - 1);
}
System.out.println(left);
System.out.println(right);
}
Here's a mutable reduction that performs the same in one pipeline. You assess it:
List<StringBuilder> stringBuilders = Arrays.stream(str.split(","))
.map(s -> s.split("_"))
.collect(
() -> Arrays.asList(new StringBuilder(), new StringBuilder()),
(List<StringBuilder> sb, String[] sa) -> {
sb.get(0).append("'").append(sa[0]).append("',");
sb.get(1).append("'").append(sa[1]).append("',");
},
List::addAll
);
String ids = stringBuilders.get(0).toString();
String relids = stringBuilders.get(1).toString();
In short, the above uses two StringBuilder
s, into which are accumulated the string parts (the first one holds your ids
, the second one holds your relids
). The main stream has String[]
elements, each holding the two parts of the original string elements, such as ID1_RELID1 => [ID1, RELID1]
.
The other simple way is something like this:
first split str
with two delimiters.( ,
& _
)
List<String> list = Arrays.asList(str.split("_|,"));
then join even items of list for ids
and odd items of list for relids
String ids = IntStream.rangeClosed(0,list.size()-1)
.filter(i->(i & 1) == 0)
.mapToObj(i-> String.format("'%s'", list.get(i).trim()))
.collect(Collectors.joining(","));
String relids = IntStream.rangeClosed(0,list.size())
.filter(i->(i & 1) == 1)
.mapToObj(i-> String.format("'%s'", list.get(i).trim()))
.collect(Collectors.joining(","));
if you like in one pipeline you can go with:
Map<Boolean, String> result= new HashMap();
rangeClosed(0, list.size() - 1)
.mapToObj(i -> new AbstractMap.SimpleEntry(i, list.get(i)))
.collect(partitioningBy(entry -> (int) entry.getKey() % 2 == 0,
mapping(entry -> String.format("'%s'", entry.getValue().toString().trim()),
toList())))
.forEach((k, v) -> result.put(k, String.join(",", v)));
then get result.get(true)
or result.get(false)
however IMO it is so verbose
I'd simply use a regex.
String regex = "(ID[0-9]+)_(RELID[0-9^,])";
String str = "ID1_RELID1,ID2_RELID2,ID3_RELID3";
String ids = str.replaceAll(regex, "'$1'"); // "'ID1','ID2','ID3'"
String relids = str.replaceAll(regex, "'$2'"); // "'RELID1','RELID2','RELID3'"
As you can see, you don't need a stream at all. Regular expression are very powerful for simple string manipulations.
Without using Stream, you can do it as follows:
public class Main {
public static void main(String[] args) {
String str = "ID1_RELID1, ID2_RELID2,ID3_RELID3";
String []substrs =str.split("_|,");
StringBuilder sbIds=new StringBuilder();
StringBuilder sbRelids=new StringBuilder();
for(int i=1;i<=substrs.length;i++)
if(i%2!=0)
sbIds.append("'"+substrs[i-1].trim()+"',");
else
sbRelids.append("'"+substrs[i-1].trim()+"',");
String ids=sbIds.toString().substring(0,sbIds.lastIndexOf(","));
String relids=sbRelids.toString().substring(0,sbRelids.lastIndexOf(","));
System.out.println(ids);
System.out.println(relids);
}
}
Output:
'ID1','ID2','ID3'
'RELID1','RELID2','RELID3'
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.