Win a copy of Head First Android this week in the Android forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Paul Clapham
  • Ron McLeod
  • Tim Cooke
  • Junilu Lacar
Sheriffs:
  • Rob Spoor
  • Devaka Cooray
  • Jeanne Boyarsky
Saloon Keepers:
  • Jesse Silverman
  • Stephan van Hulst
  • Tim Moores
  • Carey Brown
  • Tim Holloway
Bartenders:
  • Jj Roberts
  • Al Hobbs
  • Piet Souris

Java8 - Use of streams in multiple loops

 
Ranch Hand
Posts: 138
1
jQuery Spring Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi,

I am working on a problem where I need to find the words which have the same length and characters. E.g. - "act", "cat" and "tac" are same. Like "bats" and "tabs" are same.
I am able to write the program and get the desired output.

{the=1, bats=2, act=3, cat=3, tac=3, tabs=2, is=1}



The questions I have is:
1. Can I convert the code into Streams and get the desired output.
2. How to use streams in multiple for loops?

The code needs improvement but want to understand, how can I use streams in multiple loops over same list.

Below is the sample code:



Thanks,
Atul
 
Marshal
Posts: 74354
334
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Atul More wrote:. . . words which have the same length and characters. . . .

You appear to be trying to do too many things all at once. That sounds as though you are trying to identify words which are strict anagrams of each other. Are you also trying to categorise words by length?

2. How to use streams in multiple for loops?

The whole idea of the Stream API was to allow iteration without needing loops. You can create a Stream<Stream<String>> or similar, yes. You can use that sort of concept to sort things by length, yes. But maybe you should't try that at first. Try working out how to identify anagrams. I think you are well on your way to that. Remember that two words which are anagrams of each other always have the same length.

. . .. . .

Do you own the work.com domain? Only use that sort of package name if you own the domain you have named.
Don't use /* comments */ for commenting‑out. Use // before each line. An IDE can do that more‑or‑less automatically.
Why have you written a method to check for the empty String, when String already has such a method? Why are you permitting nulls? Don't convert a null to an empty String: throw an exception instead. Similarly I think it is a bad idea to return null from line 22. If the List is empty, you will get an empty Map; if you pass null, throw an Exception.
You can create Maps from Streams with methods with “group” in their name. Go through the Java™ Tutorials and see whether there is anything useful in the Map section or the rest of that “trail”. Consider carefully what you are using as the “K” for any Maps: make sure your “K” is an immutable type.
 
Atul More
Ranch Hand
Posts: 138
1
jQuery Spring Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello Campbell,

Thanks for response and inputs.

You appear to be trying to do too many things all at once. That sounds as though you are trying to identify words which are strict anagrams of each other. Are you also trying to categorise words by length?


Yes I am trying to find anagram but not based on the length. The condition I put the to avoid the unnecessary code execution nothing else.

Even I mentioned that improvement is there in code.

But the only thing I would like to understand is to how can I use the list in streams multiple times like I have used. The words list I used couple of times.

Thanks,
Atul

 
Author
Posts: 161
31
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Here is what I would do:



(You can devise a better implementation of the getCharset method!)
 
Campbell Ritchie
Marshal
Posts: 74354
334
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Good to see you back, P‑YS
Nice solution which will collect anagrams. You can easily simplify that to collect Strings by their length. Is getCharset() quite the best name for that method? I thought it meant something like UTF‑8 when I first saw it.
 
Pierre-Yves Saumont
Author
Posts: 161
31
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You're right. It's a very bad name  

Collecting strings by their length would not be a simplification. What I should have done is grouping strings by length AND set of characters (and not CharSet!). In fact, this might not be enough,  because "aabc" would then be equals to "abbc".  If true anagrams are to be considered, we can use something like:



 
Campbell Ritchie
Marshal
Posts: 74354
334
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
What's wrong with ...groupingBy(String::length)...? That would of course only group by length of the words.
 
Saloon Keeper
Posts: 13383
295
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Well... It would only group strings by length. It wouldn't make separate groupings of anagrams.

The solution is very easy. Group the strings by the sorted list of characters that make up a string:
 
Ranch Hand
Posts: 954
4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Stephan van Hulst wrote:
strings.collect(
 Collectors.groupingBy(
   string -> Arrays.asList(
     string.codePoints().sorted().toArray()
   )
 )
)
[/code]



Sorry but it is giving me compilation error. What i am doing wrong here?

words.stream().collect(
            Collectors.groupingBy(
                s -> Arrays.asList(
                                   s.codePoints().sorted.toArray()
                       )
               )
       );
 
Stephan van Hulst
Saloon Keeper
Posts: 13383
295
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I don't know, because you haven't told us what compilation error you're getting.
 
Atul More
Ranch Hand
Posts: 138
1
jQuery Spring Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello everyone,

Thanks for inputs.
Can somebody tell me how can I write the multiple loops using streams ? Like I did in the example mentioned in the first post.
I am iterating the same list twice.
Is it possible to do it using streams?

Thanks,
Atul
 
Campbell Ritchie
Marshal
Posts: 74354
334
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Atul More wrote:. . . I am iterating the same list twice.
Is it possible to do it using streams? . . .

Yes, but you cannot use the same Stream twice; you may need to create two Streams.
 
Atul More
Ranch Hand
Posts: 138
1
jQuery Spring Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi,

Yes, but you cannot use the same Stream twice; you may need to create two Streams.



Understood. I have to create each stream for each loop.
But how can I do that?
How to write that particular code.

Thanks,
Atul
 
Atul More
Ranch Hand
Posts: 138
1
jQuery Spring Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi,

I am able to solve the issue. Now getting the desired result.




Thanks,
Atul
 
Campbell Ritchie
Marshal
Posts: 74354
334
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Please find out how to reduce lines 14‑18 to one expression with the ?: operator.
 
reply
    Bookmark Topic Watch Topic
  • New Topic