First we had while loop that requires Loop Control Variable ( LCV ) priming, boolean logic design, and update to LCV.
java.util.ArrayList<Integer> me=new java.util.ArrayList<>();
me.add(1);
me.add(2);
int count=0; //LCV priming
while(count<me.size()){ //boolean logic
System.out.println(me.get(count));
count++; //update
}
We had a problem since we had to keep track of these three components separately, so in a case of counter controlled loops, a simplified while loop was developed, called for loop. It is a ternary operator using three arguments, all in one line, to simplify the while loop concept.
for(int count=0;count<me.size();count++){
System.out.println(me.get(count1));
}
We still had problems with boolean logic and +/-1 mistakes processing data. So, a simplified version of a for loop was developed, called advanced for loop.
for(int i:me){
System.out.println(i);
}
Hiding the complexities and making things simple is an advanced concept, it is a form of oxymoron in geeks world. Thus, having an input, hiding the complexities of processing the input, and having the desired output is an aim for quicker program development with less logical errors or mistakes. This hiding desire is not a digital age child, it is a mathematical theory and the base for lambda calculus.
Lambda calculus (also written as λ-calculus) is a formal system in mathematical logic for expressing computation based on function abstraction and application using variable binding and substitution. It is a universal model of computation that can be used to simulate any Turing machine and was first introduced by mathematician Alonzo Church in the 1930s as part of his research of the foundations of mathematics.
Lambda calculus consists of constructing lambda terms and performing reduction operations on them. In the simplest form of lambda calculus, terms are built using only the following rules:
The Lambda calculus is an abstract mathematical theory of computation, involving functions. The lambda calculus can be thought of as the theoretical foundation of functional programming. It is a Turing complete language; that is to say, any machine which can compute the lambda calculus can compute everything a Turing machine can (and vice versa).
The notation is based on function abstraction and application based on variable binding and substitution. If you have done same basic programming already, you might be familiar with lambda functions or anonymous functions already. They are featured in Haskell, Mathematica, Python and recent versions of C++ too. In this wiki, we will mostly stick to Haskell.
This concept of process hiding starts by understanding anonymous classes. As you can see below, class can override methods without changing the original class permanently.
class Perform{
public int doubleIt(int i){
return 2*i;
}
}
public class HiddenProcess{
public static void main(String args[]){
Perform myNumber=new Perform()
public int doubleIt(int i){
return 2*i;
}
}
public class HiddenProcess{
public static void main(String args[]){
Perform myNumber=new Perform()
{
private String addedAttribute="My Added Message";
public int doubleIt(int i){
return i+i;
}
};
System.out.println(myNumber.doubleIt(3));
}
}
private String addedAttribute="My Added Message";
public int doubleIt(int i){
return i+i;
}
};
System.out.println(myNumber.doubleIt(3));
}
}
The next concept we need to understand is interfaces. Interfaces can not be instantiated without a class implementing the interface defined method headers.
interface MyWish{
void complete(int a);
}
class MyWishRealize implements MyWish{
public void complete( int a){
System.out.println(3);
}
}
public class HiddenProcess{
public static void main(String args[]){
MyWishRealize wishOne=new MyWishRealize();
}
}
void complete(int a);
}
class MyWishRealize implements MyWish{
public void complete( int a){
System.out.println(3);
}
}
public class HiddenProcess{
public static void main(String args[]){
MyWishRealize wishOne=new MyWishRealize();
}
}
So, we can override and implement methods in anonymous classes therefore we can override methods in classes implementing interfaces.
interface MyWish{
void complete(int a);
}
class MyWishRealize implements MyWish{
public void complete( int a){
System.out.println(3);
}
}
public class HiddenProcess{
public static void main(String args[]){
MyWishRealize wishOne=new MyWishRealize(){
public void complete(int a ){
System.out.println(3000);
}
};
MyWishRealize wishTwo=new MyWishRealize(){
public void complete(int a ){
System.out.println(6000);
}
};
}
}
So, we can also implement an interface using an anonymous class, so we do not need to create an extra class just to implement the interface.
void complete(int a);
}
class MyWishRealize implements MyWish{
public void complete( int a){
System.out.println(3);
}
}
public class HiddenProcess{
public static void main(String args[]){
MyWishRealize wishOne=new MyWishRealize(){
public void complete(int a ){
System.out.println(3000);
}
};
MyWishRealize wishTwo=new MyWishRealize(){
public void complete(int a ){
System.out.println(6000);
}
};
}
}
So, we can also implement an interface using an anonymous class, so we do not need to create an extra class just to implement the interface.
interface MyWish{
void complete(int a);
}
public class HiddenProcess{
public static void main(String args[]){
MyWish gift= new MyWish(){
public void complete( int a){
System.out.println("Hello "+a);
}
};
}
}
But the simplified structure can be even more simplified by lambda expression like this;
void complete(int a);
}
public class HiddenProcess{
public static void main(String args[]){
MyWish gift= new MyWish(){
public void complete( int a){
System.out.println("Hello "+a);
}
};
}
}
But the simplified structure can be even more simplified by lambda expression like this;
interface MyWish{
void complete(int a);
}
public class HiddenProcess{
public static void main(String args[]){
MyWish gift1=(i)->System.out.println("Hello "+i);
}
}
Lambda Expression
void complete(int a);
}
public class HiddenProcess{
public static void main(String args[]){
MyWish gift1=(i)->System.out.println("Hello "+i);
}
}
Lambda Expression
Prior to Java 1.8, if you looked at the API for ArrayList, you did not have a method to process the array with forEach mehod.
void
|
ensureCapacity(int minCapacity)
Increases the capacity of this ArrayList instance,
if necessary, to ensure that it can hold at least the number of elements
specified by the minimum capacity argument.
|
get(int index)
Returns the element at the
specified position in this list.
|
|
int
|
Returns the index of the first
occurrence of the specified element in this list, or -1 if this list does not
contain the element.
|
Java 1.8 added that method to the available method's list to simplify processing the array.
void
|
ensureCapacity(int minCapacity)
Increases the capacity of this ArrayList instance,
if necessary, to ensure that it can hold at least the number of elements
specified by the minimum capacity argument.
|
void
|
Performs the given action for each
element of the Iterable until all elements have been processed or the action
throws an exception.
|
get(int index)
Returns the element at the
specified position in this list.
|
|
int
|
Returns the index of the first
occurrence of the specified element in this list, or -1 if this list does not
contain the element.
|
forEach method is based on the iterable interface and takes a consumer interface as its parameter.·
forEach
public void forEach(Consumer<? super E> action)
Description copied from
interface:
Iterable
Performs the given action for each element of the
Iterable
until all elements
have been processed or the action throws an exception. Unless otherwise
specified by the implementing class, actions are performed in the order of
iteration (if an iteration order is specified). Exceptions thrown by the action
are relayed to the caller.
Specified
by:
Parameters:
action
- The action to be performed for each element
Iterable inerface's forEach method gives us the reference to the enhanced for loop and to the idea of simplifying its operation.·
forEach
default void forEach(Consumer<? super T> action)
Performs the given action for each element of the
Iterable
until all elements
have been processed or the action throws an exception. Unless otherwise
specified by the implementing class, actions are performed in the order of
iteration (if an iteration order is specified). Exceptions thrown by the action
are relayed to the caller.
Implementation
Requirements:
The default implementation behaves as if:
for (T t : this)
action.accept(t);
Parameters:
action
- The action to be performed for each element
Throws:
NullPointerException
- if the specified action is null
Since:1.8
The Consumer interface has the method accept that takes any dataType object and performs the given operation on that dataType. Since Consumer is an interface, a class needs to implement its method accept.
java.util.function
Interface Consumer<T>
Type Parameters:
T
- the type of the input to the operation
All Known Subinterfaces:Stream.Builder<T>
Functional Interface:This is a functional interface and
can therefore be used as the assignment target for a lambda expression or
method reference.
Modifier
and Type
|
Method
and Description
|
void
|
Performs this operation on the
given argument.
|
The following code demonstrates the implementation of Consumer interface. ( Note: For simple introduction to Java's Generics - read my article - http://intro2cs-java.blogspot.com/2017/03/generic-getting-started.html )
class implementConsumer<T> implements java.util.function.Consumer<T> {
public void accept(T i){
System.out.println(i);
}
}
public class HiddenProcess{
public static void main(String args[]){
implementConsumer<String> value=new implementConsumer<>();
value.accept("Hello");
}
}
So, how can we do the same without using the extra class implementConsumer? WE should use anonymous inner class to accomplish that for this interface. But we would need to create an implementation for each dataType and that would be very annoying.
public void accept(T i){
System.out.println(i);
}
}
public class HiddenProcess{
public static void main(String args[]){
implementConsumer<String> value=new implementConsumer<>();
value.accept("Hello");
}
}
So, how can we do the same without using the extra class implementConsumer? WE should use anonymous inner class to accomplish that for this interface. But we would need to create an implementation for each dataType and that would be very annoying.
public class HiddenProcess{
public static void main(String args[]){
java.util.function.Consumer<String> value=new java.util.function.Consumer<String>(){
public void accept(String i){
System.out.println(i);
}
};
value.accept("Hello");
}
}
We would need to create an implementation for ArrayList for each dataType it is instantiated and that would annoy us as well.
public static void main(String args[]){
java.util.function.Consumer<String> value=new java.util.function.Consumer<String>(){
public void accept(String i){
System.out.println(i);
}
};
value.accept("Hello");
}
}
We would need to create an implementation for ArrayList for each dataType it is instantiated and that would annoy us as well.
public class HiddenProcess{
public static void main(String args[]){
java.util.ArrayList<Integer> me=new java.util.ArrayList<>();
me.add(1);
me.add(2);
java.util.function.Consumer<java.util.ArrayList<Integer>> value=new java.util.function.Consumer<java.util.ArrayList<Integer>>(){
public void accept(java.util.ArrayList<Integer> i){
for(int val:i)
System.out.println(val);
}
};
value.accept(me);
}
}
public static void main(String args[]){
java.util.ArrayList<Integer> me=new java.util.ArrayList<>();
me.add(1);
me.add(2);
java.util.function.Consumer<java.util.ArrayList<Integer>> value=new java.util.function.Consumer<java.util.ArrayList<Integer>>(){
public void accept(java.util.ArrayList<Integer> i){
for(int val:i)
System.out.println(val);
}
};
value.accept(me);
}
}
At the end, we can simplify all this with our lambda expression that works for every dataType and the syntax is simplified to a single line of code. Isn't that cool!!!
public class HiddenProcess{
public static void main(String args[]){
java.util.ArrayList<Integer> me=new java.util.ArrayList<>();
me.add(1);
me.add(2);
me.forEach(i->System.out.println(i));
}
}
public static void main(String args[]){
java.util.ArrayList<Integer> me=new java.util.ArrayList<>();
me.add(1);
me.add(2);
me.forEach(i->System.out.println(i));
}
}
Conclusion
Being lazy means innovation toward an advanced society, so be proud of it and keep innovating!
Hello professor, I am working of a program which include a class called Badges. All my classes are in one package, while my source files are in other package, called "resources". I really find it hard to read from the files without using the absolute path. The Badges class has method as bellow
ReplyDeletepublic void loadDataFromFile(String fileName) {
try{
Scanner sc = new Scanner(new File(fileName));
while(sc.hasNext()){
//add the data to file.
}
}catch(FileNotFoundException e){
System.out.println("Connot Find file for :" + fileName);
}
}
There are four other classes, such Employee, Student... that extends to this Badges class. When I create object that I pass the file name to loadDataFromFile().
none of these code for me. For instance,
Employee emp = new Employee();
emp.loadDataFromFile("TableViewExample/resource/Employee.txt");
emp.loadDataFromFile("/resource/Employee.txt");
emp.loadDataFromFile("Employee.txt");
** TableViewExample is the name of class where main method is.
This comment has been removed by the author.
DeleteIt is a function of the project's properties settings. You need o make sure to add the resource folder properly so the resource will be copied into the bin folder by the IDE.
DeleteYou can print out and see if you can read the file path like this.
System.out.println(TestResources.class.getResource("input.txt").getPath());
or You can create a file object from the file in the resource folder like this.
ClassLoader classLoader = getClass().getClassLoader();
java.io.File file = new java.io.File(classLoader.getResource(fn).getFile());