Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save nathanatstariongroup/2f14839e8aa6453e7195ef1c2b25f264 to your computer and use it in GitHub Desktop.
Save nathanatstariongroup/2f14839e8aa6453e7195ef1c2b25f264 to your computer and use it in GitHub Desktop.
Java Starter

Java guide for .Net developer

                                                    ( (
                                                     ) )
                                                   ........
                                                   |      |]
                                                   \      /                     
                                                    `----'                     

Table of contents

Disclaimer

This document has been produced from observations made from a java project I worked on. Some part of it may be incomplete or wrong. Please feel free to make any comment and request any change.

Introduction

First step: don't cry!

Syntax highlights

Linq vs Stream

Reading

Quick help

.Net Java REM
IEnumerable<T> Collection<T>
IEnumerator<T> Iterator<T> stackoverflow
Linq Stream
Where() filter()
Select() map()
Cast<T>() map()
FirstOrDefault() .filter(Predicate<? super T> predicate).findFirst().orElse(default(? super T)) default(? super T) => what ever default value the type has
Any() findAny()
Any(Predicate) .filter(Predicate).findAny()

Yield

yield return doesn't exist in Java as is. However using RXJava can micmac it.

Use an Observable as a "yielder". It can be used in a similar fashion if you make your own Observable. Observables can be transformed into iterators so you can even use them in more traditional for loops.

protected void GetStrings(Observer<? super String> observer)
{
    observer.onNext("a"); // yield
    observer.onComplete(); // finish
}

source : StackOverflow

Object initializer

  • .Net
    new Implementation() { Property = "value"}

the above syntax does not have the same meaning in Java.

  • Java

You can use it to create an anonimous implementation of a Interface:

this.okButton.addActionListener(new ActionListener() 
    {        
        @Override         
        public void actionPerformed(ActionEvent e) 
        {
            IterationSelectionAction();
        }
    });

Or to create an implementation that extends/ inherits from the specified class and override some overridable methods:

ElementDefinition elementDefinition = new ElementDefinition()
{
    @Override
    public void setContainer(Thing container)
    {
        // TODO Auto-generated method stub
        super.setContainer(container); 
    }
};

Inheritance

BEWARE hiding and overriding overidden methods are allowed and sneaky

Enum

Java enums default value is null. Example:

public static void main(String []args)
{
    System.out.println(new Cage().Animal); // Outputs NULL
}

public static class Cage
{
    public Animals Animal;
}

public enum Animals
{
    Dog,
    Cat
}

The same in .Net would result in 0/Dog SharpLab example

Apparently a reference to an enum value in Java points to a reference type;

Probably usefull example of enum in java

enum Color
{
    Red(255, 0, 0), 
    Green(0, 255, 0), 
    Blue(0, 0, 255),
    Purple(127, 0, 127);
    
    private byte blue;
    private byte green;
    private byte red;

    Color(int red, int green, int blue)
    {
        this.red = (byte)(red & 0xff);
        this.green = (byte)(green & 0xff);
        this.blue = (byte)(blue & 0xff);
    }
    
    public Color Add(int red, int green, int blue)
    {
        this.red += red;
        this.green += green;
        this.blue += blue;
        return this;
    }
    
    public Color Add(Color color)
    {
        return this.Add(color.red, color.green, color.blue);
    }
    
    @Override
    public String toString()
    {
        return String.format("{%s, %s, %s}", this.red& 0xff, this.green& 0xff, this.blue& 0xff);
    }
}

Sugar

Question: Is there an easy way to ... ?

Answer: No!

Interfaces

In Java interfaces have the same purpose as in .Net. However there is a couple of differences that should pointed out: TBD

Generics

Generics have been arround for sometimes now 2002 they were implemented in .NET Framework 2.0 and in 2004 in Java 1.5.

In the name of retrocompatibility in Java the typeParameter is errased at compile time in Java.

Long story short, when implementing a generic class or method in Java consider storing the type along:

/**
 * The {@linkplain Ref} is a value wrapper where the generic type can be any thing, as suggested by many java developers, 
 * to overcome the lack of {@linkplain ref} and {@linkplain out}
 * 
 * @param <TType> the type of the contained reference
 */
public final class Ref<TType>
{
    /**
     * The reference this holds
     */
    private TType reference;
    
    /**
     * The class type of this reference 
     */
    private Class<TType> clazz;

    /**
     * Initializes a new Type wrapper {@linkplain Ref}
     * Acts like the out keyword
     * 
     * @param reference the reference this will hold
     * @param clazz the type of the held reference
     */
    public Ref(Class<TType> clazz, TType reference) 
    {
        this.reference = reference;
        this.clazz = clazz;
    }
}

Another note on generics:

In .Net primitive can be used as generic type

    var numbers = new List<int>();

but not in java

    List<int> list = new ArrayList<int>(); // DOES NOT COMPILE

Instead a reference type is required

    List<Integer> list = new ArrayList<>(); // COMPILES
    List<Boolean> list = new ArrayList<>(); // COMPILES
    List<Byte> list = new ArrayList<>(); // COMPILES
    List<byte> list = new ArrayList<>(); // DOES NOT COMPILE

Ref and Out

Because every method parameter are passed by value in Java, and most importantly that the ref key doesn't exist. You might want to implement a wrapper class that act like it. Example:

/**
 * The {@linkplain Ref} is a value wrapper where the generic type can be any thing, as suggested by many java developers, 
 * to overcome the lack of {@linkplain ref} and {@linkplain out}
 * 
 * @param <TType> the type of the contained reference
 */
public final class Ref<TType>
{
    /**
     * The reference this holds
     */
    private TType reference;
    
    /**
     * The class type of this reference 
     */
    private Class<TType> clazz;
    
    /**
     * Gets the enclosed reference
     * 
     * @return a {@linkplain TType}
     */
    public TType Get()
    {
        return this.reference;
    }
    
    /**
     * Sets the encapsulated value
     * 
     * @param value the {@linkplain TType} value
     */
    public void Set(TType value)
    {
        this.reference = value;
    }
        
    /**
     * Gets the type enclosed reference
     * 
     * @return the enclosed reference type
     */
    public Class<TType> GetType()
    {
        return this.clazz;
    }
    
    /**
     * Initializes a new Type wrapper {@linkplain Ref}
     * Acts like passing by reference
     * 
     * @param reference the reference this will hold
     * @param clazz the type of the held reference
     */
    public Ref(Class<TType> clazz, TType reference) 
    {
        this.reference = reference;
        this.clazz = clazz;
    }
    
    /**
     * Initializes a new Type wrapper {@linkplain Ref}
     * Acts like the out keyword
     * 
     * @param reference the reference this will hold
     * @param clazz the type of the held reference
     */
    public Ref(Class<TType> clazz)
    {
        this.clazz = clazz;
    }

    /**
     * Gets a value indicating whether the contained reference is != null
     * 
     * @return a {@linkplain boolean}
     */
    public boolean HasValue()
    {
        return this.reference != null;
    }
}

Architecture

Namespaces

  • .Net

Namespaces in .Net should follow the folder structure of all code file.

  • Java

In java it's the same rule, but namespaces are represented by packages. Packages contains code files and also a file called package-info.java that can be used to add document at package level. e.g.

/**
* Domain classes used to produce .....
* <p>
* These classes contain the ......
* </p>
*
* @since 1.0
* @author somebody
* @version 1.0
*/
package com.domain;

Project architecture

  • .Net

In .Net we usually have:

  • Project

    • bin
      • targets (bin)
    • obj
  • Project.Test

  • Java

The usual java equivalent is:

  • src/main/java/
    • {your group id} => usually looks like com.companyname
      • at this level resides you root packages
  • src/test/java
    • {your group id} => usually looks like com.companyname
      • The namespaces usually matches the main project structure. In this regard adding package-info.java will result in a duplicate package error. Remarque since Java doesn't make any difference between similar package name between the project and the test project. No import are required to make use of references from the same namespace.
  • target => Correspond to the obj folder in .Net

Project dependencies

Maven

Maven is one external dependency managing system. But it's a little more than that: It is a build automation tool used primarily for Java project. Maven also allows through maven plugin to run the tests or to pack the generated classes to a jar.

Warning ⚠ Maven is able to reuse .class files that contains unresolved compilation error. When building a library, the problems rising from this issue are very different and misleading. The only way to spot the problem was to decompile the problematic .class and see for myself. The solution was easy enough as a manual cleanup of the local Maven repository solved the problem.

Java code style

[WIP] this section is just comments on java code style conventions.

Generic

  • Type parameter cannot be named with more that 1 letter, but can be eventually followed by 1 number. In order words, it has to match the following ^[A-Z][0-9]?$
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment