How to generate HBase java Put class from String Array? - java

I am newbie on Java 8 lambda and stream programming. This is simple source which generate HBase Put class from String array.
List<String> list = new ArrayList<>(5);
list.add("1," + "colFamily" + ",a,1");
list.add("2," + "colFamily" + ",a,2");
list.add("3," + "colFamily" + ",a,3");
list.add("4," + "colFamily" + ",a,4");
list.add("5," + "colFamily" + ",a,5");
for (int i=0 ; i<list.size() ; i++) {
String[] cells = list.get(i).split(",");
Put put = new Put(Bytes.toBytes(cells[0]));
put.addColumn(Bytes.toBytes(cells[1]),Bytes.toBytes(cells[2]),Bytes.toBytes(cells[3]));
System.out.println(put);
Results are generated correctly like below,
{"totalColumns":1,"row":"1","families":{"colFamily":[{"qualifier":"a","vlen":1,"tag":[],"timestamp":9223372036854775807}]}}
{"totalColumns":1,"row":"2","families":{"colFamily":[{"qualifier":"a","vlen":1,"tag":[],"timestamp":9223372036854775807}]}}
{"totalColumns":1,"row":"3","families":{"colFamily":[{"qualifier":"a","vlen":1,"tag":[],"timestamp":9223372036854775807}]}}
{"totalColumns":1,"row":"4","families":{"colFamily":[{"qualifier":"a","vlen":1,"tag":[],"timestamp":9223372036854775807}]}}
{"totalColumns":1,"row":"5","families":{"colFamily":[{"qualifier":"a","vlen":1,"tag":[],"timestamp":9223372036854775807}]}}
But by using Java 8 stream, I failed to generate the same results, below is the codes.
System.out.println(list.stream().collect(Collectors.mapping(l -> new Put(Bytes.toBytes(l)), Collectors.toList())));
But definitely the above code brings the wrong results.
[{"totalColumns":0,"row":"1,colFamily,a,1","families":{}}, {"totalColumns":0,"row":"2,colFamily,a,2","families":{}}, {"totalColumns":0,"row":"3,colFamily,a,3","families":{}}, {"totalColumns":0,"row":"4,colFamily,a,4","families":{}}, {"totalColumns":0,"row":"5,colFamily,a,5","families":{}}]
I have no idea how to split comma-seperated-Strings to String array using java 8 stream function.

How about this:
list
.stream()
.map(s -> s.split(","))
.map(cells -> {
Put put = new Put(Bytes.toBytes(cells[0]));
put.addColumn(Bytes.toBytes(cells[1]), Bytes.toBytes(cells[2]), Bytes.toBytes(cells[3]));
return put;
})
.forEach(System.out::println) // or .collect to list

Related

Gatling feed an ArrayList of random strings

I have gatling script to send HTTP request with an array of 10,000 email addresses, the JSON body is like this one:
{
"userIds": [
"user1#paragonia.com",
"user2#bedlam.com",
"user3#blurrybus.com",
"user4#barkarama.com",
"user5#bullzone.com",
.
.
.
"user10000#miraclis.com"
]
}
So, I generate an ArrayList of 10,000 random email addresses:
val emails = new util.ArrayList[String]
for(i <- 1 to 10000) {
emails.add("\"" + Random.alphanumeric.take(8).mkString.toLowerCase +
"#" + Random.alphanumeric.take(10).mkString.toLowerCase + ".com\"")
}
And I need to feed that ArrayList into my scenario:
val scn = scenario("Add Users")
.exec(
http("AddUsers")
.post(path)
.header("Authorization", apiKey)
.body(StringBody("{" +
"\n\t\"userIds\": " +
userNames +
"\n\t\n" +
"}")).asJson
)
The problem is that the same array sent to all the requests in my scenario, and I need to generate a different array every time.
I guess I need to convert my ArrayList to a feeder or an Iterator but I'm stuck on it.
Is it possible to do such thing in Gatling?
I found the answer.
I created a function to build the ArrayList of random emails:
def getEmailsArray(count: Integer): util.ArrayList[String] = {
val emails = new util.ArrayList[String]
for (i <- 1 to count) {
emails.add("\"" + Random.alphanumeric.take(8).mkString.toLowerCase +
"#" + Random.alphanumeric.take(10).mkString.toLowerCase + ".com\"")
}
emails
}
Then I get the ArrayList into a feeder:
val emailsFeeder = Iterator.continually(Map("emails" -> getEmailsArray(totalEmails)))

How to do Collectors.groupingBy equivalent in Java 6?

I have a List<UserVO>
Each UserVO has a getCountry()
I want to group the List<UserVO> based on its getCountry()
I can do it via streams but I have to do it in Java6
This is in Java8. I want this in Java6
Map<String, List<UserVO>> studentsByCountry
= resultList.stream().collect(Collectors.groupingBy(UserVO::getCountry));
for (Map.Entry<String, List<UserVO>> entry: studentsByCountry.entrySet())
System.out.println("Student with country = " + entry.getKey() + " value are " + entry.getValue());
I want output like a Map<String, List<UserVO>>:
CountryA - UserA, UserB, UserC
CountryB - UserM, User
CountryC - UserX, UserY
Edit: Can I further reschuffle this Map so that I display according to the displayOrder of the countries. Display order is countryC=1, countryB=2 & countryA=3
For example I want to display
CountryC - UserX, UserY
CountryB - UserM, User
CountryA - UserA, UserB, UserC
This is how you do it with plain Java. Please note that Java 6 doesn't support the diamond operator so you have use <String, List<UserVO>> explicitly all the time.
Map<String, List<UserVO>> studentsByCountry = new HashMap<String, List<UserVO>>();
for (UserVO student: resultList) {
String country = student.getCountry();
List<UserVO> studentsOfCountry = studentsByCountry.get(country);
if (studentsOfCountry == null) {
studentsOfCountry = new ArrayList<UserVO>();
studentsByCountry.put(country, studentsOfCountry);
}
studentsOfCountry.add(student);
}
It's shorter with streams, right? So try to upgrade to Java 8!
To have a specific order based on the reversed alphabetical String, as mentioned in the comments, you can replace the first line with the following:
Map<String,List<UserVO>> studentsByCountry = new TreeMap<String,List<UserVO>>(Collections.reverseOrder());

Aggregating a Map object within another Object

Edited version! From a PC instead of my phone.
I have a Class defined with following attributes:
Here is the code I have for a sample Map without being part of another class:
List<Map<String,Long>> amountList = new ArrayList<>();
Map<String, Long> amountMap = new HashMap<>();
for(int i=0; i<2;i++ ) {
amountMap.put("AMOUNT1", 12L);
amountMap.put("AMOUNT2", 10L);
amountMap.put("AMOUNT3", 10L);
amountMap.put("AMOUNT4", 12L);
amountMap.put("AMOUNT5", 10L);
amountList.add(amountMap);
}
Map<String, Long> collectset = amountList.stream()
.flatMap(entry -> entry.entrySet().stream())
.collect(toMap(Map.Entry::getKey, Map.Entry::getValue, Long::sum));
for (String str : collectset.keySet()){
System.out.println( "output: " + str + " -> " + collectset.get(str));
}
I need a result from this where the output is just as below:
output: AMOUNT3 -> 20
output: AMOUNT2 -> 20
output: AMOUNT1 -> 24
output: AMOUNT5 -> 20
output: AMOUNT4 -> 24
What I get as a result of the code above is that the values are repeating twice.
Is there a way to only output the Sum equivalent once. For instance, if the loop is changed to produce 5 Maps - I see the output printed 5 times.
Make an info object containing three strings and use that as your key value (don't forget to override hashCode if needed). Or simply use a format (such as CSV) to concatinate your strings together and then use that string as a key.
I was able to find the issue. There was a for loop just before the Stream implementation which caused to print the output based on how many times I was looping through the loop.
Here is the updated code:
List<Map<String,Long>> countList = new ArrayList<>();
Map<String, Long> countMap = new HashMap<>();
Random random = new Random();
for(int i=0; i<500;i++ ) {
countMap.put("COUNT" + random.nextInt(10), 12L);
countMap.put("COUNT" + random.nextInt(10), 10L);
countMap.put("COUNT" + random.nextInt(10), 10L);
countMap.put("COUNT" + random.nextInt(10), 12L);
countMap.put("COUNT" + random.nextInt(10), 10L);
countList.add(countMap);
}
Map<String, Long> collectset = countList.stream()
.flatMap(entry -> entry.entrySet().stream())
.collect(toMap(Map.Entry::getKey, Map.Entry::getValue, Long::sum));
System.out.println( "CollectSet Size: " + collectset.size());

How do I check if any arraylist contains specific string

I am trying with below code :
public void verifyCategorySlugsInSearchcall(BaseDTO baseDTO, String jsonResponse) {
List<String> categoryList = JsonPath.read(jsonResponse,
"response.groups.DEFAULT_GROUP.documents[*].categorySlugs[*]");
CustomReporter.reportInfoWithOutLineBreak("Category from search call Response:" + categoryList);
Assert.assertTrue(categoryList.size() > 0, "No category slug name was displayed.");
CustomReporter.reportInfoWithOutLineBreak("Category Slug from search call Response:" + categoryList);
Assert.assertTrue(categoryList.contains(baseDTO.getPsCallDetails().getCategory()),
"Category Name was not matching. Actual:" + categoryList + ".Expected:"
+ baseDTO.getPsCallDetails().getCategory());
}
My arrayalist contains all category name :
eg: ["apple-tv-apple-tv-4k","apple-tv-apple-tv-4k","apple-tv-apple-tv"]
Need to search apple-tv contains in this array. My code is giving error as not contains apple-tv in particular category.
Using streams:
boolean result = categoryList.stream()
.anyMatch(c -> c.contains("apple-tv"));
If you instead want to generate a new list containing only categories having apple-tv somewhere in the name, then use filter:
List<String> output = categoryList.stream()
.filter(c -> c.contains("apple-tv"))
.collect(Collectors.toList());

Graphviz language from jsp view Dynamic

I have some roles and each roles have users.
So my problem is according to the no. of roles and no. of users selected i have to create a graph using graphviz.
Graphviz language is like (A -> B;)(B -> C;)(B -> D;)(C -> E;)(D -> E;)(E -> F)
So i have to create a graph language according to no of roles i have and no. of users i selected...
The incoming string is like = (1CS_3Admin_1BOD_2SH_1Others).
And the graph for this language myst be like this:-
marapet This is what i am doing.
My language is like 1CS_3Admin_1BOD_2SH_1Others Where 1,3,1,2 is the no of users selected e.g 1CS means one user for CS role. Now i split them with '_' as delimiter . Now i get a string array . So the real problem is to make a language from this string array values.
Here 'name' is the string i am getting:-
Graphviz gv = new Graphviz();
gv.addln(gv.start_graph());
gv.addln("Start;");
if(name.startsWith("_"));
name=name.substring(1);
String[] str=null;
if(name.contains("_"))
str = name.split("_");
int sPreviousRepeat=0;
String sPrevious="";
int sCurrRepeat=0;
String sCurr="";
String finalInst="Start -> ";
for(int i=0;i<str.length;i++) {
sCurrRepeat=Integer.parseInt(String.valueOf(str[i].charAt(0)));
sCurr=str[i].substring(1);
if(i!=0){
sPreviousRepeat = Integer.parseInt(String.valueOf(str[i-1].charAt(0)));
sPrevious = str[i-1].substring(1);
}
if(sCurrRepeat==1){
if(i==0)
finalInst=finalInst+sCurr+";";
else
finalInst=finalInst + sPrevious+" -> "+sCurr+";";
}
else{
for(int j=0;j<sCurrRepeat;j++){
//cant figure out?????
}
}
}
Here's how I'd break down the problem:
Parse the input string into a data structure representing n ordered pairs of role and number of users
Creating the syntax of the graph (graphviz dot) from the data structure in #1
Transform the graphviz syntax into an actual image
You'll need to learn the following:
Graphviz syntax
Making a simple Java command line program
Parsing and manipulating strings in Java (split etc.)
Invoking an executable from java (dot.exe)
I think i make it.
if(name.contains("_"))
str = name.split("_");
int sPreviousRepeat=0;
String sPrevious="";
int sCurrRepeat=0;
String sCurr="";
String finalInst="Start -> ";
for(int i=0;i<str.length;i++) {
sCurrRepeat=Integer.parseInt(String.valueOf(str[i].charAt(0)));
sCurr=str[i].substring(1);
if(i!=0){
sPreviousRepeat = Integer.parseInt(String.valueOf(str[i-1].charAt(0)));
sPrevious = str[i-1].substring(1);
}
if(sCurrRepeat==1){
if(i==0)
finalInst=finalInst+sCurr+";";
else if(sPreviousRepeat>1){
for(int j=0;j<sPreviousRepeat;j++)
finalInst=finalInst + sPrevious+(j+1)+" -> "+sCurr+";";
}
else
finalInst=finalInst + sPrevious+" -> "+sCurr+";";
}
else{
for(int j=0;j<sCurrRepeat;j++){
finalInst=finalInst + sPrevious+" -> "+sCurr+(j+1)+";";
}
}
}

Categories

Resources