How work java lambda? I can not understand [closed] - java

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I have started to learn Java lambda and I do not understand it. I found an example.
String[] atp = {"Rafael Nadal", "Novak Djokovic", "Stanislas Wawrinka", "David Ferrer", "Roger Federer", "Andy Murray", "Tomas Berdych", "Juan Martin Del Potro"};
players.forEach((player) -> System.out.print(player + "; "));
And it works fine, but my code does not work.
public class Counter {
String[] atp = {"Rafael Nadal", "Novak Djokovic", "Stanislas Wawrinka", "David Ferrer", "Roger Federer", "Andy Murray", "Tomas Berdych", "Juan Martin Del Potro"};
List<String> players = Arrays.asList(atp);
private int a = 7;
private int b = 7;
public int summ(int a, int b) {
return a + b;
}
public void print(){
players.forEach((player) -> System.out.print(player + "; "));
summ((a,b)-> System.out.print(a + b));
}
}
I want understand how lambda works.
This is not working -
summ((a,b)-> System.out.print(a + b));

You can use lambdas with functional interfaces.
What is a functional interface?
It is basically an interface that has one and only abstract method (but can have other default methods for example)
The most frequent example is the Predicate interface.
public interface Predicate <T> {
boolean test(T t);
// Other methods
}
This one take any Object (generics) and returns a boolean primitive.
So let's say we want to test a condition using this interface to find pair numbers in a loop, we code the following.
Predicate<Integer> function = a -> a%2 == 0;
for (int i = 0 ; i < 10 ; i++){
if (function.test(i)){ // The primitive is AutoBoxed into an Integer Object here
System.out.println(i);
}
}

Related

Java Comparator for Objects with multiple fields [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 8 years ago.
Improve this question
I have an Object Collection with 5 fields:
id;
entityType;
entityId;
brandId;
productId;
To sort an ArrayList of Collection I have written the following Comparaor.
Comparator<Collection> collectionComparator = new Comparator<Collection>() {
#Override
public int compare(Collection collection1, Collection collection2) {
if(collection1.getId().equals(collection2.getId())) {
if(collection1.getEntityType().equals(collection2.getEntityType())) {
if(collection1.getEntityId().equals(collection2.getEntityId())) {
if(collection1.getBrandId().equals(collection2.getBrandId())) {
return collection1.getProductId().compareTo(collection2.getProductId());
} else {
return collection1.getBrandId().compareTo(collection2.getBrandId());
}
} else {
return collection1.getEntityId().compareTo(collection2.getEntityId());
}
} else {
return collection1.getEntityType().compareTo(collection2.getEntityType());
}
}
return collection1.getId().compareTo(collection2.getId());
}
};
Is this the right way to implement Comparator on the object which has multiple fields to compare?
Your method might be correct, but it is inefficient (unnecessarily calls equals) and difficult to read. It could be rewritten something like this:
public int compare(Collection c1, Collection c2)
{
int n;
n = c1.id.compareTo(c2.id);
if (n != 0) return n;
n = c1.entityType.compareTo(c2.entityType);
if (n != 0) return n;
n = c1.brandId.compareTo(c2.brandId);
if (n != 0) return n;
return c1.productId.compareTo(c2.productId);
}
Even better is to use a library method which abstracts all this logic away so you don't have to think about it. E.g. using apache.commons.lang CompareToBuilder
public int compare(Collection c1, Collection c2)
{
return new CompareToBuilder()
.append(c1.id, c2.id)
.append(c1.entityType, c2.entityType)
.append(c1.brandId, c2.brandId)
.append(c1.productId, c2.productId)
.toComparison();
}
First, Collection is a class from java.util package, so it's probably not the best idea to name your own class Collection too, although it is certainly possible.
Second, JDK8 have some neat ways to create comparators, check here: jdk8 comparators
Esspecially section 6 and 9.
EDIT: Without JKD8:
When comparing by 5 different attributes, I wouldn't hardcode the comparasion like that, you can always create your own comparator chainer (something like point 9 from previous link) and chain 5 separate comparators together.

Java Constructor by String parameters [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
Hello my problem is that
DepositoBancario(String s){
String[]v = s.split("[ :]");
Integer n= v.length;
if(n!=2) throw new IllegalArgumentException("Error"+s);
banco= new String(v[0]);
interes= new List(v[1]);
}
This constructor is for be able to build and object by a file and I want transform the element v[1] in List(interes).
Thanks for your help guys.
You don't need to create a String with new String("") you can just set banco = v[0]
List is an Interface and can not be instantiated via a constructor. What you need is a ArrayList for example. But this class doesn't have a Constructor for a Strign neither. What is in that String v[1]?
I believe you have one or more elements (interes) and you wants to convert them into list of elements. You can use something like this.
import java.util.ArrayList;
import java.util.List;
public class DepositoBancario {
String banco;
List<String> interes;
public DepositoBancario(String s){
String[]v = s.split("[ :]");
Integer n= v.length;
if(n!=2) throw new IllegalArgumentException("Error"+s);
banco= v[0];
if(v[1] != null){
interes = new ArrayList<String>();
}
for(int i=1;i<n;i++)
interes.add(v[i]);
}
}
Note : Please consider the suggestion of markusw they are valuable.
First, You code won't compile unless You are using some custom implementation of List.
For what I can understand from You question it should be something like
import java.util.List;
import java.util.ArrayList;
public class DepositoBancario {
private String banco;
private List<String> interes;
DepositoBancario(String s) {
String[]v = s.split("[ :]"); // split input string by colon or space
if(v.length != 2) { // check if there are just two fields
throw new IllegalArgumentException("Invalid syntax, two fields expected: " + s);
}
banco = v[0];
interes = new ArrayList<String>();
interes.add(v[1]);
}
}

Java - Subclasses of Array [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
Disclaimer: I'm a beginner so feel free to point stuff out...
I have a superclass composed by an array of int with 8 values, now i want to create a subclass to randomly pick 4 items in the array and store them in another Object.
Superclass:
public class SideDeck{
public static final int MaxValue = 6;
public static final int MinValue = -6;
public static final int MaxArrayValue = 8;
public final int[] sidecards = new int[MaxArrayValue];
public SideDeck(){
for(int i=0;i<MaxArrayValue;i++){
sidecards[i]=0;
}
}
public SideDeck(int sidecards1,int sidecards2,int sidecards3,int sidecards4,int sidecards5,int sidecards6, int sidecards7, int sidecards8){
sidecards[0]=sidecards1;
sidecards[1]=sidecards2;
sidecards[2]=sidecards3;
sidecards[3]=sidecards4;
sidecards[4]=sidecards5;
sidecards[5]=sidecards6;
sidecards[6]=sidecards7;
sidecards[7]=sidecards8;
}
public boolean ValidSidedeck(){
int check=0;
if (sidecards[0]!=0) {
for(int i=0;i<MaxArrayValue;i++){
if ((sidecards[i] > MinValue) && (sidecards[i] < MaxValue)){
check=1;
} else{
check=0;
break;
}
}
} else {
check=0;
}
if (check==1){
return true;
} else {
return false;
}
}
public String toString(){
String s="";
for(int i=0;i<MaxArrayValue;i++){
s+=(" || Card n° " + (i+1) + " = " + sidecards[i]);
}
return s;
}
public void ResetSidedeck(){
if (sidecards[0]!=0) {//why check it? what if we just run it?
for(int i=0;i<MaxArrayValue;i++){
sidecards[i]=0;
}
}
}
}
Subclass: (Not really sure what to do here… ) Basically it should pick 4 random positions from the .super and store them here, just that i have no clue how to create the object this way. And passing the super as constructor doesn't seem right since it's gonna pass the Object and not the array(and i don't need the full array anyway). Main thing is that i wanna keep the superclss like that, maybe just adding a method there so extract the 4 values..and passing them as arguments…?
import java.lang.Math;
public final class PlayableSideDeck extends SideDeck{
private final static int MaxCArrayValue=4;
public final int[] sidecardsPlay = new int[MaxCArrayValue];
public PlayableSideDeck(SideDeck sidecards){
/* sidecardsPlay[0]=0;
sidecardsPlay[1]=0;
sidecardsPlay[2]=0;
sidecardsPlay[3]=0;*/
// SetDeck();//<-Can i call a private method in the constructor
}
public void SetDeck(){
/* for(int j=0;j<4;j++){
int position=(super.sidecards[PickDeck()]);//<--this is the main problem.. since it's gonna call the object i guess.
sidecards[j]=position;
System.out.println(/*"i= " + i + *//* " ||| j= " + j + "|||| new sidecard= " + sidecards[j] + " |||| old sidecard=" + super.sidecards[PickDeck()]);
}*/
for(int j=0;j<MaxCArrayValue;j++){
sidecardsPlay[j]=(super.sidecards[PickDeck()]);
System.out.println(/*"i= " + i + */ " ||| j= " + j + "|||| new sidecard= " + sidecardsPlay[j] + " |||| old sidecard=" + super.sidecards[PickDeck()] + "|| random= " + PickDeck());
}
}
public int PickDeck(){
return ((int)(Math.random() * 8));
}
public String toString(){
String s="";
for(int i=0;i<MaxCArrayValue;i++){
s+=(" || Card n° " + (i+1) + " = " + sidecards[i]);
}
return s;
}
}
Thanks.
I'm not sure how you plan to use PlayableSideDeck, so I'll answer answer this two ways and you can pick the most fitting answer.
First, as the book Effective Java (by Josh Bloch) points out, you should favor composition over inheritance. By using composition you have your answer to the question of whether you should pass an instance of SideDeck to the constructor of PlayableSideDeck - you will have to since you won't be inheriting any access to SideDeck. Anyway, I'd recommend reading Item 16 in the book (google for it, there are copies available online) and see if composition doesn't better fit your needs.
Second, if you decide to go with inheritance, you don't need to pass an instance of SideDeck to the constructor of PlayableSideDeck. This is because when you create an instance of PlayableSideDeck you are automatically creating an instance of SideDeck along with it. All constructors in Java will implicitly call super() (which is the superclasses's default constructor) if you don't explicitly provide another such call yourself. For example, you could prevent the implicit call to super() like so:
public class BaseClass {
protected String strValue;
public BaseClass () {
strValue = "";
}
public BaseClass (String str) {
strValue = str;
}
}
public class SubClass extends BaseClass {
private int intValue;
SubClass (String str, int i) {
super (str);
intValue = i;
// note that since strValue is protected, SubClass can access directly
System.out.println ("strValue = " + strValue);
}
}
In this example, if you call new SubClass ("foobar") then you will see strValue = foobar printed on the console.
If BaseClass didn't have a zero argument constructor you would, in fact, be required to call super(str) since the compiler wouldn't be able to figure out how to do it for you.
Also, since you asked, here are a few other tips and pointers:
In the constructor SideDeck() you explicitly initialize all values of the array to 0, which isn't necessary. They will already all be 0. If you needed to init them to 0 then you'd be better off avoiding code duplication by calling ResetSideDeck. Speaking of which, you can shorten that code to Arrays.fill (sidecards, 0); (be sure to import java.util.Arrays).
Yes, you can call private methods from a constructor - but only private methods that are part of the local class, not any of the superclasses (you can, however, call protected methods of superclasses).
You're right about not checking sidecards[0] == 0 since there's little efficiency to be gained unless MaxArrayValue becomes very large.
Your class member variables such as sidecards should be private (or maybe protected if you need to access them from a subclass). Use getter/setter methods to access them.
Lastly, Java naming conventions would tell you to use a lower-case letter for method names (e.g. setDeck, pickDeck, resetDeck, etc.), and for even more idiomatic Java you could rename ValidaDeck to isValidDeck (since it returns a boolean). For the constants such as MaxArrayValue the convention is to use all upper-case with underscores between words, e.g. MAX_ARRAY_VALUE.
Hope this all helps!

How to write switch statements based on 3 variables? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I have a lecagy validator class that I'd like to work with. It gives all permutations to validate 1-3 different fields.
class Validator {
Checker Validator.A, Validator.B, Validator.C;
Checker[] ABC = {Validator.A, Validator.B, Validator.C};
Checker[] AB = {Validator.A, Validator.B};
Checker[] BC = {Validator.B, Validator.C};
Checker[] AC = {Validator.A, Validator.C};
}
I don't have any influence on this class. But have to use one of these Checkers.
I want to chose the needed validator based on the fields that are not empty.
Therefore, I wrote the following switch statemend. But to me it seems to be very ugly. How could I improve this?
String a, b, c;
boolean isA = !a.isEmpty();
boolean isB = !b.isEmpty();
boolean isC = !c.isEmpty();
Checker[] checker;
if (isA && isB && isC) {
checker = Validator.ABC;
} else if (isA && isB) {
checker = Validator.AB;
} else if (isA && isC) {
checker = Validator.AC;
} else if (isB && isC) {
checker = Validator.BC;
} else if (isA) {
checker = Validator.A;
} else if (isB) {
checker = Validator.B;
} else if (isC) {
checker = Validator.C;
}
How about this?
List<Checker> checkers = new ArrayList<Checker>();
if (!a.isEmpty()) checkers.add(Validator.A);
if (!b.isEmpty()) checkers.add(Validator.B);
if (!c.isEmpty()) checkers.add(Validator.C);
Checker[] checker = checkers.toArray(new Checker[checkers.size()]);
Alternatively you could do it this way
List<Checker> list = new ArrayList<>();
if (!a.isEmpty()) {
list.add(Validator.A);
}
if (!b.isEmpty()) {
list.add(Validator.B);
}
if (!c.isEmpty()) {
list.add(Validator.C);
}
Checker[] checker = list.toArray(new Checker[list.size()]);
You could simplify it using reflection, approximately like this (haven't actually compiled, but should be close enough):
String name = (a? "A":"") + (b? "B":"") + (c? "C":"");
checker = Validator.class.getField(name).get();
if you really want to do it, you have to convert whole your input to "case'able" data. e.g int
2 ^((int) a) * 3^((int) b) * 5^((int) c)
or to string (since java 7)
but, don't do it. it's ugly. create a collection and fill it with necessary checkers. as showed by Chris King
You can do the whole thing with enums. It adds a powerful extendibility component.
enum Checker {
A, B, C;
public boolean check () {
// You do this.
return true;
}
}
enum Validator{
ABC(Checker.A, Checker.B, Checker.C),
AB(Checker.A, Checker.B),
BC(Checker.B, Checker.C),
AC(Checker.A, Checker.C),
A(Checker.A),
B(Checker.B),
C(Checker.C),
;
final Checker[] checkers;
Validator(Checker ... checkers) {
this.checkers = checkers;
}
boolean validate(Collection a, Collection b, Collection c) {
// Grow the name of the validator from the data.
String name = (!a.isEmpty()?"A":"") +
(!b.isEmpty()?"B":"") +
(!c.isEmpty()?"C":"");
// The final result.
boolean checksOut = true;
// TODO: Handle the all-empty scenario.
if ( name.length() > 0 ) {
// Pull the checks array out of the correct validator.
Checker [] checks = Validator.valueOf(name).checkers;
for ( Checker check : checks ) {
// Do all of the checks defined.
checksOut &= check.check();
}
}
return checksOut;
}
}

How can I instantiate the class DefaultHashMap [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I'm trying to access the DefaultHashMap class but getting error in the main method. Could anyone please tell me what is the problem?
import java.util.Random;
import java.util.*;
public class PythonToJava {
public static void main(String[] args) {
Random rm = new Random();
int i = rm.nextInt(1000);
HashMap<Integer,Integer> stats = new HashMap<Integer,Integer>();
DefaultHashMap<K,V> default = new DefaultHashMap<K,V>();
System.out.println("Random Number Generated is: " + i);
for (int j = 0; j<i; j++){
int value = rm.nextInt(500);
System.out.println("The value of VALUE is " + value);
}
}
}
class DefaultHashMap<K,V> extends HashMap<K,V> {
protected V defaultValue;
public DefaultHashMap(V defaultValue) {
this.defaultValue = defaultValue;
}
#Override
public V get(Object k) {
V v = super.get(k);
return ((v == null) && !this.containsKey(k)) ? this.defaultValue : v;
}
}
Please help me in rectifying the errors I'm encountering at the line with the code:
DefaultHashMap<K,V> default = new DefaultHashMap<K,V>();
The K and V are type parameters, and here, you need to use concrete types to substitute them, the same as when you are using HashMap.
K,V has to be objects
You cannot use variable default. Its a java reserve word.
You should read about java generics
http://docs.oracle.com/javase/tutorial/java/generics/why.html

Categories

Resources