Reputation: 4418
I have one string for example :
2014@2@200@0#2014@2@200@0#2012@2@200@0#2012@2@200@0#2011@2@200@0
Now what I need to store the above details into one map with below rule:
For example if we split above string using # then we can get below data into string array :
array[0] = "2014@2@200@0";
array[1] = "2014@2@200@0";
array[2] = "2012@1@100@0";
array[3] = "2012@3@200@0";
array[4] = "2011@2@200@0";
Now again split the array data using '@'.
So we get :
a[0] = "2014";
a[1] = "2";
a[2] = "200";
a[3] = "0";
Map look like : Map"String, TestClass" test;
TestClass {
String a1;
String a2;
String s3;
String a4;
}
Map key : a[0] value
I need to group those data by a[0] value.
For example map data for 2014 key :
key : 2014
value : a4 = 2014, a1 = 2+2, a2 = 200 + 200, a3 = 0 + 0
key : 2012
value : a4 = 2012, a1 = 1+3, a2 = 100 + 200, a3 = 0 + 0
How to achieve the above case?
Upvotes: 1
Views: 74
Reputation: 4031
Here is a short solution using Java 8:
TestSplit.java
import java.util.stream.Stream;
public class TestSplit {
public static void main (String... args) {
Map<String, TestClass> map = split("2014@2@200@0#2014@2@200@0#2012@1@100@0#2012@3@200@0#2011@2@200@0");
map.forEach((key, value) -> System.out.println(key + " -> " + value));
}
private static Map<String, TestClass> split(String input) {
String[] testClassStrings = input.split("#");
Stream<String[]> testClassStringsStream = Arrays.stream(testClassStrings).map(s -> s.split("@"));
Stream<TestClass> testClasses = testClassStringsStream.map(s -> new TestClass(s[0], s[1], s[2], s[3]));
Map<String, TestClass> testClassesMap = new HashMap<>();
testClasses.forEach((TestClass tc) -> {
TestClass oldValue = testClassesMap.get(tc.a0);
testClassesMap.put(tc.a0, oldValue == null ? tc : new TestClass(oldValue, tc));
});
return testClassesMap;
}
}
TestClass.java
class TestClass {
String a0;
String a1;
String a2;
String a3;
public TestClass(String a0, String a1, String a2, String a3) {
this.a0 = a0;
this.a1 = a1;
this.a2 = a2;
this.a3 = a3;
}
public TestClass(TestClass tc1, TestClass tc2) {
this.a0 = tc1.a0;
this.a1 = tc1.a1 + " + " + tc2.a1;
this.a2 = tc1.a2 + " + " + tc2.a2;
this.a3 = tc1.a3 + " + " + tc2.a3;
}
@Override
public String toString() {
return String.format("a0 = %s, a1 = %s, a3 = %s, a4 = %s", a0, a1, a2, a3);
}
}
All you need to do is invoke the split
method in the TestSplit
class. The method should be concise and readable, but with a bit more effort you can make it even more functional. Here are the precise steps:
Split the string using #
(line String[] testClassStrings = input.split("#");
). That will perform the following transformation: "2014@2@200@0#2014@2@200@0#2012@1@100@0#2012@3@200@0#2011@2@200@0"
to
testClassStrings[0] = "2014@2@200@0"
testClassStrings[1] = "2014@2@200@0"
testClassStrings[2] = "2012@1@100@0"
testClassStrings[3] = "2012@3@200@0"
testClassStrings[4] = "2011@2@200@0"
Split each string using @
. (line Stream<String[]> testClassStringsStream = Arrays.stream(testClassStrings).map(s -> s.split("@"));
. Now you have a stream where each entry is an array of something like ["2014", "2", "200", "0"]
.
From each string build a new TestClass
with the line Stream<TestClass> testClasses = testClassStringsStream.map(s -> new TestClass(s[0], s[1], s[2], s[3]));
.
Iterate over all test classes and add them to the map testClassesMap
. In case certain test class is already contained in the map, apply the addition of its elements:
Map<String, TestClass> testClassesMap = new HashMap<>();
testClasses.forEach((TestClass tc) -> {
TestClass oldValue = testClassesMap.get(tc.a0);
testClassesMap.put(tc.a0, oldValue == null ? tc : new TestClass(oldValue, tc));
});
Running the main method in TestSplit
will produce:
2014 -> a0 = 2014, a1 = 2 + 2, a3 = 200 + 200, a4 = 0 + 0
2012 -> a0 = 2012, a1 = 1 + 3, a3 = 100 + 200, a4 = 0 + 0
2011 -> a0 = 2011, a1 = 2, a3 = 200, a4 = 0
Upvotes: 1
Reputation: 29316
You can use Java - 8 Stream to accomplish it, as follows:
Stream.of(str.split("#")).map(e -> e.split("@")).map(x -> new TestClass(x[1], x[2], x[3], x[0])).collect(Collectors.toMap(TestClass::getA4, z -> z,(p1, p2) -> p1));
Example implementation though you have to tweak logic a bit:
SplitString.java
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class SplitString {
public static void main(String[] args) {
Map<String, TestClass> map = Stream.of(str.split("#")).map(e -> e.split("@")).map(x -> new TestClass(x[1], x[2], x[3], x[0])).collect(Collectors.toMap(TestClass::getA4, z -> z,(p1, p2) -> p1));
System.out.println(map);
}
}
TestClass.java
public class TestClass {
private final String a1;
private final String a2;
private final String a3;
private final String a4;
public TestClass(String a1, String a2, String a3, String a4) {
this.a1 = a1;
this.a2 = a2;
this.a3 = a3;
this.a4 = a4;
}
public String getA1() {
return a1;
}
public String getA2() {
return a2;
}
public String getA3() {
return a3;
}
public String getA4() {
return a4;
}
@Override
public String toString() {
return "TestClass [a4=" + a4 + ", a1=" + a1 + ", a2=" + a2 + ", a3="
+ a3 + "]";
}
}
Output:
{2014=TestClass [a4=2014, a1=2, a2=200, a3=0], 2012=TestClass [a4=2012, a1=2, a2=200, a3=0], 2011=TestClass [a4=2011, a1=2, a2=200, a3=0]}
Upvotes: 0
Reputation: 48733
You need to create a custom method that joins all the grouped TestClass field data.
In Java 8, you can easily map/join data using the stream interface.
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
public class DataMapper {
public static String data = "2014@2@200@0#2014@2@200@0#2012@1@100@0#2012@3@200@0#2011@2@200@0";
public static void main(String[] args) {
Map<String, List<TestClass>> map = parse(data, "#", "@");
Iterator<Map.Entry<String, List<TestClass>>> iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, List<TestClass>> key = iterator.next();
String a1 = joinInstanceFieldValues(key.getValue(), t -> t.getA1(), " + ");
String a2 = joinInstanceFieldValues(key.getValue(), t -> t.getA2(), " + ");
String a3 = joinInstanceFieldValues(key.getValue(), t -> t.getA3(), " + ");
System.out.printf("key : %4$s%nvalue : a4 = %4$s, a1 = %1$s, a2 = %2$s, a3 = %3$s %n%n", a1, a2, a3, key.getKey());
}
}
public static Map<String, List<TestClass>> parse(String data, String delimOuter, String delimInner) {
Map<String, List<TestClass>> result = new HashMap<>();
String tokens[] = data.split(delimOuter);
for (String value : tokens) {
TestClass test = TestClass.parse(value, delimInner);
String key = test.getA4();
List<TestClass> list = result.containsKey(key) ? result.get(key) : new ArrayList<>();
list.add(test);
result.put(key, list);
}
return result;
}
private static <T> String joinInstanceFieldValues(List<T> list, Function<T, String> func, String delimiter) {
return list.stream().map(func).collect(Collectors.joining(delimiter));
}
}
public class TestClass {
private String a1;
private String a2;
private String a3;
private String a4;
public String getA1() { return a1; }
public String getA2() { return a2; }
public String getA3() { return a3; }
public String getA4() { return a4; }
public TestClass(String a1, String a2, String a3, String a4) {
this.a1 = a1;
this.a2 = a2;
this.a3 = a3;
this.a4 = a4;
}
@Override
public String toString() {
return String.format("a4 = %4$s, a1 = %1$s, a2 = %2$s, a3 = %3$s", a1, a2, a3, a4);
}
public static TestClass parse(String input, String delimiter) throws IllegalArgumentException {
String[] data = input.split(delimiter);
if (data.length != 4) {
throw new IllegalArgumentException("Invalid number of tokens: " + data.length);
}
return new TestClass(data[1], data[2], data[3], data[0]);
}
}
key : 2014
value : a4 = 2014, a1 = 2 + 2, a2 = 200 + 200, a3 = 0 + 0
key : 2012
value : a4 = 2012, a1 = 1 + 3, a2 = 100 + 200, a3 = 0 + 0
key : 2011
value : a4 = 2011, a1 = 2, a2 = 200, a3 = 0
Upvotes: 0
Reputation: 1556
Try this
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
public class Test
{
String a1;
String a2;
String a3;
String a4;
Test(String[] str)
{
a1=str[0];
a2=str[1]+"+"+str[1];
a3=str[2]+"+"+str[2];
a4=str[3]+"+"+str[3];
}
public static void main(String[] args)
{
String str="2014@2@200@0#2014@2@200@0#2012@2@200@0#2012@2@200@0#2011@2@200@0";
String arr[]=str.split("#");
Map<String,Test> map=new HashMap<String,Test>();
for (String value : arr)
{
String s[]=value.split("@");
Test test=new Test(s);
map.put(s[0], test);
}
for (Iterator iterator = map.entrySet().iterator(); iterator.hasNext();)
{
Entry key=(Entry) iterator.next();
Test t1=map.get(key.getKey());
System.out.println("Map Key:"+key.getKey());
System.out.print("\ta1: "+t1.a1);
System.out.print("\ta2: "+t1.a2);
System.out.print("\ta3: "+t1.a3);
System.out.print("\ta4: "+t1.a4);
System.out.println();
}
}
}
Output:
Map Key:2014
a1:2014 a2:2+2 a3:200+200 a4:0+0
Map Key:2012
a1:2012 a2:2+2 a3:200+200 a4:0+0
Map Key:2011
a1:2011 a2:2+2 a3:200+200 a4:0+0
Upvotes: 0