help with grails map - java

I'm trying to dynamically create a map collection but I am still new to grails and was hoping someone could help me. What I want to do is parse and xml file and add the values to a map. I've got the parsing down, but just dont know how to dynamically add the node values to the map. here's what i have so far:
example xml stream:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<person>
<connections total="29">
<person>
<id>123245</id>
<first-name>me</first-name>
<last-name>you</last-name>
</person>
</connections>
</person>
I then parse it like this:
def alum = new XmlSlurper().parseText(xmlResponse)
alum.connections.person.each{ conName ->
print conName.'id'.toString() + " " + conName.'first-name'.toString() + " " + conName.'last-name'.toString() + "\n"
}
So, this allows me to iterate over, and parse, the xml stream. my question is, if i wanted to add the values, dynamically, to a map like this:
def myMap= [fName:"SomeName", lName:"Sme last Name", id:1234]
how would i do this?
Thank you
jason

If you don't know the child node names and want to use them as the keys in the map, use this:
def alum = new XmlSlurper().parseText(xmlResponse)
alum.connections.person.each { conName ->
def myMap = [:]
conName.children().each { child -> myMap[child.name()] = child.text() }
}
This will result in [id: '123245', 'first-name': 'me', 'last-name': 'you']
Unrelated: you can shorted up your debug code with a GString:
print "${conName.'id'} ${conName.'first-name'} ${conName.'last-name'}\n"

well, i ended up just using a multidimensional array, and that seems to have worked fine. Thanks again for your help
int i=0
String[][] friends = new String[test][4]
alum.connections.person.each{ conName ->
friends[i][0] =conName.'id'.toString()
friends[i][1] =conName.'first-name'.toString()
friends[i][2] =conName.'last-name'.toString()
friends[i][3] =conName.'picture-url'.toString()
i++
}
[Friends:friends]
This way, i was able to pass it on to my groovy page and iterate over the array

Related

How to loop through stream groups in Java to perform operations on Strings in each group

I have a sorted ArrayList A and used streams to group by the substring(3,7). I'm using a large dataset, so I don't know all the different substring(3,7) there are.
ArrayList A for example looks something like this (but with a lot more data): ooo122ppp, aaa122b333, zzz122bmmm, ccc9o9i333, mmm9o9i111, qqqQmQm888, 777QmQmlll, vvvjjj1sss
I need to loop through each group so that I can do something to that grouped data. I've tried for loops, if statements, etc, but can't figure it out. I've tried this, but I get an error regarding the for loop. How am I able to loop through each group I have to perform operations on the Strings in the group?
Collection<List<String>> grouped = A.stream().collect(groupingBy(ex -> ex.substring(3,7))).values();
for(int g=0; g<grouped.forEach(); g++) {
//do something
}
You can use the forEach method on Collection. It should not be confused with a regular for loop.
grouped.forEach(group -> {
group.forEach(str -> {
//do something
});
});
Are you looking for something like this?
List<String> stringList = List.of("ooo122ppp", "aaa122b333", "zzz122bmmm", "ccc9o9i333", "mmm9o9i111", "qqqQmQm888", "777QmQmlll", "vvvjjj1sss");
Map<String, List<String>> collection = stringList.stream().collect(Collectors.groupingBy(ex -> ex.substring(3, 7)));
for (Map.Entry<String, List<String>> entry : collection.entrySet()) {
System.out.println("group <" + entry.getKey() + "> strings " + entry.getValue());
}
Output
group <jjj1> strings [vvvjjj1sss]
group <122b> strings [aaa122b333, zzz122bmmm]
group <122p> strings [ooo122ppp]
group <9o9i> strings [ccc9o9i333, mmm9o9i111]
group <QmQm> strings [qqqQmQm888, 777QmQmlll]
Otherwise please try to better explain the requirement ;)

Java loop with a replaceFirst Method

this is my first post on Stack Overflow, so please, be forgiving! :)
I have a list with 403 Polish registration plates symbols and counties. It looks like this:
BIA powiat białostocki
BBI powiat bielski
BGR powiat grajewski
CT Toruń
etc.
I made a code which let me to turn the first space into "=".
import java.io.*;
public class Test {
public static void main(String args[]) {
String Str = new String("BAU powiat augustowski");
System.out.println(Str.replaceFirst(" ", "="));
}
}
How can I make a loop (for? do while?) to change all 403 records? I would appreciate any help. Thank you in advance!
If your list is a List<String>, you can do this :
for (for int i = 0, i < yourList.size(), i++) {
yourList.set(i, yourList.get(i).replaceFirst(" ", "="));
}
Other ways to loop are available here : https://crunchify.com/how-to-iterate-through-java-list-4-way-to-iterate-through-loop/
Best
You COULD also use Stream API. Eg if you want to filter all invalid strings
List<String> registrations = new ArrayList<>(5);
registrations.add("BIA powiat białostocki");
registrations.add("BBI powiat bielski");
registrations.add("BGR powiat grajewski");
registrations.add("BGGHND");
registrations.add("CT Toruń etc.");
registrations = registrations.stream()
.filter(registration -> registration.split(" ").length>1)
.map(registration -> registration.replaceFirst(" ","="))
.collect(Collectors.toList());
Output:
BIA=powiat białostocki
BBI=powiat bielski
BGR=powiat grajewski
CT=Toruń etc.
As you mentioned how can make a loop then I would suggest to learn java loop syntax at first. Following tutorial can be helpful
https://books.trinket.io/thinkjava2/chapter6.html
https://www.codingame.com/playgrounds/6162/6-ways-to-iterate-or-loop-a-map-in-java
Regarding the solution, you can loop your lists using for/while loop or using Stream API. Here is your solution using stream API:
List<String> lists = new ArrayList<>();
lists.add("BAU powiat augustowski");
lists.add("BBI powiat bielski");
lists = lists.stream()
.map(s -> s.replaceFirst("\\s", "="))
.collect(toList());
Either if you are using an ArrayList or a HashSet you can use two ways:
Fyi: assuming your lists name is registrationList and it holds Objects names Registration
Either a for loop:
for(Registration registration : registrationList){
registration.replaceFirst(" ", "=");
}
Or you can use a Stream:
registrationList.stream.forEach(registration-> registration.replaceFirst(" ", "="));
If you have all lines in txt file and you want to modify that by replacing first space to = you could use stream API like:
List<String> collect = Files.lines(Paths.get(PATH_TO_FILE)).stream()
.map(s -> s.replaceFirst(" ", "="))
.collect(toList());
Files.write(PATH_TO_FILE, collect, StandardOpenOption.CREATE);
See more StandardOpenOption

Get Pojo from a java list using parallel stream without using any kind of index

I have a Java List as follows:
FileService fileService = new FileService("testi");
List<FilePojo> list = fileService.getAllFiles();
What I want to do is iterate over the list, get FilePojo object from it and print certain properties. I can achieve that by doing something like this:
for (FilePojo filePojo : list){
System.out.println(filePojo.getId()+" "+filePojo.getName());
}
And then I stumbled across Stream api and tried refactoring my code as follows:
Stream.of(list).parallel().forEach(filePojo -> {
System.out.println(filePojo);
}
});
Using this, I cannot access the getters from filePojo (Unlike the first method), although I can see the objects like this:
[pojo.FilePojo#56528192, pojo.FilePojo#6e0dec4a, pojo.FilePojo#96def03, pojo.FilePojo#5ccddd20, pojo.FilePojo#1ed1993a, pojo.FilePojo#1f3f4916, pojo.FilePojo#794cb805, pojo.FilePojo#4b5a5ed1]
I can access getters if I use an index like this:
Stream.of(list).parallel().forEach(filePojo -> {
for (int i = 0; i < list.size(); i++) {
System.out.println("=============================\n" + "Element at " + i + "\n" + filePojo.get(i).getId() + "\n" + filePojo.get(i).getCustomerId() + "\n" + filePojo.get(i).getFileName() + "\n ========================");
}
});
Is it possible to get the Pojo from the stream of a list without using an index (similar to the first method)? or do I need to resort to indexing to solve this problem?
You can do it using streams as:
list.stream() // Stream<FilePojo>
.map(filePojo -> filePojo.getId() + " " + filePojo.getName())
.forEach(System.out::println);
Using the Stream.of, you would have to flatMap the stream since you end up creating the Stream<List<FilePojo>> instead as
Stream.of(list) // Stream<List<FilePojo>>
.flatMap(List::stream) // Stream<FilePojo>
.map(filePojo -> filePojo.getId() + " " + filePojo.getName())
.forEach(System.out::println);
Further read: Should I always use a parallel stream when possible?
You are using Stream.of() method in a wrong way, you are creating stream of lists, not of objects inside of it.
Try this one:
list.stream()
.parallel()
.forEach(filePojo -> System.out.println(filePojo.getId() + " " + filePojo.getName()));
Sure, you can create a "stream", map it then print:
list.stream()
.map(filePojo -> filePojo.getId() + " " + filePojo.getName())
.forEach(e -> System.out.println(e));
Stream.of(list) reads as "create a stream of lists" but what you want is "create a stream of elements in the list" hence the list.stream above.
Further, don't carelessly call Stream.of(list).parallel() when you're not sure that you can benefit from parallel processing, it might come back to bite you with worse performance than the sequential approach.
but in reality if all you need is the above then there is no need for this, just proceed with your approach or do:
list.forEach(f -> System.out.println(f.getId()+" "+f.getName()));
since lists have the forEach method.

Create a Java for loop to concatenate 2 sets of strings

I have
Map<String, String> prefixes
and
List<String> annotationProperties
And I am trying to get the string output of
prefix: annotationProperty
for each entry (they were entered in order).
Is there a for loop I could use to concatenate these? I need to return the entries as a List<String> to use in an XML output.
Thank you!
I assume annotationProperties is a key for prefix map. If that is the case then in Java 8 you can do this:
List<String> output = annotationProperties.stream()
.map(prop -> String.format("%s: %s", prefix.get(prop), prop))
.collect(Collectors.toList());
stream is called so you can use stream functions such as map and collect
map is called to transform the strings in annotationProperties into your desired output
and collect is called to convert the stream back into a list
If you want to use a for loop then you could also do it like this:
// The end size is known, so initialize the capacity.
List<String> output = new ArrayList<>(annotationProperties.size());
for (String prop : annotationProperties){
output.add(String.format("%s: %s", prefix.get(prop), prop));
}
Can a set a variable equal to .collect(Collectors.toList()); ?
We already have one! In both cases we made a variable output which is a list of Strings formatted as prefix: property. If you want to use this list then you can loop over it like this:
for (String mystring : output) {
// do xml creation with mystring
}
or like this:
for (int i = 0; i < output.size(); i++){
String mystring = output.get(i);
// do xml creation with mystring
}
or like this:
output.stream().forEach(mystring -> {
// do xml creation with mystring
});

Avro iterate over GenericRecord

I have a GenericRecord, and want to iterate over the entire collection of key/values. The record is a java data structure that is the equivalent of a plain json string. Eg:
{"key1":"val1","key2":val2",...} but is quite long.
The problem is, I dont know how many key,vals are inside it.
I've tried:
AvroKeyValue<String,String> kv = new AvroKeyValue<>(record);
Iterator<String,String> iterator = new AvroKeyValue.Iterator<String,String>(kv);
But this does not work.
The apache docs about it are here:
http://avro.apache.org/docs/1.7.0/api/java/org/apache/avro/hadoop/io/AvroKeyValue.Iterator.html
Use the GenericRecord's schema to list the available fields
for (Field field : record.getSchema().getFields()) {
String fieldKey = field.name();
System.out.println(fieldKey + " : " + record.get(fieldKey));
}
You can get the number of fields of a GenericRecord with:
record.getSchema().getFields().size();

Categories

Resources