2016-02-21 35 views
5

Làm cách nào để thực hiện thao tác Scala bên dưới để tìm ký tự thường xuyên nhất trong chuỗi trong java 8?Hoạt động lặp trong Scala Vs Java 8

val tst = "Scala is awesomestttttts" 
val op = tst.foldLeft(Map[Char,Int]())((a,b) => { 
    a+(b -> ((a.getOrElse(b, 0))+1)) 
    }).maxBy(f => f._2) 

Ở đây, đầu ra là

(Char, Int) = (t,6) 

tôi đã có thể để có được một dòng ký tự trong Java 8 như thế này:

Stream<Character> sch = tst.chars().mapToObj(i -> (char)i); 

nhưng không thể tìm ra whats lần/foldLeft/foldRight thay thế chúng tôi có trong Java 8

Ai đó có thể giúp đỡ?

Trả lời

8

Something như thế này có vẻ phù hợp với mã Scala mà bạn cung cấp (nếu tôi hiểu nó một cách chính xác):

String tst = "Java is awesomestttttts"; 
Optional<Map.Entry<Character, Long>> max = 
    tst.chars() 
     .mapToObj(i -> (char) i) 
     .collect(Collectors.groupingBy(Function.identity(), 
             Collectors.counting())) 
     .entrySet() 
     .stream() 
     .max(Comparator.comparing(Map.Entry::getValue)); 
System.out.println(max.orElse(null)); 
+1

'System.out.println (Collections.max (tst.chars() .boxed() .collect (Collectors.groupingBy (i -> (char) (int) i, Collectors.counting())). entrySet(), Map.Entry.comparingByValue())); ' – Holger

+0

@Holger Điều đó không biên dịch trong intellij 15 –

+1

@Federico Peralta Schaffner: khi tôi sao chép từ nhận xét của tôi, nó cũng không hoạt động, bởi vì bằng cách nào đó, ['U + 200C'] (http://www.fileformat.info/info/unicode/char/200c/index.htm) [' U + 200B'] (http://www.fileformat.info/info/ unicode/char/200B/index.htm) chuỗi nằm giữa '(' và ')' của 'emptySet()', vô hình nhưng gây ra lỗi trình biên dịch. Sau khi loại bỏ hai nhân vật bất hợp pháp này, nó biên dịch tốt với Netbeans và javac. – Holger

8

Nếu bạn không nhớ bằng cách sử dụng thư viện của bên thứ ba Eclipse Collections có một loại Bag rằng có thể theo dõi số lượng nhân vật. Tôi đã cung cấp hai ví dụ bên dưới sử dụng Túi. Thật không may là không có maxByOccurrences có sẵn ngày hôm nay trên Bag, nhưng kết quả tương tự có thể đạt được bằng cách sử dụng topOccurrences(1) có sẵn. Bạn cũng có thể sử dụng forEachWithOccurrences để tìm số tối đa nhưng sẽ có nhiều mã hơn.

Ví dụ sau sử dụng CharAdapter, cũng được bao gồm trong Bộ sưu tập Eclipse.

MutableBag<Character> characters = 
    CharAdapter.adapt("Scala is awesomestttttts") 
     .collect(Character::toLowerCase) 
     .toBag(); 
MutableList<ObjectIntPair<Character>> charIntPairs = characters.topOccurrences(2); 

Assert.assertEquals(
    PrimitiveTuples.pair(Character.valueOf('t'), 6), charIntPairs.get(0)); 
Assert.assertEquals(
    PrimitiveTuples.pair(Character.valueOf('s'), 5), charIntPairs.get(1)); 

Ví dụ thứ hai sử dụng chars() phương pháp có sẵn trên String mà trả về một IntStream. Nó cảm thấy một chút vụng về rằng một cái gì đó gọi là chars() không trả về một CharStream, nhưng điều này là bởi vì CharStream không có sẵn trong JDK 8.

MutableBag<Character> characters = 
    "Scala is awesomestttttts" 
     .toLowerCase() 
     .chars() 
     .mapToObj(i -> (char) i) 
     .collect(Collectors.toCollection(Bags.mutable::empty)); 
MutableList<ObjectIntPair<Character>> charIntPairs = characters.topOccurrences(2); 

Assert.assertEquals(
    PrimitiveTuples.pair(Character.valueOf('t'), 6), charIntPairs.get(0)); 
Assert.assertEquals(
    PrimitiveTuples.pair(Character.valueOf('s'), 5), charIntPairs.get(1)); 

Trong cả hai ví dụ, tôi chuyển đổi các ký tự thành chữ thường đầu tiên, do đó là 5 lần xuất hiện của 's'. Nếu bạn muốn chữ hoa và chữ thường được phân biệt thì chỉ cần thả mã chữ thường trong cả hai ví dụ.

Lưu ý: Tôi là người cam kết cho Bộ sưu tập Eclipse.

0

Đây là mẫu bằng cách Stream trong AbacusUtil:

String str = "Scala is awesomestttttts"; 
CharStream.from(str).boxed().groupBy(t -> t, Collectors.counting()) 
      .max(Comparator.comparing(Map.Entry::getValue)).get(); 

Nhưng tôi nghĩ rằng cách đơn giản nhất bởi MultiSet:

CharStream.from(str).toMultiset().maxOccurrences().get(); 
Các vấn đề liên quan