For of to forEach -> lambda expression - java

I have a "for of" on my java code and Im trying to convert to a "for each" with a lambda expression.
for (Bicycle element : bicycleList) {
txtOutput.append("Model:" + element.getModel() + "\n");
}
I have tried to do this:
bicycleList.forEach(txtOutput.append -> ("Model:" + bicycle.getModel() + "\n"));
Can anyone help me?

bicycleList.forEach(element -> txtOutput.append ("Model:" + element.getModel() + "\n"));

You could alternatively use streams as :
String txtOutput = bicycleList.stream()
.map(element -> "Model:" + element.getModel() + "\n")
.collect(Collectors.joining("", "", ""));

Related

Need a way to get to get the pattern in a string matched with List.stream().anyMatch()

I'm matching a list of strings against a list of keywords. The goal is to get a string only one time if it has any of the keywords in it.
Actually I'm doing it with this loop:
for (int i = 0; i < keywords.size(); i++) {
if (text.toLowerCase().contains(keywords.get(i))) {
System.out.println("keyword >>> " + keywords.get(i)
+ " text >>> " + text);
break;
}
}
I like to know if there is a way to get the keyword if I'm using the java stream API like so:
if (keywords.stream().anyMatch(text.toLowerCase()::contains)) {
System.out.println("keyword >>> " + "how to get the keyword here"
+ " text >>> " + text);
}
anyMatch returns a boolean
Using .filter() & findFirst() you can retrieve a value. Note that if you use findFirst() you get an Optional<String> and could either use ifPresent() like this:
keywords.stream()
.filter(keyword -> text.toLowerCase().contains(keyword))
.findFirst()
.ifPresent(keyWord -> System.out.println("[2] keyword >>> " + keyWord + " text >>> " + text));
Or with Optional.isPresent() & Optional.get():
Optional<String> firstKey = keywords.stream()
.filter(keyword -> text.toLowerCase().contains(keyword))
.findFirst();
if (firstKey.isPresent()) {
System.out.println("[2] keyword >>> " + firstKey.get() + " | text >>> " + text);
}
As a less fancy alternative to stream there is a nicer for syntax in Java 1.6+
for(String keyword: keywords) {
if (text.toLowerCase().contains(keyword)) {
System.out.println("keyword >>> " + keyword
+ "text >>> " + text);
break;
}
}
I find the for syntax easier to read than the stream syntax. In a previous job I did a lot of C++ lambda functions with BOOST and the code was hard to parse, and the errors hard to trace.
Another option would be to print an informational message if the keyword was not found. This is easily done by moving the isPresent test inside the print statement.
List<String> keywords =
Arrays.asList("now", "is", "the", "time");
String text = "what are your names?";
Optional<String> opt = keywords.stream()
.filter(keyword -> text
.toLowerCase().contains(keyword))
.findFirst();
System.out.println(!opt.isPresent() ? "No keyword was found!" :
"keyword >>> " + opt.get()
+ " text >>> " + text);
Prints
No keyword was found!

using system.out.print with java streams

I have the below code to map each entry to a print statement, But it shows error.
Is something wrong in the way I understood Stream().map()?
How do I use System.out.println() within the streams API? how do I correct the following code?
public static void main(String[] args) {
Properties p = new Properties();
p.setProperty("name", "XYX");
p.setProperty("email", "xyx#mail.com");
p.setProperty("address", "addr-street-city");
p.entrySet().stream().map(e ->
System.out.println(" " + e.getKey().toString() + " " + e.getValue().toString() + ""));
}
If you want to use map:
p.entrySet().stream()
.map(e -> " "+e.getKey()+" "+e.getValue())
.forEach(System.out::println);
p.entrySet().forEach(e -> System.out.println(e.getKey() + " " + e.getValue()));
or
p.forEach((key, value) -> System.out.println(key + " " + value));
properties.entrySet().stream()
.map(entry -> String.format("%s : %s", entry.getKey(), entry.getValue()))
.forEach(System.out::println);
.map(...) - convert you key-value to a string format
.forEach(...) - prints your string
Your output should look like that :
address : addr-street-city
email : xyx#mail.com
name : XYX
p.entrySet().forEach(System.out::println)
map() should be used only if you want to alter/modify stream otherwise
for printing to the console forEach would do the work as it accepts BiConsumer to print key and value

Java Flux GroupedFlux count() print

Hi rectors all aver the world. I'm doing reactivi programming in Java. I'm a java/grails/react developer but first steps with reactive programming with Spring Boot, version 2 M7 in this case. In the next code:
#GetMapping(API_BASE_PATH + "/flux4")
public String flux4() {
StringBuilder sb = new StringBuilder();
Flux.just("alpha", "bravo", "charlie")
.map(String::toUpperCase)
.flatMap(s -> Flux.fromArray(s.split("")))
.groupBy(String::toString)
.sort(Comparator.comparing(GroupedFlux::key))
.map(group -> group.key() + " => " + group.count() + "; ")
.subscribe(sb::append);
return "flux 4: " + sb.toString();
}
I get the group.key() printed but how caon I get printed the group.count() ?
Any help is welcome
Cheers
Juan
I think I am reading the same book as you :)
Here is the solution using block().
Flux.just("alpha", "beta", "charlie")
.map(String::toUpperCase)
.flatMap(s -> Flux.fromArray(s.split("")))
.groupBy(String::toString)
.sort((o1,o2) -> o1.key().compareTo(o2.key()))
.flatMap(group -> Mono.just(Tuples.of(group.key(), group.count().block())))
.map(keyAndCount -> keyAndCount.getT1() + " => " + keyAndCount.getT2() + "; ")
I am wondering if there is an alternate way that doesn't call block()?. Now group.count() returns a Mono<Long>, and group.key() returns a String. It would be good if we could combine the two to form a Mono<Tuple2<String, Long>> without having to evaluate the result of the Mono. Seems like there should be a general method for doing that?
The book tried to use:
Mono.just(group.key()).and(group.count())
But that just listens for the completion events and returns a Mono<Void>, and therefore gives me compile errors...
Addendum: found it! Use the zip method:
Flux.just("alpha", "beta", "charlie")
.map(String::toUpperCase)
.flatMap(s -> Flux.fromArray(s.split("")))
.groupBy(String::toString)
.sort((o1,o2) -> o1.key().compareTo(o2.key()))
.flatMap(group -> Mono.zip(Mono.just(group.key()), group.count()))
.map(keyAndCount -> keyAndCount.getT1() + " => " + keyAndCount.getT2() + "; ")

why is "+" added to all my coordinates in url builder?

I have this code to build a string of coordinates:
public String generateUrl(CompleteRoutingResponseShort completeRoutingResponse) {
if (completeRoutingResponse == null)
{
return "CompleteRoutingResponse is null";
}
UriBuilder builder = UriBuilder
.fromPath(Constants.LIVEMAP_BASE_URL)
.scheme("http");
builder.queryParam("lineGeom", getCoordsLists(completeRoutingResponse));
return builder.build().toString();
}
private String getCoordsLists() {
List<String> lists = new ArrayList<>();
for (AlternativeShort alternative : completeRoutingResponses.alternatives)
{
String list = "( " + alternative.coords.stream().map(item -> String.format("%.4f , %.4f", item.x, item.y))
.collect(Collectors.joining(", ")) + ")";
// list.replace("+","");
lists.add(list);
}
return String.join(", ", lists);
}
however I get this url as an output:
"http:/myhost.com/tiles/internal?lineGeom=(+34.9178+,+31.9550,+34.9175+,+31.9552,+34.9174+,+31.9553,+34.9172+,+31.9555,+34.9171+,+31.9556,+34.9171+,+31.9556,+34.9168+,+31.9559,+34.9168+,+31.9559,+34.9167+,+31.9561,+34.9165+,+31.9562,+34.9164+,+31.9564,+34.9161+,+31.9567,+34.9161+,+31.9568,+34.9160+,+31.9570,+34.9159+,+31.9571,+34.9158+,+31.9572,+34.9158+,+31.9573,+34.9157+,+31.9574,+34.9157+,+31.9574,+34.9166+,+31.9577,+34.9166+,+31.9577,+34.9178+,+31.9581,+34.9184+,+31.9583,+34.9188+,+31.9583,+34.9192+,+31.9584,+34.9195+,+31.9585,+34.9201+,+31.9585,+34.9204+,+31.9585,+34.9208+,+31.9585,+34.9211+,+31.9585,+34.9214+,+31.9585,+34.9216+,+31.9585,+34.9222+,+31.9584,+34.9224+,+31.9584,+34.9227+,+31.9583,+34.9233+,+31.9582,+34.9233+,+31.9582,+34.9238+,+31.9580,+34.9246+,+31.9577,+34.9257+,+31.9572,+34.9262+,+31.9571,+34.9265+,+31.9569,+34.9266+,+31.9569,+34.9268+,+31.9569,+34.9271+,+31.9568,+34.9276+,+31.9567,+34.9281+,+31.9566,+34.9284+,+31.9566,+34.9289+,+31.9566,+34.9307+,+31.9565,+34.9314+,+31.9564,+34.9320+,+31.9564,+34.9325+,+31.9563,+34.9325+,+31.9563,+34.9330+,+31.9563,+34.9335+,+31.9563,+34.9340+,+31.9562,+34.9345+,+31.9562,+34.9345+,+31.9562,+34.9357+,+31.9560,+34.9361+,+31.9560,+34.9365+,+31.9559,+34.9365+,+31.9559,+34.9369+,+31.9559,+34.9373+,+31.9558,+34.9373+,+31.9558,+34.9376+,+31.9557,+34.9377+,+31.9556,+34.9382+,+31.9554,+34.9387+,+31.9549,+34.9387+,+31.9549,+34.9389+,+31.9547,+34.9394+,+31.9542,+34.9394+,+31.9542,+34.9395+,+31.9543,+34.9395+,+31.9543,+34.9398+,+31.9545,+34.9399+,+31.9546,+34.9399+,+31.9546,+34.9401+,+31.9548,+34.9407+,+31.9555,+34.9414+,+31.9565,+34.9417+,+31.9571,+34.9417+,+31.9571,+34.9418+,+31.9572,+34.9418+,+31.9572,+34.9420+,+31.9578,+34.9420+,+31.9579,+34.9421+,+31.9585,+34.9421+,+31.9585,+34.9421+,+31.9590,+34.9421+,+31.9599,+34.9421+,+31.9599,+34.9422+,+31.9607,+34.9422+,+31.9608,+34.9423+,+31.9609,+34.9423+,+31.9610,+34.9423+,+31.9610,+34.9423+,+31.9611,+34.9424+,+31.9611,+34.9425+,+31.9612,+34.9426+,+31.9613,+34.9426+,+31.9613,+34.9426+,+31.9613,+34.9429+,+31.9616,+34.9432+,+31.9618,+34.9436+,+31.9621,+34.9449+,+31.9630,+34.9449+,+31.9630,+34.9487+,+31.9649,+34.9487+,+31.9649,+34.9525+,+31.9668,+34.9525+,+31.9668,+34.9531+,+31.9671,+34.9535+,+31.9672,+34.9538+,+31.9674,+34.9542+,+31.9676,+34.9546+,+31.9678,+34.9550+,+31.9680,+34.9553+,+31.9682,+34.9554+,+31.9682,+34.9558+,+31.9684,+34.9566+,+31.9689,+34.9570+,+31.9691,+34.9573+,+31.9694,+34.9579+,+31.9698,+34.9582+,+31.9701,+34.9586+,+31.9704,+34.9591+,+31.9709,+34.9594+,+31.9713,+34.9599+,+31.9720,+34.9602+,+31.9725,+34.9605+,+31.9730,+34.9608+,+31.9736,+34.9610+,+31.9742,+34.9612+,+31.9746,+34.9613+,+31.9752,+34.9614+,+31.9756,+34.9615+,+31.9764,+34.9627+,+31.9857,+34.9630+,+31.9883,+34.9632+,+31.9892,+34.9634+,+31.9902,+34.9637+,+31.9912,+34.9654+,+31.9961,+34.9658+,+31.9974,+34.9659+,+31.9979,+34.9660+,+31.9984,+34.9662+,+31.9994,+34.9663+,+32.0002,+34.9664+,+32.0011,+34.9671+,+32.0154,+34.9671+,+32.0166,+34.9671+,+32.0169,+34.9671+,+32.0176,+34.9670+,+32.0179,+34.9669+,+32.0185,+34.9668+,+32.0192,+34.9666+,+32.0198,+34.9663+,+32.0206,+34.9660+,+32.0211,+34.9656+,+32.0218,+34.9652+,+32.0225,+34.9649+,+32.0229,+34.9644+,+32.0236,+34.9627+,+32.0256,+34.9607+,+32.0279,+34.9602+,+32.0285,+34.9596+,+32.0292,+34.9587+,+32.0300,+34.9534+,+32.0351,+34.9530+,+32.0356,+34.9525+,+32.0361,+34.9520+,+32.0368,+34.9515+,+32.0374,+34.9414+,+32.0522,+34.9408+,+32.0531,+34.9404+,+32.0539,+34.9399+,+32.0548,+34.9396+,+32.0555,+34.9392+,+32.0567,+34.9381+,+32.0603,+34.9381+,+32.0603,+34.9357+,+32.0679,+34.9357+,+32.0679,+34.9341+,+32.0730,+34.9341+,+32.0730,+34.9336+,+32.0747,+34.9331+,+32.0765,+34.9331+,+32.0765,+34.9330+,+32.0767,+34.9330+,+32.0768,+34.9328+,+32.0781,+34.9328+,+32.0781,+34.9328+,+32.0793,+34.9328+,+32.0793,+34.9333+,+32.0832,+34.9341+,+32.0899,+34.9351+,+32.0989,+34.9358+,+32.1057,+34.9359+,+32.1064,+34.9359+,+32.1064,+34.9359+,+32.1075,+34.9361+,+32.1093,+34.9363+,+32.1106,+34.9366+,+32.1119,+34.9369+,+32.1130,+34.9369+,+32.1131,+34.9373+,+32.1141,+34.9375+,+32.1146,+34.9381+,+32.1159,+34.9387+,+32.1171,+34.9391+,+32.1178,+34.9391+,+32.1178,+34.9399+,+32.1189,+34.9403+,+32.1195,+34.9410+,+32.1204,+34.9411+,+32.1204,+34.9414+,+32.1208,+34.9442+,+32.1238,+34.9477+,+32.1273,+34.9477+,+32.1273,+34.9497+,+32.1294,+34.9497+,+32.1294,+34.9533+,+32.1331,+34.9533+,+32.1331,+34.9554+,+32.1350,+34.9556+,+32.1351,+34.9558+,+32.1352,+34.9562+,+32.1354,+34.9564+,+32.1355,+34.9566+,+32.1355,+34.9578+,+32.1358,+34.9582+,+32.1360,+34.9586+,+32.1361,+34.9589+,+32.1363,+34.9591+,+32.1364,+34.9593+,+32.1366,+34.9595+,+32.1368,+34.9596+,+32.1370,+34.9598+,+32.1372,+34.9598+,+32.1374,+34.9599+,+32.1377,+34.9600+,+32.1379,+34.9600+,+32.1381,+34.9600+,+32.1383,+34.9599+,+32.1385,+34.9599+,+32.1387,+34.9598+,+32.1389,+34.9597+,+32.1392,+34.9596+,+32.1393,+34.9595+,+32.1395,+34.9594+,+32.1397,+34.9592+,+32.1399,+34.9591+,+32.1400,+34.9589+,+32.1402,+34.9587+,+32.1403,+34.9560+,+32.1421,+34.9560+,+32.1421,+34.9515+,+32.1449,+34.9515+,+32.1449,+34.9513+,+32.1451,+34.9513+,+32.1451,+34.9509+,+32.1453,+34.9509+,+32.1453,+34.9504+,+32.1457,+34.9504+,+32.1457,+34.9456+,+32.1488,+34.9439+,+32.1500,+34.9431+,+32.1505,+34.9431+,+32.1505,+34.9423+,+32.1512,+34.9403+,+32.1527,+34.9399+,+32.1531,+34.9371+,+32.1556,+34.9324+,+32.1598,+34.9297+,+32.1622,+34.9297+,+32.1622,+34.9280+,+32.1635,+34.9265+,+32.1645,+34.9254+,+32.1650,+34.9237+,+32.1658,+34.9237+,+32.1658,+34.9237+,+32.1658,+34.9235+,+32.1659,+34.9223+,+32.1663,+34.9213+,+32.1665,+34.9209+,+32.1666,+34.9207+,+32.1667,+34.9196+,+32.1670,+34.9167+,+32.1676,+34.9167+,+32.1676,+34.9146+,+32.1681,+34.9124+,+32.1686,+34.9121+,+32.1686,+34.9112+,+32.1688,+34.9101+,+32.1689,+34.9089+,+32.1690,+34.9065+,+32.1693,+34.9056+,+32.1694,+34.9045+,+32.1695,+34.9038+,+32.1697,+34.9032+,+32.1698,+34.9031+,+32.1698,+34.9025+,+32.1700,+34.9022+,+32.1701,+34.9018+,+32.1702,+34.9015+,+32.1703,+34.9002+,+32.1708,+34.8985+,+32.1714,+34.8985+,+32.1714,+34.8982+,+32.1714,+34.8981+,+32.1714,+34.8977+,+32.1714,+34.8975+,+32.1714,+34.8972+,+32.1714,+34.8970+,+32.1714,+34.8963+,+32.1716,+34.8938+,+32.1721,+34.8935+,+32.1722,+34.8935+,+32.1722,+34.8935+,+32.1723,+34.8935+,+32.1723,+34.8935+,+32.1727,+34.8935+,+32.1727,+34.8935+,+32.1728,+34.8935+,+32.1729,+34.8935+,+32.1729,+34.8935+,+32.1730,+34.8934+,+32.1732,+34.8933+,+32.1734,+34.8933+,+32.1734,+34.8922+,+32.1744,+34.8922+,+32.1744,+34.8913+,+32.1753,+34.8913+,+32.1753,+34.8906+,+32.1761,+34.8906+,+32.1761,+34.8903+,+32.1763,+34.8899+,+32.1769,+34.8896+,+32.1772,+34.8896+,+32.1772,+34.8891+,+32.1775,+34.8887+,+32.1778,+34.8886+,+32.1781,+34.8886+,+32.1781,+34.8891+,+32.1804,+34.8891+,+32.1804,+34.8893+,+32.1812,+34.8893+,+32.1812,+34.8900+,+32.1846,+34.8900+,+32.1846,+34.8902+,+32.1853,+34.8902+,+32.1856,+34.8902+,+32.1857,+34.8898+,+32.1886,+34.8898+,+32.1886,+34.8896+,+32.1896,+34.8896+,+32.1896,+34.8893+,+32.1912,+34.8893+,+32.1914,+34.8892+,+32.1916,+34.8892+,+32.1917,+34.8893+,+32.1919,+34.8893+,+32.1920,+34.8894+,+32.1920,+34.8895+,+32.1921,+34.8896+,+32.1922,+34.8897+,+32.1922,+34.8899+,+32.1922,+34.8900+,+32.1922,+34.8902+,+32.1922,+34.8903+,+32.1921,+34.8903+,+32.1920,+34.8904+,+32.1919,+34.8904+,+32.1918,+34.8905+,+32.1917,+34.8905+,+32.1916,+34.8904+,+32.1912,+34.8904+,+32.1912,+34.8898+,+32.1911,+34.8898+,+32.1911,+34.8891+,+32.1911,+34.8891+,+32.1911,+34.8885+,+32.1910,+34.8872+,+32.1912,+34.8872+,+32.1912,+34.8858+,+32.1913,+34.8858+,+32.1913,+34.8848+,+32.1914,+34.8844+,+32.1915,+34.8844+,+32.1915,+34.8838+,+32.1916,+34.8838+,+32.1916,+34.8820+,+32.1920,+34.8820+,+32.1920,+34.8811+,+32.1922,+34.8811+,+32.1922,+34.8810+,+32.1925,+34.8810+,+32.1928,+34.8810+,+32.1928,+34.8808+,+32.1934,+34.8808+,+32.1934,+34.8807+,+32.1940,+34.8807+,+32.1940,+34.8805+,+32.1953,+34.8805+,+32.1953,+34.8805+,+32.1958)",
how can I remove the + signs ?
In your getCoordsLists() method you are joining the collectors with ", "
thats why, after building the url it is adding spaces after every coordinate.
so just replace the ", " with "," in the following line:
String list = "( " + alternative.coords.stream().map(item -> String.format("%.4f , %.4f", item.x, item.y))
.collect(Collectors.joining(", ")) + ")";
It is happening because default url encoder is replacing the spaces by "+" so that the link will not be broken.
You should also replace the last line in the same way, where you are returning the string.

Can't call hasOwnProperty on Java List with Nashorn

I've got an application that executes a lot of javascript server side and I'm trying to convert from Rhino to Nashorn but I am running into trouble with my scripts. Using Rhino I would always convert whatever arguments I had for a function into a JSON string but that's really slow. With Nashorn I'm trying to just pass in the arguments as Java objects but they don't seem to inherit functions from Javascript's Object type. Here is a sample method that illustrates my problem where hasOwnProperty is not available on my array:
public String printArrayValues() throws ScriptException, NoSuchMethodException {
String script =
"function printArrayValues(objArray) {\n" +
" var result = '';\n" +
" for(var obj in objArray) {\n" +
" if(objArray.hasOwnProperty(obj)) {\n" +
" result = result + ' ' + objArray[obj];\n" +
" }\n" +
" }\n" +
" return result;\n" +
"}";
List<String> data = Arrays.asList(new String[]{ "one", "two", "three"});
ScriptEngine scriptEngine = new NashornScriptEngineFactory().getScriptEngine();
scriptEngine.eval(script);
String result = (String) ((Invocable) scriptEngine).invokeFunction("printArrayValues", data);
}
Here the call to invokeFunction throws an exception:
javax.script.ScriptException: TypeError: [one, two, three] has no such function "hasOwnProperty" in <eval> at line number 4
If I call the same function in a browser, I get what I would expect:
> printArrayValues(["one", "two", "three"]);
> " one two three"
Is there some way I can accomplish this so I really can use these Java objects without turning them into a JSON string and then eval'ing it into a Javascript object?
You can't use Java arrays in this way. Java arrays are "hardwired" objects. Unlike ordinary objects, they don't have methods and they support the [] operator, which objects can't.
This Article about Nashorn at Oracle explains that you need to use the Java.to and Java.from methods in your javascript in order to change a Java array to a Javascript array.
use Java.from() to transform the Java List to Javascript Array, and then operate on it.
String script =
"function printArrayValues(objArray) {\n" +
" var result = '';\n var temp = Java.from(objArray);" +
" for(var obj in temp ) {\n" +
" if(temp .hasOwnProperty(obj)) {\n" +
" result = result + ' ' + temp [obj];\n" +
" }\n" +
" }\n" +
" return result;\n" +
"}";

Categories