Putting it together
- Java course
- Advanced
- Lesson 77/82
- 6 min
Combine all layers into a working mini service.
Putting it together
In the final lesson you combine all layers. In main you will run this flow:
- Apply a stream filter on
ledgerand print the filtered count. - Compute the total with
ExecutorServiceand print it. - Call
testGetCountof theLedgerServiceTestclass. - Finally print
service.getCount().
These steps are all deterministic, so the output is the same every time. This shows how an advanced app is built layer by layer.
Practice Combine the whole flow
Use the previous lesson's solution. In main add: compute service.ledger.stream().filter(t -> t.amount > 100).count() and print it. Compute the total with ExecutorService, get it with pool.submit(task).get() and print it. Create a LedgerServiceTest instance and call testGetCount(). Finally print service.getCount().
Starter code
import java.util.ArrayList;
import java.util.concurrent.*;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class Transaction {
String category;
int amount;
Transaction(String category, int amount) {
this.category = category;
this.amount = amount;
}
}
class LedgerService {
ArrayList<Transaction> ledger = new ArrayList<>();
void add(Transaction t) { ledger.add(t); }
int getCount() { return ledger.size(); }
}
class LedgerServiceTest {
@Test
void testGetCount() {
LedgerService s = new LedgerService();
s.add(new Transaction("market", 120));
assertEquals(1, s.getCount());
}
}
public class Main {
public static void main(String[] args) throws Exception {
LedgerService service = new LedgerService();
service.add(new Transaction("market", 120));
service.add(new Transaction("fuel", 80));
// Combine the flow: filter, concurrent total, test, print
}
}Sample solution
import java.util.ArrayList;
import java.util.concurrent.*;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class Transaction {
String category;
int amount;
Transaction(String category, int amount) {
this.category = category;
this.amount = amount;
}
}
class LedgerService {
ArrayList<Transaction> ledger = new ArrayList<>();
void add(Transaction t) { ledger.add(t); }
int getCount() { return ledger.size(); }
}
class LedgerServiceTest {
@Test
void testGetCount() {
LedgerService s = new LedgerService();
s.add(new Transaction("market", 120));
assertEquals(1, s.getCount());
}
}
public class Main {
public static void main(String[] args) throws Exception {
LedgerService service = new LedgerService();
service.add(new Transaction("market", 120));
service.add(new Transaction("fuel", 80));
long filteredCount = service.ledger.stream()
.filter(t -> t.amount > 100)
.count();
ExecutorService pool = Executors.newSingleThreadExecutor();
Callable<Integer> task = () -> {
int sum = 0;
for (Transaction t : service.ledger) sum += t.amount;
return sum;
};
int total = pool.submit(task).get();
pool.shutdown();
LedgerServiceTest test = new LedgerServiceTest();
test.testGetCount();
System.out.println(filteredCount);
System.out.println(total);
System.out.println(service.getCount());
}
}Expected output
1 200 2
Practice Summary: a mini integration
Define a new Summary class. Give it a void run() method that builds a LedgerService with two records and prints getCount() and the result of stream().filter(t -> t.amount > 100).count() on separate lines. In main, call new Summary().run().
Starter code
import java.util.ArrayList;
class Transaction {
String category;
int amount;
Transaction(String category, int amount) {
this.category = category;
this.amount = amount;
}
}
class LedgerService {
ArrayList<Transaction> ledger = new ArrayList<>();
void add(Transaction t) { ledger.add(t); }
int getCount() { return ledger.size(); }
}
// Define the Summary class
public class Main {
public static void main(String[] args) {
// Run a Summary instance
}
}Sample solution
import java.util.ArrayList;
class Transaction {
String category;
int amount;
Transaction(String category, int amount) {
this.category = category;
this.amount = amount;
}
}
class LedgerService {
ArrayList<Transaction> ledger = new ArrayList<>();
void add(Transaction t) { ledger.add(t); }
int getCount() { return ledger.size(); }
}
class Summary {
void run() {
LedgerService s = new LedgerService();
s.add(new Transaction("market", 120));
s.add(new Transaction("fuel", 80));
System.out.println(s.getCount());
long big = s.ledger.stream().filter(t -> t.amount > 100).count();
System.out.println(big);
}
}
public class Main {
public static void main(String[] args) {
new Summary().run();
}
}Expected output
2 1
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 Which layers run together in the combining lesson?
- Stream, Concurrent and Test Correct answer
- Only Concurrent
- Only Stream
- Only Test
Explanation: Stream, Concurrent and Test layers run in the same main.
2 Complete the Future.get call
ExecutorService pool = Executors.newSingleThreadExecutor();
Callable<Integer> task = () -> { /* toplam */ return 200; };
int total = pool.submit(task).____();
ExecutorService pool = Executors.newSingleThreadExecutor();
Callable<Integer> task = () -> { /* toplam */ return 200; };
int total = pool.submit(task).get();
Explanation: get() blocks until the result is ready and returns it.
3 Match the project summary
| Term | Meaning |
|---|---|
Transaction |
Model class |
Stream filter |
Records over 100 |
ExecutorService |
Concurrent total |
LedgerServiceTest |
Unit test |