Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pure functional solution of word count #2

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
128,457 changes: 128,457 additions & 0 deletions examples/data/big.txt

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package mk.ukim.finki.np.av10;

import java.util.Base64;

public class EmailDecoratorDemo {
interface Email {
String getContent();
}

static abstract class EmailDecorator implements Email {
private final Email email;

protected EmailDecorator(Email email) {
this.email = email;
}

@Override
public String getContent() {
return email.getContent();
}
}

static class TextEmail implements Email {
private final String text;

TextEmail(String text) {
this.text = text;
}

@Override
public String getContent() {
return text;
}
}

static class SpamEmail extends EmailDecorator {

SpamEmail(Email email) {
super(email);
}

@Override
public String getContent() {
return super.getContent().toUpperCase();
}
}

static class SignatureEmail extends EmailDecorator {

SignatureEmail(Email email) {
super(email);
}

@Override
public String getContent() {
return super.getContent() + " \nMy Signature";
}
}

static class Base64Email extends EmailDecorator {

protected Base64Email(Email email) {
super(email);
}

@Override
public String getContent() {
return Base64.getEncoder().encodeToString(super.getContent().getBytes());
}
}

public static void main(String[] args) {
Email textEmail = new TextEmail("text email");
System.out.println("Base64 spam email");
Email base64Spam = new Base64Email(new SpamEmail(textEmail));
System.out.println(base64Spam.getContent());
System.out.println("Spam with signature");
Email spamWithSignature = new SpamEmail(new SignatureEmail(textEmail));
System.out.println(spamWithSignature.getContent());
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package mk.ukim.finki.np.av10;


import java.util.Base64;
import java.util.function.Function;

public class EmailDecoratorFunctionalDemo {
interface EmailDecorator extends Function<TextEmail, TextEmail> {
}

static class TextEmail {
private final String text;

TextEmail(String text) {
this.text = text;
}

public String getText() {
return text;
}
}

static EmailDecorator spamEmail = email -> new TextEmail(email.getText().toUpperCase());

static EmailDecorator signatureEmail = email -> new TextEmail(email.getText() + "\nMy Signature");

static EmailDecorator base64Email = email -> new TextEmail(Base64.getEncoder().encodeToString(email.getText().getBytes()));

public static void main(String[] args) {

System.out.println("Base64 spam email");
TextEmail email = new TextEmail("text email");
System.out.println(base64Email.andThen(spamEmail).apply(email));
System.out.println("Spam with signature");
System.out.println(spamEmail.andThen(signatureEmail).apply(email));
}

}
49 changes: 47 additions & 2 deletions examples/src/main/java/mk/ukim/finki/np/av5/WordCount.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

Expand All @@ -23,8 +24,12 @@ public static void main(String[] args) throws IOException {
}
for (String fileName : args) {
try {
String wordCount = processFile(fileName);
//wordCount = processWithMapReduce(fileName);
long start = System.nanoTime();
//String wordCount = processFile(fileName);
//String wordCount = processFile(fileName);
FileStat wordCount = pureFunctional(fileName);
long end = System.nanoTime();
System.out.printf("Took: %.3fms\n", (end - start) / 1000000.);
result.append(String.format("%s -> %s\n", fileName, wordCount));
} catch (IOException e) {
System.err.println(e.getMessage());
Expand Down Expand Up @@ -84,6 +89,12 @@ private static String processWithMapReduce(String fileName) throws IOException {

}

private static FileStat pureFunctional(String fileName) throws IOException {
return Files.lines(Paths.get(fileName))
.map(new WordCounter())
.reduce(FileStat.identity(), FileStat::add);
}

static class FileCounts implements Consumer<String> {
private static final Pattern WORD = Pattern.compile("\\s+");
long lines;
Expand All @@ -109,4 +120,38 @@ public String toString() {
}
}

static class FileStat {
private final long lines;
private final long chars;
private final long words;

FileStat(long lines, long chars, long words) {
this.lines = lines;
this.chars = chars;
this.words = words;
}

static FileStat identity() {
return new FileStat(0, 0, 0);
}

FileStat add(FileStat stat) {
return new FileStat(this.lines + stat.lines, this.chars + stat.chars, this.words + stat.words);
}

@Override
public String toString() {
return String.format("%d %d %d", lines, words, chars);
}
}

static class WordCounter implements Function<String, FileStat> {
private static final Pattern WORD = Pattern.compile("\\s+");

@Override
public FileStat apply(String line) {
return new FileStat(1, line.length() + 1, WORD.split(line).length);
}
}

}
25 changes: 25 additions & 0 deletions examples/src/main/java/mk/ukim/finki/np/optional/OptionalDemo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package mk.ukim.finki.np.optional;

public class OptionalDemo {

public static String findStudent(String number, String name) {
Student student = OptionalProblem.findByNumber(number);
if (student != null) {
if (student.matchName(name)) {
return student.toString();
}
}
return "Student not found";
}

public static String findStudentOptional(String number, String name) {
return OptionalSolution.findByNumber(number)
.filter(it -> it.matchName(name))
.map(Student::toString)
.orElse("Student not found");
}

public static void main(String[] args) {
System.out.println(findStudent("007", "Gjorgji"));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package mk.ukim.finki.np.optional;

public class OptionalProblem {


public static Student findByNumber(String number) {
for (Student student : StudentsData.students) {
if (student.matchNumber(number)) {
return student;
}
}
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package mk.ukim.finki.np.optional;

import java.util.Optional;

public class OptionalSolution {

public static Optional<Student> findByNumber(String number) {
return StudentsData.students.stream()
.filter(it -> it.matchNumber(number))
.findFirst();

}
}
24 changes: 24 additions & 0 deletions examples/src/main/java/mk/ukim/finki/np/optional/Student.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package mk.ukim.finki.np.optional;

public class Student {
private final String number;
private final String name;

public Student(String number, String name) {
this.number = number;
this.name = name;
}

public boolean matchName(String name) {
return this.name.startsWith(name);
}

public boolean matchNumber(String number) {
return this.number.equals(number);
}

@Override
public String toString() {
return String.format("%s. %s", number, name);
}
}
14 changes: 14 additions & 0 deletions examples/src/main/java/mk/ukim/finki/np/optional/StudentsData.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package mk.ukim.finki.np.optional;

import java.util.Arrays;
import java.util.List;

public class StudentsData {
public static List<Student> students = Arrays.asList(
new Student("001", "Gjorgji"),
new Student("002", "Tomche"),
new Student("003", "Andrej"),
new Student("004", "Aleksandra"),
new Student("005", "Aleksandar")
);
}