original source : https://medium.com/tompee/idiomatic-kotlin-lambdas-and-sam-constructors-fe2075965bfb

This article is a part of the Idiomatic Kotlin series. The complete list is at the bottom of the article.

In this article we will explore Kotlin lambdas, SAM constructors and interoperability with Java functional interfaces. For those who are not familiar with functional programming, lambdas and functional interfaces in Java, this might not be the best entry point for you but I will try to explain as easy as possible.

What is a Lambda expression?

A lambda expression is a block of code that can be passed to another function. Functions that accept these types of functions are normally called Higher-order functions. Lambda expressions allows us to realize Functional Programming, a paradigm wherein functions are treated as values.

Before Java 8, this is achieved using anonymous inner classes. Let us look at an example.

button.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        return false;
    }
});

To achieve behavior passing, you need to create an instance of the interface and pass it to the function.

Java 8 introduced lambda expressions along with functional interfaces. A functional interface is an interface with a single method. They are commonly referred to as single abstract method or SAM. Lambda expressions represents these functional interfaces in a more concise way to deal with functional programming. Converting the above code to lambda syntax will look like

button.setOnTouchListener((v, event) -> false);

Plain and simple. Kotlin has a similar syntax for lambdas. We will discuss that in the next sections.

Motivation

Aside from conciseness, syntactic sugar and reduction of boilerplate code, there are other benefits to using lambdas as well. Lambda functions, if not capturing, each exists as a single object in the JVM and reusing them will not incur any other performance overhead. They are also generated at runtime while anonymous inner classes are class-loaded and instantiated for each call.

How to define a lambda function?

The most concise syntax for a kotlin lambda function is

{ param1 : Type1, param2 : Type2 -> body }

Specific rules to follow:

  1. Always enclosed in curly braces
  2. Left part consists of comma separated parameters. No need to enclose in parentheses. The arrow serves as the separator.
  3. The right side is the code body. This can be multi-line and the last expression can be the return value. An explicit return@<operation> can also be used.

Lambda functions can be used directly or assigned to a variable. When a lambda expression is stored in a variable, you can invoke it as a regular function or using the invoke method. A direct lambda function can be run as a function as well, but is does not offer good readability.

// Regular f(x)
val addOffset = {x : Int -> x + 1}
println(addOffset(2))

// Invoke
println(addOffset.invoke(2))

// Anonymous invocation
println({x : Int -> x + 1}(2))

A lambda can be passed to a function in a lot of ways. If the function requires a lambda as its final parameter, you can take it out of the parentheses. Other than that you use the general syntax of passing arguments.

fun addOffset(base: Int, lambda: (Int) -> Int): Int {
    return lambda.invoke(base)
}

fun addOffset(lambda: (Int) -> Int, base : Int): Int {
    return lambda.invoke(2)
}

// Last argument lambda
addOffset(2) {x : Int -> x + 1}

// General syntax
addOffset ({ x : Int -> x + 1}, 2)

There is another simplification in lambda syntax that I myself is fond of using. If the function has a single argument and its type can be inferred, an autogenerated variable named it will be available for you to use. This is handy on cases wherein you are running out of variable names, or names does not matter much but is not for cases of nested lambdas.

Differences of Java and Kotlin lambdas

Java lambdas can only access final variables. Kotlin on the other hand supports access of non-final variables. This case was briefly touched in another one of my articles. Kotlin supports this feature by wrapping the variables in a reference and the lambda function captures this reference for it to use.

Compatibility with Java Functional Interfaces

Kotlin lambdas are fully compatible with Java functional interfaces. To prove it let us decompile a simple setOnTouchListener call.

button.setOnTouchListener((OnTouchListener)(new OnTouchListener() {
   public final boolean onTouch(View v, MotionEvent e) {
      Intrinsics.checkExpressionValueIsNotNull(v, "v");
      return true;
   }
}));

The compiler is smart enough to know that the function needs an instance of View.OnTouchListener. The compiler interprets a lambda function that represents a functional interface as a instance of an anonymous class implementing that functional interface.

You may think that Kotlin just converts the lambda into an anonymous class just like the old times. Well there is a bit of a catch here. When using anonymous classes explicitly, you are always creating a new instance. But in lambda, if it is not capturing, there will exist a single instance of it that is used on every reuse.

Note: For those who are not familiar, capturing lambdas are lambdas that use variables that are outside their immediate scope. Think of it as a function in a class that uses private fields. You can say it “captures” those variables. Non-capturing on the other hand does not depend on any variable outside their immediate scope. You can think of them as pure functions.

SAM Constructors

Even though the compiler is smart enough to convert your lambda into an anonymous class implementation of functional interfaces, there are still cases wherein you need to explicitly convert. Kotlin supports explicit conversion using the SAM constructors.

SAM constructors allow you to convert a lambda expression to an instance of a function interface. The syntax is pretty straightforward.

FunctionalInterfaceName { lambda_function }

When do you need to do this you say? Let’s take a look at 2 examples.

// Assigning to a variable
val runnable : Runnable = Runnable { print("I am a runnable")}

// Returning a specific type of functional interface
fun createOnClickListener() : View.OnClickListener {
    return View.OnClickListener { v -> print("I am clicked") }
}

Both of this cases requires you to have a specific functional interface type. Lambda cannot be used directly for that.

Java SAM vs. Kotlin Function Types

Kotlin uses function types instead of interfaces. So if you are coding in pure Kotlin, it is important to use function types for lambda types as Kotlin does not support conversion of lambdas to Kotlin interfaces. More on function types soon.

Considerations

Lambdas are not without their overhead. A lambda function by default, under the hood, generates .class and surprisingly, a step towards reaching your DEX limit. There is a good summary here. Thankfully, we can reduce some of these overhead using other features such as inlining. This will be discussed in one of the future articles so watch out for it.

Check out the other articles in the idiomatic kotlin series. The sample source code for each article can be found here in Github.

  1. Extension Functions
  2. Sealed Classes
  3. Infix Functions
  4. Class Delegation
  5. Local functions
  6. Object and Singleton
  7. Sequences
  8. Lambdas and SAM constructors
  9. Lambdas with Receiver and DSL
  10. Elvis operator
  11. Property Delegates and Lazy
  12. Higher-order functions and Function Types
  13. Inline functions
  14. Lambdas and Control Flows
  15. Reified Parameters
  16. Noinline and Crossinline
  17. Variance
  18. Annotations and Reflection
  19. Annotation Processor and Code Generation

original source : https://www.geeksforgeeks.org/socket-programming-in-java/

Socket Programming in Java

This article describes a very basic one-way Client and Server setup where a Client connects, sends messages to server and the server shows them using socket connection. There’s a lot of low-level stuff that needs to happen for these things to work but the Java API networking package (java.net) takes care of all of that, making network programming very easy for programmers.

Client Side Programming

Establish a Socket Connection

To connect to other machine we need a socket connection. A socket connection means the two machines have information about each other’s network location (IP Address) and TCP port.The java.net.Socket class represents a Socket. To open a socket:

Socket socket = new Socket(“127.0.0.1”, 5000)
  • First argument – IP address of Server. ( 127.0.0.1  is the IP address of localhost, where code will run on single stand-alone machine).
  • Second argument – TCP Port. (Just a number representing which application to run on a server. For example, HTTP runs on port 80. Port number can be from 0 to 65535)

Communication

To communicate over a socket connection, streams are used to both input and output the data.

Closing the connection

The socket connection is closed explicitly once the message to server is sent.

In the program, Client keeps reading input from user and sends to the server until “Over” is typed.

Java Implementation

// A Java program for a Client
import java.net.*;
import java.io.*;

public class Client
{
// initialize socket and input output streams
private Socket socket = null;
private DataInputStream input = null;
private DataOutputStream out = null;

// constructor to put ip address and port
public Client(String address, int port)
{
// establish a connection
try
{
socket = new Socket(address, port);
System.out.println(“Connected”);

// takes input from terminal
input = new DataInputStream(System.in);

// sends output to the socket
out = new DataOutputStream(socket.getOutputStream());
}
catch(UnknownHostException u)
{
System.out.println(u);
}
catch(IOException i)
{
System.out.println(i);
}

// string to read message from input
String line = “”;

// keep reading until “Over” is input
while (!line.equals(“Over”))
{
try
{
line = input.readLine();
out.writeUTF(line);
}
catch(IOException i)
{
System.out.println(i);
}
}

// close the connection
try
{
input.close();
out.close();
socket.close();
}
catch(IOException i)
{
System.out.println(i);
}
}

public static void main(String args[])
{
Client client = new Client(“127.0.0.1”, 5000);
}
}

Server Programming

Establish a Socket Connection

To write a server application two sockets are needed.

  • A ServerSocket which waits for the client requests (when a client makes a new Socket())
  • A plain old Socket socket to use for communication with the client.

Communication

getOutputStream() method is used to send the output through the socket.

Close the Connection

After finishing,  it is important to close the connection by closing the socket as well as input/output streams.

// A Java program for a Server
import java.net.*;
import java.io.*;

public class Server
{
//initialize socket and input stream
private Socket socket = null;
private ServerSocket server = null;
private DataInputStream in = null;

// constructor with port
public Server(int port)
{
// starts server and waits for a connection
try
{
server = new ServerSocket(port);
System.out.println(“Server started”);

System.out.println(“Waiting for a client …”);

socket = server.accept();
System.out.println(“Client accepted”);

// takes input from the client socket
in = new DataInputStream(
new BufferedInputStream(socket.getInputStream()));

String line = “”;

// reads message from client until “Over” is sent
while (!line.equals(“Over”))
{
try
{
line = in.readUTF();
System.out.println(line);

}
catch(IOException i)
{
System.out.println(i);
}
}
System.out.println(“Closing connection”);

// close connection
socket.close();
in.close();
}
catch(IOException i)
{
System.out.println(i);
}
}

public static void main(String args[])
{
Server server = new Server(5000);
}
}

Important Points

  • Server application makes a ServerSocket on a specific port which is 5000. This starts our Server listening for client requests coming in for port 5000.
  • Then Server makes a new Socket to communicate with the client.
socket = server.accept()
  • The accept() method blocks(just sits there) until a client connects to the server.
  • Then we take input from the socket using getInputStream() method. Our Server keeps receiving messages until the Client sends “Over”.
  • After we’re done we close the connection by closing the socket and the input stream.
  • To run the Client and Server application on your machine, compile both of them. Then first run the server application and then run the Client application.

To run on Terminal or Command Prompt

Open two windows one for Server and another for Client

1. First run the Server application as ,

$ java Server

Server started
Waiting for a client …

2. Then run the Client application on another terminal as,

$ java Client

It will show – Connected and the server accepts the client and shows,

Client accepted

3. Then you can start typing messages in the Client window. Here is a sample input to the Client

Hello
I made my first socket connection
Over

Which the Server simultaneously receives and shows,

Hello
I made my first socket connection
Over
Closing connection

Notice that sending “Over” closes the connection between the Client and the Server just like said before.

If you’re using Eclipse or likes of such-

  1. Compile both of them on two different terminals or tabs
  2. Run the Server program first
  3. Then run the Client program
  4. Type messages in the Client Window which will be received and showed by the Server Window simultaneously.
  5. Type Over to end.

This article is contributed by Souradeep Barua. If you like GeeksforGeeks and would like to contribute, you can also write an article and mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

또 다른 socket programming in java 설명

original source : https://www.javatpoint.com/socket-programming

Java Socket Programming

Java Socket programming is used for communication between the applications running on different JRE.

Java Socket programming can be connection-oriented or connection-less.

Socket and ServerSocket classes are used for connection-oriented socket programming and DatagramSocket and DatagramPacket classes are used for connection-less socket programming.

The client in socket programming must know two information:

  1. IP Address of Server, and
  2. Port number.

Here, we are going to make one-way client and server communication. In this application, client sends a message to the server, server reads the message and prints it. Here, two classes are being used: Socket and ServerSocket. The Socket class is used to communicate client and server. Through this class, we can read and write message. The ServerSocket class is used at server-side. The accept() method of ServerSocket class blocks the console until the client is connected. After the successful connection of client, it returns the instance of Socket at server-side.

Socket class

A socket is simply an endpoint for communications between the machines. The Socket class can be used to create a socket.

Important methodsMethodDescription

1) public InputStream getInputStream()

          returns the InputStream attached with this socket.

2) public OutputStream getOutputStream()

          returns the OutputStream attached with this socket.

3) public synchronized void close()

          closes this socket

ServerSocket class

The ServerSocket class can be used to create a server socket. This object is used to establish communication with the clients.

Important methodsMethodDescription

1) public Socket accept()

          returns the socket and establish a connection between server and client.

2) public synchronized void close()

          closes the server socket.

Example of Java Socket Programming

Creating Server:

To create the server application, we need to create the instance of ServerSocket class. Here, we are using 6666 port number for the communication between the client and server. You may also choose any other port number. The accept() method waits for the client. If clients connects with the given port number, it returns an instance of Socket.

  1. ServerSocket ss=new ServerSocket(6666);  
  2. Socket s=ss.accept();//establishes connection and waits for the client  

Creating Client:

To create the client application, we need to create the instance of Socket class. Here, we need to pass the IP address or hostname of the Server and a port number. Here, we are using “localhost” because our server is running on same system.

  1. Socket s=new Socket(“localhost”,6666);  

Let’s see a simple of Java socket programming where client sends a text and server receives and prints it.

File: MyServer.java

  1. import java.io.*;  
  2. import java.net.*;  
  3. public class MyServer {  
  4. public static void main(String[] args){  
  5. try{  
  6. ServerSocket ss=new ServerSocket(6666);  
  7. Socket s=ss.accept();//establishes connection  
  8. DataInputStream dis=new DataInputStream(s.getInputStream());  
  9. String  str=(String)dis.readUTF();  
  10. System.out.println(“message= ”+str);  
  11. ss.close();  
  12. }catch(Exception e){System.out.println(e);}  
  13. }  
  14. }  

File: MyClient.java

  1. import java.io.*;  
  2. import java.net.*;  
  3. public class MyClient {  
  4. public static void main(String[] args) {  
  5. try{      
  6. Socket s=new Socket(“localhost”,6666);  
  7. DataOutputStream dout=new DataOutputStream(s.getOutputStream());  
  8. dout.writeUTF(“Hello Server”);  
  9. dout.flush();  
  10. dout.close();  
  11. s.close();  
  12. }catch(Exception e){System.out.println(e);}  
  13. }  
  14. }  

download this example

To execute this program open two command prompts and execute each program at each command prompt as displayed in the below figure.

After running the client application, a message will be displayed on the server console.

Example of Java Socket Programming (Read-Write both side)

In this example, client will write first to the server then server will receive and print the text. Then server will write to the client and client will receive and print the text. The step goes on.

File: MyServer.java

  1. import java.net.*;  
  2. import java.io.*;  
  3. class MyServer{  
  4. public static void main(String args[])throws Exception{  
  5. ServerSocket ss=new ServerSocket(3333);  
  6. Socket s=ss.accept();  
  7. DataInputStream din=new DataInputStream(s.getInputStream());  
  8. DataOutputStream dout=new DataOutputStream(s.getOutputStream());  
  9. BufferedReader br=new BufferedReader(new InputStreamReader(System.in));  
  10.  
  11. String str=“”,str2=“”;  
  12. while(!str.equals(“stop”)){  
  13. str=din.readUTF();  
  14. System.out.println(“client says: ”+str);  
  15. str2=br.readLine();  
  16. dout.writeUTF(str2);  
  17. dout.flush();  
  18. }  
  19. din.close();  
  20. s.close();  
  21. ss.close();  
  22. }}  

File: MyClient.java

  1. import java.net.*;  
  2. import java.io.*;  
  3. class MyClient{  
  4. public static void main(String args[])throws Exception{  
  5. Socket s=new Socket(“localhost”,3333);  
  6. DataInputStream din=new DataInputStream(s.getInputStream());  
  7. DataOutputStream dout=new DataOutputStream(s.getOutputStream());  
  8. BufferedReader br=new BufferedReader(new InputStreamReader(System.in));  
  9.  
  10. String str=“”,str2=“”;  
  11. while(!str.equals(“stop”)){  
  12. str=br.readLine();  
  13. dout.writeUTF(str);  
  14. dout.flush();  
  15. str2=din.readUTF();  
  16. System.out.println(“Server says: ”+str2);  
  17. }  
  18.  
  19. dout.close();  
  20. s.close();  
  21. }}  

How to get names of classes inside a jar file?