Tuesday, May 9, 2017

Evolve ....

 
Collections.sort(itemList, new Comparator<Item>() {
    @Override    public int compare(Item o1, Item o2) {
        return o1.getItemId().compareTo(o2.getItemId());    }
});



 
Collections.sort(itemList, (o1, o2) -> o1.getItemId().compareTo(o2.getItemId()));
 

 
Collections.sort(itemList, Comparator.comparing(Item::getItemId));
 


Sunday, April 2, 2017

Java8 streams and lambda expression GroupBy MaxBy MinBy Example

package com.company.samples;
import java.util.*;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.stream.Collectors;
import static java.util.stream.Collectors.*;
public class Java8GroupByMaxByMinByExample {
public static void main (String[] args) {
Student s1 = new Student ("Shyam", 22, "A");
Student s2 = new Student ("Ram", 23, "A");
Student s3 = new Student ("Mohan", 22, "B");
Student s4 = new Student ("Ramesh", 21, "B");
List<Student> list = Arrays.asList (s1, s2, s3, s4);
Comparator<Student> ageComparator = Comparator.comparing (Student::getAge);
//Find eldest student in each class and group by class
Map<String, Optional<Student>> eldestByClass = list.stream ().
collect (groupingBy (Student::getClassName, Collectors.reducing (BinaryOperator.maxBy (ageComparator))));
//Group students by classname
Map<String, List<Student>> studentsByClass = list.stream ()
.collect (groupingBy (s -> s.getClassName ()));
//Group students by age for each class
Map<String, List<Integer>> studentAgesByClass = list.stream ()
.collect (groupingBy (st -> st.getClassName (), mapping ((Student s) -> s.getAge (), toList ())));
//Group students by classname
Map<String, List<String>> studentNamesByClass = list.stream ()
.collect (groupingBy (s -> s.getClassName (), mapping ((Student s) -> s.getName (), toList ())));
//another syntax -1
Map<String, List<String>> studentNamesByClass2 = list.stream ()
.collect (groupingBy (s -> s.getClassName (), mapping (s -> s.getClassName (), toList ())));
//another syntax -2
Map<String, List<String>> studentNamesByClass3 = list.stream ()
.collect (groupingBy (s -> s.getClassName (), mapping (Student::getClassName, toList ())));
//another syntax -3 use set instead of List to eliminate duplications
Map<String, Set<String>> studentNamesByClass4 = list.stream ()
.collect (groupingBy (s -> s.getClassName (), mapping (Student::getClassName, toSet ())));
//Find youngest student in each class and group by class
Map<String, Optional<Student>> youngestByClass = list.stream ().collect (groupingBy (Student::getClassName,
Collectors.reducing (BinaryOperator.minBy (ageComparator))));
}
}
class Student {
private String name;
private int age;
private String className;
public Student (String name, int age, String className) {
this.name = name;
this.age = age;
this.className = className;
}
public String getName () {
return name;
}
public void setName (String name) {
this.name = name;
}
public int getAge () {
return age;
}
public void setAge (int age) {
this.age = age;
}
public String getClassName () {
return className;
}
public void setClassName (String className) {
this.className = className;
}
}

Wednesday, March 22, 2017

How Hadoop works


Hadoop divides the given input file into small parts to increase parallel processing. It uses its own file system called HDFS. Each spitted file is assigned to the mapper which works on the same physical machine with the given chunk. 

Mappers are processing small file chunks and passing their processing results to context.Mappers are processing splitted files (each chunk {piece of the main file} size = HDFS block size) line by line in the map function .

Hadoop supports different programming languages so it uses its own serilization/deseriliazation mechanism. That why you see IntWritable, LongWritable,etc types in the examples. You can write your own Writable classess by implementing the Writable interface according to your requirements.

Hadoop collects all different outputs of the mappers and sort them by KEY and forwards these results to Reducers.


"Book says all values with same key will go to same reducer"



map (Key inputKey, Value inputValue, Key outputKey, Value outputValue)


reduce (Key inputKeyFromMapper, Value inputValueFromMapper, Key outputKey, Value output value)



Hadoop calls reduce function for the each line of given file.

And finally writes the result of reducers to the HDFS file system.

See the WordCount example for better understanding : hadoop-wordcount-example


Friday, March 10, 2017

Kafka Basics, Producer, Consumer, Partitions, Topic, Offset, Messages

Kafka is a distributed system that runs on a cluster with many computers. Producers are the programs that feeds kafka brokers. A broker is a kafka server which stores/keeps/maintains incoming messages in files with offsets. Each message is stored in a file with an index , actually this index is an offset. Consumers are the programs which consumes the given data with offsets. Kafka does not deletes consumed messages with its default settings. Messages stays still persistent for 7 days with default configuration of Kafka.



Topics are the contracts between the producer and consumers. Producer pushes messages to a specific topic and consumers consumes messages from that specific topic. There can be many different topics and Consumer Groups which are consuming data from a specific topic according to your business requirements.





If topic is very large (larger than the storage capacity of a computer) then kafka can use other computers as a cluster node to store that large topic. Those nodes are called as partition in kafka terminology. So each topic may be divided in many partitions (computers) in the Kafka Cluster.

So how kafka make decisions on storing and dividing large topics in to the partitions ? Answer : It does not !


So you should make calculations according to your producer/consumer load, message size and storage capacity. This concept is called as partitioning. Kafka expect you to implement Partitioner interface. Of course there is a default partitioner (SimplePartitioner implements Partitioner).




As a result; A topic is divided into many partitions and each partition has its own OffSet and each consumer reads from different partitions but many consumers can not read from same partition to prevent duplicated reads.

If you need to collect specific messages on the specific partition you should use message keys. Same keys are always collected in the same partition. By the way those messages are consumed by the same Consumer.

Topic partitioning is the key for parallelism in Kafka. On both the producer and the broker side, writes to different partitions can be done fully in parallel. So it is important to have much partitions for a better Performance !

Please see the below use case which shows semantics of a kafka server for a  game application's events for some specifics business requirements. All the messages related to a specific game player is collected on the particular partition. UserIds are used as message keys here.


I tried to briefly summarize it... I am planning to add more post about  data pipelining with: 
 Hadoop->Kafka->Spark | Storm  etc..

Bye

Images are taken from: Learning Journal and Cloudera 


Monday, March 6, 2017

Scalable System Design Patterns

1) Load Balancer : 












2) Scatter and Gather: 











3) Result Cache :











4) Shared Space












5) Pipe and Filter













6) Map Reduce












7)Bulk Synchronous Parellel












8)Execution Orchestrator



Friday, March 3, 2017

REDIS 101


Client Libraries:


Data Types

1) Strings : BinarySafe: MAX 512 MB, you can even save images etc..
2) Set : Unique list of elements. Useful when operation on two different key with : intersect, union, difference

3) SortedSet

4) List
5) Hash : Useful for storing objects with fields. name, surname etc...

Pipelining : Less blocking client code can be achived by means of it : Send multiple request and get one answer as result. Consider: split them to multiple pipelines to reduce memory requirements on server side.using pipelining Redis running on an average Linux system can deliver even 500k requests per second.Is not it enough ? 


Pub/Sub: implements org.springframework.data.redis.connection.MessageListener





Thursday, February 16, 2017

Java 8 Optional examples and usage

        Why OptionalUse it with streams , use it in your return types, make your code safer against to the NPE, make your code more readable...This allows the caller to continue a chain of fluent method calls.

And NoteThe key here is the focus on use as a return type. The class is definitively not intended for use as a property of a Java Bean. Witness to this is that Optional does not implement Serializable, which is generally necessary for widespread use as a property of an object.


If you really wonder what will change in your life with this new Stolen keyword (from Guava) you'd better to read its origin.

More code & less bullshit.. Lets see its usage then..







package com.company.samples.optional;
import com.company.samples.way10.Worker;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
/**
#### There are few ways of creating Optional ###
opt = Optional.of(notNull); will throw exception if it is null
 
opt = Optional.ofNullable(mayBeNull);
 
opt = Optional.empty();
Usages of the Optional.X -> : of (), ofNullable (), empty (), get (), map (), filter (), ifPresent (), orElse ()
*/
public class OptionalTester {
public static void main (String[] args) {
Optional<Worker> workerOptional = getSomeBeanFromSomeWhere ();
Optional<Worker> nullWorkerOptional = getSomeNullBeanFromSomeWhere ();
// # 1) ifpresent -> alternative for if null check
nullWorkerOptional.ifPresent (w -> System.out.println ("ifPresent->worker" + w));
workerOptional.ifPresent (w -> System.out.println ("ifPresent->worker" + w));
// # 2) get -> // will throw an exc if optional is empty
try {
// this line will cause an java.util.NoSuchElementException: No value present
Worker worker = nullWorkerOptional.get ();
System.out.println ("get-> nullworker = " + worker);
} catch (Exception e) {
e.printStackTrace ();
//will print stackTrace of java.util.NoSuchElementException: No value present
}
try {
Worker worker = workerOptional.get ();
System.out.println ("get-> nonNullworker = " + worker);// will print this line
} catch (Exception e) {
e.printStackTrace ();
// this will not throw exception cause it is not null
// but as a programmer you should use try/catch with optional.get
}
// # 3) get -> // provide something other if it is empty , equivalent of the if( worker == null){ return alternativeWorker;}
Worker worker = nullWorkerOptional.orElse (alternativeWorkerFromSomeWhereElse ());
System.out.println ("orElse-> nullWorker = " + worker);
worker = workerOptional.orElse (alternativeWorkerFromSomeWhereElse ());
System.out.println ("orElse-> nonNull = " + worker);
// # Optional + filter usage, equivalent of the if( worker == null && !name.equals ( "Logan")){ print (wroker);}
boolean notLoganFound = workerOptional.filter (w -> w.getName ().equals ("Logan")).isPresent ();
System.out.println ("filter-> compare = " + notLoganFound);
notLoganFound = workerOptional.isPresent () && !workerOptional.get ().getName ().equals ("Logan");
System.out.println ("filter-> compare = " + notLoganFound);
// # Optional + map usage, check and transform the data
workerOptional.map (w -> {
w.setName ("animal");
return w;
}).ifPresent (w -> System.out.println ("ifPresent->TransformedWorker" + w));
//think about the below statement ...We are using a null worker but it does not throw exception, nice huh ?
nullWorkerOptional.map (w -> {
w.setName ("animal");
return w;
}).ifPresent (w -> System.out.println ("ifPresent->TransformedNULLWorker" + w));
//orElse usage
Worker unWrappedNonNullValueOfOptionalWithOrElse = nullWorkerOptional.orElseGet (() -> getSomeBeanFromSomeWhere ().get ());
System.out.println ("unWrappedNonNullValueOfOptionalWithOrElse = " + unWrappedNonNullValueOfOptionalWithOrElse);
// And converting to the lists
List<Worker> workerList = nullWorkerOptional.map (Collections::singletonList).orElse (Collections.emptyList ());
System.out.println ("Arrays.toString (workerList.toArray ()) = " + Arrays.toString (workerList.toArray ()));
}
private static Worker alternativeWorkerFromSomeWhereElse () {
return new Worker ("Wolverine", 182, 79);
}
public static Optional<Worker> getSomeBeanFromSomeWhere () {
return Optional.of (new Worker ("Logan", 182, 79));
}
public static Optional<Worker> getSomeNullBeanFromSomeWhere () {
Worker nullWorker = null;
return Optional.ofNullable (nullWorker);
}
}
And you can use in streams as follows
Worker w1 = new Worker ("w1", 181, 81);
Worker w2 = new Worker ("w2", 182, 82);
Worker w3 = new Worker ("w3", 183, 83);
Worker w4 = null;
Worker w5 = new Worker ("w5", 185, 85);
List<Optional<Worker>> workerList = new ArrayList<> ();
workerList.add (Optional.ofNullable (w1));
workerList.add (Optional.ofNullable (w2));
workerList.add (Optional.ofNullable (w3));
workerList.add (Optional.ofNullable (w4));
workerList.add (Optional.ofNullable (w5));
List<Optional<Worker>> nonNullList = workerList.stream ().filter (w -> w.isPresent ()).collect (Collectors.toList ());
System.out.println ("Arrays.toString (workerList.toArray ()) = " + Arrays.toString (nonNullList.toArray ()));
view raw streamsOptional hosted with ❤ by GitHub

Thursday, February 9, 2017

Java 8 Lambda Building Blocks: Predicate, Function, Consumer, Supplier, BinaryOperator

















Let the code explain itself..Be quiet...And read..







Predicate<T>-- T in ,boolean out
Predicate<Man> richManMatcher = m->m.getCashAmount () > 1000000;
if (richManMatcher.test (someMan)) {
marryWithRichMan (someMan);
}
Function<T,R> -- Tin, R out
Function<Worker,Integer> salaryIncreaser = w->w.getSalary () + 500;
for (Worker worker: workers){
worker.setSalary (salaryIncreaser.apply(worker));
}
// OR with Method References
workers.stream ().map (salaryIncreaser::apply);
BiFunction<T,U,R> -- Tin, R out
Worker worker = new Worker ("worker",120,80);
List<Worker> workers = new ArrayList<> ();
BiFunction<Integer, Integer, Integer> bodyIndexCalculator = (h,w) -> h/w;
Integer workerBodyIndex = bodyIndexCalculator.apply (worker.getHeight (), worker.getWeight ());
workers.stream ().mapToInt (w->bodyIndexCalculator.apply (w.getHeight (),w.getWeight ())).average ();
Consumer<T> --T in, void
Consumer<Worker> salaryIncreaser = w->w.setSalary (w.getSalary () * 1.2);
for (Worker worker: workers){
salaryIncreaser.accept(worker));
}
Supplier<T> -- Nothing In -- T out
Supplier<Worker> hardWorkingWorkerSupplier = ()->randomWorkerFromSomeWhere();
Worker w = hardWorkingWorkerSupplier.get();
BinaryOperator<T> -- TwoT's in, T out
BinaryOperator<Integer> multiplier = (n1,n2) ->n1 * n2;
int multipliedvalue = multiplier.apply (n1,n2);



Bye


Java 8 Lambda Expressions

I'll try to explain the topic according to my motto --"No bullshit , Just Code.."

1) SAM= Single Abstract Method = An Interface with Only One Method = Functional Interface

@FunctionalInterface
public interface StateChangeListener {
public String onStateChange(State oldState, State newState);
}
view raw sam hosted with ❤ by GitHub
2) A class with a method which will consume a lambda expression

public class StateManager {
public void addNewStateListener(StateChangeListener listener) { //blahh }
}
view raw LamdbaConsumer hosted with ❤ by GitHub
3) Now.. Actionnn...Lambda expression as a parameter

StateManager stateManager = new StateManager();
stateManager.addNewStateListener(
(oldState, newState) -> System.out.println("State changed")
);




Okeyy... I know some of you need bullshit also :)

If you want to pass a behavior to a parameter (behavior= function=action) just create an interface and annotate it @FunctionalInterface and use Lambda Syntax like i did in above.

(param1,param2,,,,,paramN) -> {play with params}

Java 8 lots of built in @FunctionalInterface inside it. You can use them anywhere you need. Just  google for them .

Bye

Wednesday, February 8, 2017

Adapter Pattern VS Decorator Patter VS Facade Pattern VS Proxy Pattern VS Bridge Pattern - Summary - Table

I know this is not very presentable but it is easier to remember design patterns in the below format (at least for me).
Whatever...
Above is a list of Structural Design Patterns.
All of them is encapsulates some objects or interfaces and delegates the calls to them at the bottom . 
So what is difference between them on top of their behaviour ?
The difference is your intent !

And I don't recommend you to memorize them .Just read them once and hope to get an inspiration when you needed those.

Just encapsulate and delegate. --From "The Joy of Painting"


Friday, January 6, 2017

Favor object composition over class inheritance in Java with Project Lombok Delegate annotation


Subject: Object composition in Java via Lombok @Delegate annotation

Problem Statement : One common drawback of using composition instead of inheritance is that methods being provided by individual components may have to be implemented in the derived type, even if they are only forwarding methods. In contrast, inheritance does not require all of the base class's methods to be re-implemented within the derived class. Rather, the derived class only need to implement (override) the methods having different behavior than the base class methods. This can require significantly less programming effort if the base class contains many methods providing default behavior and only a few of them need to be overridden within the derived class.

Solution: This drawback can be avoided by using traits, mixins, or protocol extensions. Some languages, such as Perl 6, provide a handles keyword to facilitate method forwarding. In Java, Project Lombok lets you implement delegation using a single @Delegate annotation on the field instead of copying and maintaining names and types of all methods from the delegated field


Code : For the ones who says - "No bullshit , just the code..." :))

import lombok.Data;
@Data
public class BasicStudent {
    private String name;

    public void writeYourNameOnTheBlackBoard (){
        System.out.println ("There is no He/she/it in turkish because we are not sexists :) ");
    }
}


import lombok.experimental.Delegate;
public class EnhancedStudent {

    @Delegate
    BasicStudent beaFeaturesCameHereWithAnnotation;

}

public class StudentProcessor {
    public static void main (String[] args) {
        EnhancedStudent enhancedStudent = new EnhancedStudent ();
        enhancedStudent.writeYourNameOnTheBlackBoard ();
    }
}


 -- for the memory of Christoph Portman

Tuesday, January 3, 2017

Java Maze solver program

Copy , paste, run... The ones are the walls in the below matrix and zeroes are open ways in the labyrinth. We are trying to find shortest path to the given destination : which is (x,y)-> (19,8) here in the example Just modify the maze by playing with the Ones and Zeroes and run it in your local
package com.company.samples.way8;
public class JavaMazeSolver {
public static void main (String[] args) {
// A sample maze to solve...
// We will try to reach to cell [6][8] = val-> (-1)
int exitRow = 19;
int exitColumn = 8;
// One(s)=1 are the blocked cells,
// Zero(s)=0 are the open cells
int[][] maze = new int[][]{
//0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
{ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },//0
{ 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 },//1
{ 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0 },//2
{ 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0 },//3
{ 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 },//4
{ 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 },//5
{ 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 },//6
{ 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1 },//7
{ 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 },//8
{ 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 },//9
{ 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 },//10
{ 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1 },//11
{ 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 },//12
{ 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 },//13
{ 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 },//14
{ 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1 },//15
{ 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 },//16
{ 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 },//17
{ 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 },//18
{ 1, 0, 1, 0, 1, 1, 1, 1,-1, 1, 1, 1, 1, 1, 1, 1 },//19
{ 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 },//20
{ 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 } //21
};
// This is someting like linkedList...
// We need a two dimensional array, same sized with the given maze
LinkedMatrixCell[][] linkedMatrixMatrixCell = new LinkedMatrixCell[maze.length][maze[0].length] ;
// Let each cell know the map
LinkedMatrixCell.setLinkedMatrixCellMaze (linkedMatrixMatrixCell);
// This will build up our whole/complete map, see this constructor
// You can print the maze after calling this if you want
new LinkedMatrixCell (0,0, maze, 0);
// now it is time to call out recursive function starting from the destination
findMinPathToTarget ( maze, exitRow, exitColumn, 0);
// And lets see some isThisTheShortestPath huh ??
displayTheNavigatableMap ( LinkedMatrixCell.getLinkedMatrixCellMaze ());
}
private static void displayTheNavigatableMap (LinkedMatrixCell[][] linkedMatrixCellMaze) {
for (int i = 0; i < linkedMatrixCellMaze.length; i++) {
for (int j = 0; j < linkedMatrixCellMaze[0].length; j++) {
if(linkedMatrixCellMaze[i][j] != null){
System.out.print ("(" + String.format ("%03d",Integer.parseInt (linkedMatrixCellMaze[i][j].toString ())) + ") ");
}else{
System.out.print ("(**) ");
}
}
System.out.println ();
}
System.out.println ("linkedMatrixCellMaze = " + linkedMatrixCellMaze);
}
public static int findMinPathToTarget (int[][] maze, int exitRow, int exitCol, int distance) {
LinkedMatrixCell[][] linkedMatrixCellMaze = LinkedMatrixCell.getLinkedMatrixCellMaze ();
LinkedMatrixCell currentCell = linkedMatrixCellMaze[exitRow][exitCol];
DistanceResult distanceResult = currentCell.setDistance2Start (distance);
int oneMoreStep = distance + 1;
DistanceResult distanceSetResult = null;
// try to go left
if (currentCell.left != null) {
distanceSetResult = currentCell.left.setDistance2Start (oneMoreStep);
if (exitCol -1 >= 0 && distanceSetResult.isThisTheShortestPath == true)
findMinPathToTarget (maze, exitRow, exitCol -1, distanceSetResult.getDistance ());
}
// try to go right
if (currentCell.right != null) {
distanceSetResult = currentCell.right.setDistance2Start (oneMoreStep);
if(exitCol + 1 <= linkedMatrixCellMaze[0].length && distanceSetResult.isThisTheShortestPath == true)
findMinPathToTarget (maze, exitRow, exitCol + 1, distanceSetResult.getDistance ());
}
// try to go down
if (currentCell.down != null) {
distanceSetResult = currentCell.down.setDistance2Start (oneMoreStep);
if(exitRow <= linkedMatrixCellMaze.length && distanceSetResult.isThisTheShortestPath == true)
findMinPathToTarget (maze, exitRow + 1, exitCol, distanceSetResult.getDistance ());
}
// try to go up
if (currentCell.up != null) {
distanceSetResult = currentCell.up.setDistance2Start (oneMoreStep);
if(exitRow >= 0 && distanceSetResult.isThisTheShortestPath == true)
findMinPathToTarget (maze, exitRow -1, exitCol, distanceSetResult.getDistance ());
}
return distance;
}
static class LinkedMatrixCell {
// let each cell has the map information
static LinkedMatrixCell[][] linkedMatrixCellMaze;
// cell coordinates : value can be 0 (open road), 1 (blocked road) , -1 (destination)
int xPosition , yPosition , value;
// I will drive my code to find always smaller distances if possible
int distance2Start = Integer.MAX_VALUE -1;
// let each cell get linked to its neighbours
LinkedMatrixCell up, down,left, right = null;
public LinkedMatrixCell (int xPosition, int yPosition, int[][] maze, int distance2Start) {
linkedMatrixCellMaze[xPosition][yPosition] = this;
this.xPosition = xPosition;
this.yPosition = yPosition;
this.value = maze[this.xPosition][this.yPosition];
// I would refactor the below statements but i guess these are more readable & understandable
if (this.yPosition > 0 && maze[xPosition][yPosition - 1] != 1) {
if (linkedMatrixCellMaze[xPosition][yPosition - 1] == null) this.left = new LinkedMatrixCell (xPosition, yPosition - 1, maze, distance2Start + 1);
else this.left = linkedMatrixCellMaze[xPosition][yPosition - 1];
}
if (this.yPosition < maze[0].length - 1 && maze[xPosition][yPosition + 1] != 1) {
if (linkedMatrixCellMaze[xPosition][yPosition + 1] == null) this.right = new LinkedMatrixCell (xPosition, yPosition + 1, maze,distance2Start + 1);
else this.right = linkedMatrixCellMaze[xPosition][yPosition + 1];
}
if (this.xPosition > 0 && maze[xPosition - 1][yPosition] != 1) {
if (linkedMatrixCellMaze[xPosition - 1][yPosition] == null) this.up = new LinkedMatrixCell (xPosition - 1, yPosition, maze,distance2Start + 1);
else this.up = linkedMatrixCellMaze[xPosition - 1][yPosition];
}
if (this.xPosition < maze.length - 1 && maze[xPosition + 1][yPosition] != 1) {
if (linkedMatrixCellMaze[xPosition + 1][yPosition] == null) this.down = new LinkedMatrixCell (xPosition + 1, yPosition, maze,distance2Start + 1);
else this.down = linkedMatrixCellMaze[xPosition + 1][yPosition];
}
}
public static void setLinkedMatrixCellMaze (LinkedMatrixCell[][] linkedMatrixCellMaze) {
LinkedMatrixCell.linkedMatrixCellMaze = linkedMatrixCellMaze;
}
public static LinkedMatrixCell[][] getLinkedMatrixCellMaze () {
return linkedMatrixCellMaze;
}
public int getDistance2Start () {
return distance2Start;
}
public DistanceResult setDistance2Start (int distance2Start) {
DistanceResult result = new DistanceResult (distance2Start, true);
DistanceResult result1 = checkOtherSide (distance2Start, this.up);
if(result1.getDistance () < result.getDistance ()){ result = result1;}
DistanceResult result2 = checkOtherSide (distance2Start, this.down);
if(result2.getDistance () < result.getDistance ()){ result = result2;}
DistanceResult result3 = checkOtherSide (distance2Start, this.left);
if(result3.getDistance () < result.getDistance ()){ result = result3;}
DistanceResult result4 = checkOtherSide (distance2Start, this.right);
if(result4.getDistance () < result.getDistance ()){ result = result4;}
return result;
}
private DistanceResult checkOtherSide (int distance2Start, LinkedMatrixCell sideCell) {
DistanceResult result;
if (sideCell != null && sideCell.getDistance2Start () + 1 < distance2Start) {
this.distance2Start = sideCell.getDistance2Start () + 1;
result = new DistanceResult (distance2Start, false);
} else {
if (this.distance2Start >= distance2Start) {
this.distance2Start = distance2Start;
result = new DistanceResult (distance2Start, true);
} else {
result = new DistanceResult (this.distance2Start, false);
}
}
return result;
}
@Override
public String toString () {
return ""+distance2Start ;
}
}
static final class DistanceResult{
int distance;
boolean isThisTheShortestPath;
public DistanceResult (int distance, boolean isThisTheShortestPath) {
this.distance = distance;
this.isThisTheShortestPath = isThisTheShortestPath;
}
public int getDistance () {
return distance;
}
@Override
public String toString () {
return "DistanceResult{" +
"distance=" + distance +
'}';
}
}
}
view raw JavaMazeSolver hosted with ❤ by GitHub

HuntMacllory Algorithm Java Implementation

package com.company.samples.way8;
import java.util.Arrays;
/**
* G C A C G C T G G C A C G C T G <= SJ
* 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
* G 0 1 1 1 1 1 1 1 1 G 0 1 1 0 0 0 0 0 0
* A 0 1 1 2 2 2 2 2 2 A 0 0 0 1 0 0 0 0 0
* C 0 1 2 2 3 3 3 3 3 C 0 0 0 0 1 0 0 0 0
* G 0 1 2 2 3 4 4 4 4 SI=> G 0 0 0 0 0 1 0 0 0
* C 0 1 2 2 3 4 5 5 5 C 0 0 0 0 0 0 1 1 0
* G 0 1 2 2 3 4 5 5 6 G 0 0 0 0 0 0 0 0 1
* C 0 1 2 2 3 4 5 5 6 C 0 0 0 0 0 0 0 0 1
* G 0 1 2 2 3 4 5 5 6 G 0 0 0 0 0 0 0 0 1
*
S-i : G-ACGC-GCG
S-j : GGCACGGC--
*
*/
public class HuntMacllury {
public static void main (String[] args) {
String si = "GACGCGCG";
String sj = "GCACGCTG";
int[][] matrix = new int[si.length () + 1][sj.length () + 1];
for (int i = 1; i < si.length () + 1; i++) {
for (int j = 1; j < sj.length () + 1; j++) {
if (si.charAt (i - 1) == sj.charAt (j - 1)) {
matrix[i][j] = matrix[i - 1][j - 1] + 1;
} else {
matrix[i][j] = matrix[i - 1][j] > matrix[i][j - 1] ? matrix[i - 1][j] : matrix[i][j - 1];
}
}
}
printMatrix (matrix);
int[][] directionMatrix = createDirectionMatrix (matrix);
directionMatrix = getIncrementalDiagonalMatrix (matrix, directionMatrix, matrix.length - 1, matrix[0].length - 1);
printMatrix (directionMatrix);
printStringI (si, directionMatrix);
printStringJ (sj, directionMatrix);
}
private static void printStringJ (String sj, int[][] directionMatrix) {
System.out.print ("S-j : ");
for (int j = 1; j < directionMatrix[0].length; j++) {
boolean charPrinted = false;
for (int i = 1; i < directionMatrix.length; i++) {
if (directionMatrix[i][j] == 1) {
if (!charPrinted) {
System.out.print (sj.charAt (j - 1));
} else {
System.out.print ("-");
}
charPrinted = true;
}
}
}
System.out.println ("");
}
private static void printStringI (String si, int[][] directionMatrix) {
System.out.print ("S-i : ");
for (int i = 1; i < directionMatrix.length; i++) {
boolean charPrinted = false;
for (int j = 1; j < directionMatrix[0].length; j++) {
if (directionMatrix[i][j] == 1) {
if (!charPrinted) {
System.out.print (si.charAt (i - 1));
} else {
System.out.print ("-");
}
charPrinted = true;
}
}
}
System.out.println ("");
}
private static void printMatrix (int[][] matrix) {
for (int i = 0; i < matrix[0].length; i++) {
for (int j = 0; j < matrix[0].length; j++) {
System.out.print (matrix[i][j] + " ");
}
System.out.println ("");
}
System.out.println ("");
}
private static int[][] getIncrementalDiagonalMatrix (int[][] matrix, int[][] directionMatrix, int starti, int startj) {
directionMatrix[starti][startj] = 1;
if (starti == 1 && startj == 1) {
return directionMatrix;
}
int i = starti;
int j = startj;
int left = matrix[i][j - 1];
int up = matrix[i - 1][j];
int diagon = matrix[i - 1][j - 1];
if (diagon >= up && diagon >= left) {
i--;
j--;
return getIncrementalDiagonalMatrix (matrix, directionMatrix, i, j);
} else if (up > diagon && up > left) {
i--;
return getIncrementalDiagonalMatrix (matrix, directionMatrix, i, j);
} else if (left > diagon && left > up) {
j--;
return getIncrementalDiagonalMatrix (matrix, directionMatrix, i, j);
}
return directionMatrix;
}
private static int[][] createDirectionMatrix (int[][] matrix) {
int[][] directionMatrix = new int[matrix.length][matrix[0].length];
for (int i = 0; i < matrix.length; i++) {
Arrays.fill (directionMatrix[i], 0);
}
return directionMatrix;
}
}
view raw HuntMacllory hosted with ❤ by GitHub