Java stream operation invocations









up vote
12
down vote

favorite
1












Can anyone point to a official Java documentation which describes how many times Stream will invoke each "non-interfering and stateless" intermediate operation for each element.



For example:



Arrays.asList("1", "2", "3", "4").stream()
.filter(s -> check(s))
.forEach(s -> System.out.println(s));

public boolean check(Object o)
return true;



The above currently will invoke check method 4 times.



Is it possible that in the current or future versions of JDKs the check method gets executed more or less times than the number of elements in the stream created from List or any other standard Java API?










share|improve this question



















  • 4




    Is there some motive behind this question? Like, you want to add unit test like verify(times(4)).check(anyBool) such that it doesn't fail in future?
    – Aayush Kumar Singha
    23 hours ago






  • 1




    I do not see a reason why that stream would ever return more than 4 values?
    – Mark
    23 hours ago










  • The motive is that if check also does important processing for each element then I want to be sure that it does only once for each element in the stream.
    – tsolakp
    23 hours ago






  • 4




    The filter predicate is supposed to be stateless.
    – Radiodef
    23 hours ago






  • 1




    @chrylis. I don't think it will make any difference.
    – tsolakp
    22 hours ago














up vote
12
down vote

favorite
1












Can anyone point to a official Java documentation which describes how many times Stream will invoke each "non-interfering and stateless" intermediate operation for each element.



For example:



Arrays.asList("1", "2", "3", "4").stream()
.filter(s -> check(s))
.forEach(s -> System.out.println(s));

public boolean check(Object o)
return true;



The above currently will invoke check method 4 times.



Is it possible that in the current or future versions of JDKs the check method gets executed more or less times than the number of elements in the stream created from List or any other standard Java API?










share|improve this question



















  • 4




    Is there some motive behind this question? Like, you want to add unit test like verify(times(4)).check(anyBool) such that it doesn't fail in future?
    – Aayush Kumar Singha
    23 hours ago






  • 1




    I do not see a reason why that stream would ever return more than 4 values?
    – Mark
    23 hours ago










  • The motive is that if check also does important processing for each element then I want to be sure that it does only once for each element in the stream.
    – tsolakp
    23 hours ago






  • 4




    The filter predicate is supposed to be stateless.
    – Radiodef
    23 hours ago






  • 1




    @chrylis. I don't think it will make any difference.
    – tsolakp
    22 hours ago












up vote
12
down vote

favorite
1









up vote
12
down vote

favorite
1






1





Can anyone point to a official Java documentation which describes how many times Stream will invoke each "non-interfering and stateless" intermediate operation for each element.



For example:



Arrays.asList("1", "2", "3", "4").stream()
.filter(s -> check(s))
.forEach(s -> System.out.println(s));

public boolean check(Object o)
return true;



The above currently will invoke check method 4 times.



Is it possible that in the current or future versions of JDKs the check method gets executed more or less times than the number of elements in the stream created from List or any other standard Java API?










share|improve this question















Can anyone point to a official Java documentation which describes how many times Stream will invoke each "non-interfering and stateless" intermediate operation for each element.



For example:



Arrays.asList("1", "2", "3", "4").stream()
.filter(s -> check(s))
.forEach(s -> System.out.println(s));

public boolean check(Object o)
return true;



The above currently will invoke check method 4 times.



Is it possible that in the current or future versions of JDKs the check method gets executed more or less times than the number of elements in the stream created from List or any other standard Java API?







java java-8 java-stream






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 7 hours ago









Mani Grover

111214




111214










asked 23 hours ago









tsolakp

4,40411219




4,40411219







  • 4




    Is there some motive behind this question? Like, you want to add unit test like verify(times(4)).check(anyBool) such that it doesn't fail in future?
    – Aayush Kumar Singha
    23 hours ago






  • 1




    I do not see a reason why that stream would ever return more than 4 values?
    – Mark
    23 hours ago










  • The motive is that if check also does important processing for each element then I want to be sure that it does only once for each element in the stream.
    – tsolakp
    23 hours ago






  • 4




    The filter predicate is supposed to be stateless.
    – Radiodef
    23 hours ago






  • 1




    @chrylis. I don't think it will make any difference.
    – tsolakp
    22 hours ago












  • 4




    Is there some motive behind this question? Like, you want to add unit test like verify(times(4)).check(anyBool) such that it doesn't fail in future?
    – Aayush Kumar Singha
    23 hours ago






  • 1




    I do not see a reason why that stream would ever return more than 4 values?
    – Mark
    23 hours ago










  • The motive is that if check also does important processing for each element then I want to be sure that it does only once for each element in the stream.
    – tsolakp
    23 hours ago






  • 4




    The filter predicate is supposed to be stateless.
    – Radiodef
    23 hours ago






  • 1




    @chrylis. I don't think it will make any difference.
    – tsolakp
    22 hours ago







4




4




Is there some motive behind this question? Like, you want to add unit test like verify(times(4)).check(anyBool) such that it doesn't fail in future?
– Aayush Kumar Singha
23 hours ago




Is there some motive behind this question? Like, you want to add unit test like verify(times(4)).check(anyBool) such that it doesn't fail in future?
– Aayush Kumar Singha
23 hours ago




1




1




I do not see a reason why that stream would ever return more than 4 values?
– Mark
23 hours ago




I do not see a reason why that stream would ever return more than 4 values?
– Mark
23 hours ago












The motive is that if check also does important processing for each element then I want to be sure that it does only once for each element in the stream.
– tsolakp
23 hours ago




The motive is that if check also does important processing for each element then I want to be sure that it does only once for each element in the stream.
– tsolakp
23 hours ago




4




4




The filter predicate is supposed to be stateless.
– Radiodef
23 hours ago




The filter predicate is supposed to be stateless.
– Radiodef
23 hours ago




1




1




@chrylis. I don't think it will make any difference.
– tsolakp
22 hours ago




@chrylis. I don't think it will make any difference.
– tsolakp
22 hours ago












2 Answers
2






active

oldest

votes

















up vote
15
down vote













This does not have to do with the source of the stream, but rather the terminal operation and optimization done in the stream implementation itself. For example:



Stream.of(1,2,3,4)
.map(x -> x + 1)
.count();


Since java-9, map will not get executed a single time.



Or:



 someTreeSet.stream()
.sorted()
.findFirst();


sorted might not get executed at all, since the source is a TreeSet and getting the first element is trivial, but if this is implemented inside stream API or not, is a different question.



So the real answer here - it depends, but I can't imagine one operation that would get executed more that the numbers of elements in the source.






share|improve this answer
















  • 2




    "but I can't imagine one operation that would get executed more that the numbers of elements in the source" - Well, if you specify a Comparator for sorting, its compare will definitely be invoked more times than the number of elements, but that's just nitpicking. +1
    – Fureeish
    23 hours ago






  • 1




    @Fureeish no no, very good nitpick, indeed you are right; but it seems sorted is the only one that could do that. distinct does not for example
    – Eugene
    23 hours ago






  • 1




    Some time ago I asked this question about jdk8 flatMap (also see this related question). In short, in jdk8&9 flatMap is not completely lazy and elements can be visited more than once, while in jdk10 this behavior has been fixed.
    – Federico Peralta Schaffner
    22 hours ago







  • 1




    @FedericoPeraltaSchaffner as said earlier I can write it as Stream.of(1, 1) .flatMap(x -> Stream.of(x, x)) .forEach(System.out::println); does it mean that it gets visited more than once?
    – Eugene
    22 hours ago






  • 2




    4 times according to my own maths ;) I get your point, I was thinking about tricky use cases with flatMap, followed by filter. In such hypothetical cases, maybe reality is counterintuituve. Let me try to find an example...
    – Federico Peralta Schaffner
    22 hours ago

















up vote
3
down vote













From the documentation:




Laziness-seeking. Many stream operations, such as filtering, mapping, or duplicate removal, can be implemented lazily, exposing opportunities for optimization. For example, "find the first String with three consecutive vowels" need not examine all the input strings. Stream operations are divided into intermediate (Stream-producing) operations and terminal (value- or side-effect-producing) operations. Intermediate operations are always lazy.




By that virtue, because filter is an intermediate operation which creates a new Stream as part of its operation, due to its laziness, it will only ever invoke the filter predicate once per element as part of its rebuilding of the stream.



The only way that your method would possibly have a different number of invocations against it in the stream is if the stream were somehow mutated between states, which given the fact that nothing in a stream actually runs until the terminal operation, would only realistically be possible due to a bug upstream.






share|improve this answer




















  • So what does "Laziness" mean in Java streams? To me it means that the actual invocation of intermediate operation will happen after invocation of terminal operation. But it does not guarantee that intermediate operation will be invoked only once per element (or not at all depending on terminal operation).
    – tsolakp
    22 hours ago










Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













 

draft saved


draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53234586%2fjava-stream-operation-invocations%23new-answer', 'question_page');

);

Post as a guest






























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
15
down vote













This does not have to do with the source of the stream, but rather the terminal operation and optimization done in the stream implementation itself. For example:



Stream.of(1,2,3,4)
.map(x -> x + 1)
.count();


Since java-9, map will not get executed a single time.



Or:



 someTreeSet.stream()
.sorted()
.findFirst();


sorted might not get executed at all, since the source is a TreeSet and getting the first element is trivial, but if this is implemented inside stream API or not, is a different question.



So the real answer here - it depends, but I can't imagine one operation that would get executed more that the numbers of elements in the source.






share|improve this answer
















  • 2




    "but I can't imagine one operation that would get executed more that the numbers of elements in the source" - Well, if you specify a Comparator for sorting, its compare will definitely be invoked more times than the number of elements, but that's just nitpicking. +1
    – Fureeish
    23 hours ago






  • 1




    @Fureeish no no, very good nitpick, indeed you are right; but it seems sorted is the only one that could do that. distinct does not for example
    – Eugene
    23 hours ago






  • 1




    Some time ago I asked this question about jdk8 flatMap (also see this related question). In short, in jdk8&9 flatMap is not completely lazy and elements can be visited more than once, while in jdk10 this behavior has been fixed.
    – Federico Peralta Schaffner
    22 hours ago







  • 1




    @FedericoPeraltaSchaffner as said earlier I can write it as Stream.of(1, 1) .flatMap(x -> Stream.of(x, x)) .forEach(System.out::println); does it mean that it gets visited more than once?
    – Eugene
    22 hours ago






  • 2




    4 times according to my own maths ;) I get your point, I was thinking about tricky use cases with flatMap, followed by filter. In such hypothetical cases, maybe reality is counterintuituve. Let me try to find an example...
    – Federico Peralta Schaffner
    22 hours ago














up vote
15
down vote













This does not have to do with the source of the stream, but rather the terminal operation and optimization done in the stream implementation itself. For example:



Stream.of(1,2,3,4)
.map(x -> x + 1)
.count();


Since java-9, map will not get executed a single time.



Or:



 someTreeSet.stream()
.sorted()
.findFirst();


sorted might not get executed at all, since the source is a TreeSet and getting the first element is trivial, but if this is implemented inside stream API or not, is a different question.



So the real answer here - it depends, but I can't imagine one operation that would get executed more that the numbers of elements in the source.






share|improve this answer
















  • 2




    "but I can't imagine one operation that would get executed more that the numbers of elements in the source" - Well, if you specify a Comparator for sorting, its compare will definitely be invoked more times than the number of elements, but that's just nitpicking. +1
    – Fureeish
    23 hours ago






  • 1




    @Fureeish no no, very good nitpick, indeed you are right; but it seems sorted is the only one that could do that. distinct does not for example
    – Eugene
    23 hours ago






  • 1




    Some time ago I asked this question about jdk8 flatMap (also see this related question). In short, in jdk8&9 flatMap is not completely lazy and elements can be visited more than once, while in jdk10 this behavior has been fixed.
    – Federico Peralta Schaffner
    22 hours ago







  • 1




    @FedericoPeraltaSchaffner as said earlier I can write it as Stream.of(1, 1) .flatMap(x -> Stream.of(x, x)) .forEach(System.out::println); does it mean that it gets visited more than once?
    – Eugene
    22 hours ago






  • 2




    4 times according to my own maths ;) I get your point, I was thinking about tricky use cases with flatMap, followed by filter. In such hypothetical cases, maybe reality is counterintuituve. Let me try to find an example...
    – Federico Peralta Schaffner
    22 hours ago












up vote
15
down vote










up vote
15
down vote









This does not have to do with the source of the stream, but rather the terminal operation and optimization done in the stream implementation itself. For example:



Stream.of(1,2,3,4)
.map(x -> x + 1)
.count();


Since java-9, map will not get executed a single time.



Or:



 someTreeSet.stream()
.sorted()
.findFirst();


sorted might not get executed at all, since the source is a TreeSet and getting the first element is trivial, but if this is implemented inside stream API or not, is a different question.



So the real answer here - it depends, but I can't imagine one operation that would get executed more that the numbers of elements in the source.






share|improve this answer












This does not have to do with the source of the stream, but rather the terminal operation and optimization done in the stream implementation itself. For example:



Stream.of(1,2,3,4)
.map(x -> x + 1)
.count();


Since java-9, map will not get executed a single time.



Or:



 someTreeSet.stream()
.sorted()
.findFirst();


sorted might not get executed at all, since the source is a TreeSet and getting the first element is trivial, but if this is implemented inside stream API or not, is a different question.



So the real answer here - it depends, but I can't imagine one operation that would get executed more that the numbers of elements in the source.







share|improve this answer












share|improve this answer



share|improve this answer










answered 23 hours ago









Eugene

66k992158




66k992158







  • 2




    "but I can't imagine one operation that would get executed more that the numbers of elements in the source" - Well, if you specify a Comparator for sorting, its compare will definitely be invoked more times than the number of elements, but that's just nitpicking. +1
    – Fureeish
    23 hours ago






  • 1




    @Fureeish no no, very good nitpick, indeed you are right; but it seems sorted is the only one that could do that. distinct does not for example
    – Eugene
    23 hours ago






  • 1




    Some time ago I asked this question about jdk8 flatMap (also see this related question). In short, in jdk8&9 flatMap is not completely lazy and elements can be visited more than once, while in jdk10 this behavior has been fixed.
    – Federico Peralta Schaffner
    22 hours ago







  • 1




    @FedericoPeraltaSchaffner as said earlier I can write it as Stream.of(1, 1) .flatMap(x -> Stream.of(x, x)) .forEach(System.out::println); does it mean that it gets visited more than once?
    – Eugene
    22 hours ago






  • 2




    4 times according to my own maths ;) I get your point, I was thinking about tricky use cases with flatMap, followed by filter. In such hypothetical cases, maybe reality is counterintuituve. Let me try to find an example...
    – Federico Peralta Schaffner
    22 hours ago












  • 2




    "but I can't imagine one operation that would get executed more that the numbers of elements in the source" - Well, if you specify a Comparator for sorting, its compare will definitely be invoked more times than the number of elements, but that's just nitpicking. +1
    – Fureeish
    23 hours ago






  • 1




    @Fureeish no no, very good nitpick, indeed you are right; but it seems sorted is the only one that could do that. distinct does not for example
    – Eugene
    23 hours ago






  • 1




    Some time ago I asked this question about jdk8 flatMap (also see this related question). In short, in jdk8&9 flatMap is not completely lazy and elements can be visited more than once, while in jdk10 this behavior has been fixed.
    – Federico Peralta Schaffner
    22 hours ago







  • 1




    @FedericoPeraltaSchaffner as said earlier I can write it as Stream.of(1, 1) .flatMap(x -> Stream.of(x, x)) .forEach(System.out::println); does it mean that it gets visited more than once?
    – Eugene
    22 hours ago






  • 2




    4 times according to my own maths ;) I get your point, I was thinking about tricky use cases with flatMap, followed by filter. In such hypothetical cases, maybe reality is counterintuituve. Let me try to find an example...
    – Federico Peralta Schaffner
    22 hours ago







2




2




"but I can't imagine one operation that would get executed more that the numbers of elements in the source" - Well, if you specify a Comparator for sorting, its compare will definitely be invoked more times than the number of elements, but that's just nitpicking. +1
– Fureeish
23 hours ago




"but I can't imagine one operation that would get executed more that the numbers of elements in the source" - Well, if you specify a Comparator for sorting, its compare will definitely be invoked more times than the number of elements, but that's just nitpicking. +1
– Fureeish
23 hours ago




1




1




@Fureeish no no, very good nitpick, indeed you are right; but it seems sorted is the only one that could do that. distinct does not for example
– Eugene
23 hours ago




@Fureeish no no, very good nitpick, indeed you are right; but it seems sorted is the only one that could do that. distinct does not for example
– Eugene
23 hours ago




1




1




Some time ago I asked this question about jdk8 flatMap (also see this related question). In short, in jdk8&9 flatMap is not completely lazy and elements can be visited more than once, while in jdk10 this behavior has been fixed.
– Federico Peralta Schaffner
22 hours ago





Some time ago I asked this question about jdk8 flatMap (also see this related question). In short, in jdk8&9 flatMap is not completely lazy and elements can be visited more than once, while in jdk10 this behavior has been fixed.
– Federico Peralta Schaffner
22 hours ago





1




1




@FedericoPeraltaSchaffner as said earlier I can write it as Stream.of(1, 1) .flatMap(x -> Stream.of(x, x)) .forEach(System.out::println); does it mean that it gets visited more than once?
– Eugene
22 hours ago




@FedericoPeraltaSchaffner as said earlier I can write it as Stream.of(1, 1) .flatMap(x -> Stream.of(x, x)) .forEach(System.out::println); does it mean that it gets visited more than once?
– Eugene
22 hours ago




2




2




4 times according to my own maths ;) I get your point, I was thinking about tricky use cases with flatMap, followed by filter. In such hypothetical cases, maybe reality is counterintuituve. Let me try to find an example...
– Federico Peralta Schaffner
22 hours ago




4 times according to my own maths ;) I get your point, I was thinking about tricky use cases with flatMap, followed by filter. In such hypothetical cases, maybe reality is counterintuituve. Let me try to find an example...
– Federico Peralta Schaffner
22 hours ago












up vote
3
down vote













From the documentation:




Laziness-seeking. Many stream operations, such as filtering, mapping, or duplicate removal, can be implemented lazily, exposing opportunities for optimization. For example, "find the first String with three consecutive vowels" need not examine all the input strings. Stream operations are divided into intermediate (Stream-producing) operations and terminal (value- or side-effect-producing) operations. Intermediate operations are always lazy.




By that virtue, because filter is an intermediate operation which creates a new Stream as part of its operation, due to its laziness, it will only ever invoke the filter predicate once per element as part of its rebuilding of the stream.



The only way that your method would possibly have a different number of invocations against it in the stream is if the stream were somehow mutated between states, which given the fact that nothing in a stream actually runs until the terminal operation, would only realistically be possible due to a bug upstream.






share|improve this answer




















  • So what does "Laziness" mean in Java streams? To me it means that the actual invocation of intermediate operation will happen after invocation of terminal operation. But it does not guarantee that intermediate operation will be invoked only once per element (or not at all depending on terminal operation).
    – tsolakp
    22 hours ago














up vote
3
down vote













From the documentation:




Laziness-seeking. Many stream operations, such as filtering, mapping, or duplicate removal, can be implemented lazily, exposing opportunities for optimization. For example, "find the first String with three consecutive vowels" need not examine all the input strings. Stream operations are divided into intermediate (Stream-producing) operations and terminal (value- or side-effect-producing) operations. Intermediate operations are always lazy.




By that virtue, because filter is an intermediate operation which creates a new Stream as part of its operation, due to its laziness, it will only ever invoke the filter predicate once per element as part of its rebuilding of the stream.



The only way that your method would possibly have a different number of invocations against it in the stream is if the stream were somehow mutated between states, which given the fact that nothing in a stream actually runs until the terminal operation, would only realistically be possible due to a bug upstream.






share|improve this answer




















  • So what does "Laziness" mean in Java streams? To me it means that the actual invocation of intermediate operation will happen after invocation of terminal operation. But it does not guarantee that intermediate operation will be invoked only once per element (or not at all depending on terminal operation).
    – tsolakp
    22 hours ago












up vote
3
down vote










up vote
3
down vote









From the documentation:




Laziness-seeking. Many stream operations, such as filtering, mapping, or duplicate removal, can be implemented lazily, exposing opportunities for optimization. For example, "find the first String with three consecutive vowels" need not examine all the input strings. Stream operations are divided into intermediate (Stream-producing) operations and terminal (value- or side-effect-producing) operations. Intermediate operations are always lazy.




By that virtue, because filter is an intermediate operation which creates a new Stream as part of its operation, due to its laziness, it will only ever invoke the filter predicate once per element as part of its rebuilding of the stream.



The only way that your method would possibly have a different number of invocations against it in the stream is if the stream were somehow mutated between states, which given the fact that nothing in a stream actually runs until the terminal operation, would only realistically be possible due to a bug upstream.






share|improve this answer












From the documentation:




Laziness-seeking. Many stream operations, such as filtering, mapping, or duplicate removal, can be implemented lazily, exposing opportunities for optimization. For example, "find the first String with three consecutive vowels" need not examine all the input strings. Stream operations are divided into intermediate (Stream-producing) operations and terminal (value- or side-effect-producing) operations. Intermediate operations are always lazy.




By that virtue, because filter is an intermediate operation which creates a new Stream as part of its operation, due to its laziness, it will only ever invoke the filter predicate once per element as part of its rebuilding of the stream.



The only way that your method would possibly have a different number of invocations against it in the stream is if the stream were somehow mutated between states, which given the fact that nothing in a stream actually runs until the terminal operation, would only realistically be possible due to a bug upstream.







share|improve this answer












share|improve this answer



share|improve this answer










answered 23 hours ago









Makoto

78.9k15122164




78.9k15122164











  • So what does "Laziness" mean in Java streams? To me it means that the actual invocation of intermediate operation will happen after invocation of terminal operation. But it does not guarantee that intermediate operation will be invoked only once per element (or not at all depending on terminal operation).
    – tsolakp
    22 hours ago
















  • So what does "Laziness" mean in Java streams? To me it means that the actual invocation of intermediate operation will happen after invocation of terminal operation. But it does not guarantee that intermediate operation will be invoked only once per element (or not at all depending on terminal operation).
    – tsolakp
    22 hours ago















So what does "Laziness" mean in Java streams? To me it means that the actual invocation of intermediate operation will happen after invocation of terminal operation. But it does not guarantee that intermediate operation will be invoked only once per element (or not at all depending on terminal operation).
– tsolakp
22 hours ago




So what does "Laziness" mean in Java streams? To me it means that the actual invocation of intermediate operation will happen after invocation of terminal operation. But it does not guarantee that intermediate operation will be invoked only once per element (or not at all depending on terminal operation).
– tsolakp
22 hours ago

















 

draft saved


draft discarded















































 


draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53234586%2fjava-stream-operation-invocations%23new-answer', 'question_page');

);

Post as a guest














































































這個網誌中的熱門文章

How to read a connectionString WITH PROVIDER in .NET Core?

Node.js Script on GitHub Pages or Amazon S3

Museum of Modern and Contemporary Art of Trento and Rovereto