Initialize variable with complex expression [closed] - java

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 5 years ago.
Improve this question
Is there a way in Java 8 to simultaneously declare and initialize a final variable with the result of a complex expression?
In other words, is something like the following possible?
final int x = [capturedVariable] {
switch (capturedVariable) {
case 1: return 42;
case 2: return 84;
default: return 66;
}
};
While the syntax is obviously "creative", I hope the intent is clear.
Edit 1: While this particular example can be written using ternary operators, it's merely an example of a complex expression and I'm looking for a general solution.
Edit 2: Maybe a less controversial way to look at this question is the following: What is the syntax to simultaneously declare and invoke a lambda/closure in Java 8?

I don't see how Java 8 is relevant here, you can assign a final variable in multiple places so long as you always assign it and only ever assign it once, for example this is legal Java code (assuming blah is a valid boolean):
final int test;
if (blah) {
test = 1;
} else {
test = 2;
}
The expressions can be as complicated as you like so long as the compiler is able to deterministically prove that you always initialize the variable once and only once. (For example loops would make it fail).

Seems overkill, but you could use a Supplier:
final int x = new Supplier<Integer>() {
public Integer get() {
// Complexity here
return result;
}
}.get();
I'm sure it's my Java-fu being weak (I guess not), but the only way I could get the lambda version working is to have a reusable call utility function somewhere:
class Utils {
public static <T> T call(Supplier<T> x) {
return x.get();
}
}
...and then:
final int x = Utils.call(() -> {
// Complexity here
return result;
});
Matthias points out in a comment (refined by Aominè) that you can avoid that intermediary function, but it isn't much prettier than the first solution above:
final int x = ((Supplier<Integer>) () -> {
// Complexity here
return result;
}).get();
...but at least it doesn't require generating a class.

You ca create your own Interface an create init method which take an init and return another int for example :
Init i = (x) -> {
switch (x) {
case 1:
return 42;
case 2:
return 84;
default:
return 66;
}
};
final int x = i.init(1);
...
interface Init {
int init(int x);
}

Related

how to multiply an int [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 1 year ago.
Improve this question
How should I make a damage multiplier when someone has a block break on them?
I have used the following if-statement to make it happen:
if(card.getEffects() == Cards.Effects.Block_Break) {
packag.CustomDecks.cSet= Attack(int damage)*1.5;
}
I misspeled Attacks
but it doesn't recognize the keyword "damage".
This is my Cards class:
public class Cards {
enum Effects {
Return, Secret, Recover, Block_Break, Lifesteal, Burn, Paralyze, Reflect, Draw;
private static final Effects[] effects = Effects.values();
public static Effects getEffects(int i) {
return Effects.effects[i];
}
}
private final Effects effects;
Cards(Effects effects) {
this.effects = effects;
}
public Effects getEffects() {
return this.effects;
}
}
Another class Attacks:
class Attacks extends Cards {
public int damage;
private final Effects effects;
Attacks(int damage, final Effects effects) {
super(effects);
this.damage = damage;
this.effects = effects;
}
}
cSet = new ArrayList<CustomDecks>();
Shuriken = new Attacks("Shuriken", 3, 2, packag.Effects.Return, packag.Cards.Classs.Wizard, packag.Cards.Rarity.Common, new ImageIcon("Shuriken.png"));
cSet.add(Shuriken);
this is cSet
Did you know: You can add properties to an enum.
Define an enum with properties using a constructor
For example to add a damage-multiplier or damage-factor to each write:
public enum Effects {
Return(1), // default factor is 1, which means no change
Secret(1),
Recover(1),
Block_Break(1.5), // multiplier added here
Lifesteal(1),
Burn(1),
Paralyze(1),
Reflect(1),
Draw(1);
private final double damageFactor;
// constructor to associate a damage-multiplier to each Effect
Effects(double damageFactor) {
this.damageFactor = damageFactor;
}
// you need a getter to use the factor outside
public double getDamageFactor() {
return this.damageFactor;
}
private static final Effects[] effects = Effects.values();
public static Effects getEffects(int i) {
return Effects.effects[i];
}
}
Then you could simply use it to apply Effect-specific damage like this:
// typo: assume the class name is "Attack" not "Attacks"
Attack(int damage, final Effects effects) {
super(effects);
// final damage is a combination of effect-factor multiplied specified damage
this.damage = (int) Math.round(damage * effects.getDamageFactor()); // round to int, e.g. 3 * 1.5 = 4.5; rounded to 5
this.effects = effects;
}
The if-statement leads to compile-error(s)
if(card.getEffects() == Cards.Effects.Block_Break) {
packag.CustomDecks.cSet= Attack(int damage)*1.5;
}
What you gave as if-statement will lead to a compile-error, because
Class not found: there is no class (hence no constructor) called Attack. The class given is named in plural: Attacks (ending with s!).
Syntax-Error: to call a constructor with new (forgot that keyword!) simply pass a variable like myDamage (no int as type-declaration needed!)
Constructor not found: the constructor of Attack requires currently 2 arguments: int damage and Effects effects. But you only passed the first.
Type-Error: the new Attack object can not be multiplied with a double like 1.5
Not sure if packag.CustomDecks.cSet is correct.
Fix the syntax errors
To fix it, you could correct like that:
int myDamage = 10;
if (card.getEffects() == Cards.Effects.Block_Break) {
// prefix with new, int multiplication, pass 2nd param
packag.CustomDecks.cSet = new Attack(myDamage * 2, Cards.Effects.Block_Break); // will init damage with 20
}
Or - with the new constructor from above - you can make use of the effect passed in:
packag.CustomDecks.cSet = new Attack(damage, card.getEffects()); // *1.5: is done inside using factor bound to current effect
Note: No if is needed then. The factor is constantly pulled from current effect.
Naming Convention commonly used in Java
Class Names:
Usually classes in Java are named in singular, unless they are collections containing many items.
Enums:
Also the enum class would be named Effect (singular) by convention. Because an enum defines a set of constants. But an enum variable like the field in your class Attacks represents a single state and value, for example the state Block_Break.
The enum-values are usually written in uppercase with underscores separating words like BLOCK_BREAK. It's the same naming-convention like for constants, because enum-values are constants.

Where is the solution stub in this program and how would I call a method in it? [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 2 years ago.
Improve this question
This is a specific question, don't downvote it just because it doesn't help you.
public class Answer {
public static String answer(int n) {
String nums="";
int limit = 10005;
int x=2;
while(limit>0){
if(isPrime(x)){
limit-=String.valueOf(x).length();
nums = nums + String.valueOf(x);
}
x+=1;
}
String out="";
if(n==0){
out="23571";
}else{
for(int i=1;i<6;i++){
out += String.valueOf(nums.charAt(n+i));
}
//Problem Solved: instead of this loop, it should be out = nums.substring(n,n+5)
}
return out;
}
public static boolean isPrime(int number) {
for(int check = 2; check < number; ++check) {
if(number % check == 0) {
return false;
}
}
return true;
}
}
Nothing is wrong with this code as far as I know, I'm just using it as an example for you to use.
"It must implement the answer() method in the solution stub." was in the directions for me, but I don't know much about the vocabulary of programming, I only understand logic behind programming, so this is the only thing I don't know how to solve. So what I am asking is where do I put the "answer()" at in this program?
It was looking for substring, which I didn't include because I haven't used java in about a year and simply forgot about it.
Here as I can figure out you have problems in understanding the meaning of "stub". It is simply the test method as provided by the answer here. And if you want to test the above code you have to implement the main method in your code to do the same. Something like this
public static void main(String [] args){
//Either use Scanner object or provide the hard coded input as per your requirements
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
System.out.println(answer(n));
}
EDIT AS PER OP REQUIREMENT
Okay so as per your requirement it is asking you for the unit test. There are many ways to do it but my preferred is to make stub concrete class
Implementation an stub concrete class in JUNIT
class Answer {
public String answer(int n){
// Code body
return "result"// in your case out variable
}
}
class solution extends Answer {
#Override
public String answer(int n){
//return "your stubbed result";
}
}

Object contains list of object. Find max depth [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I have the following class:
class A {
List<A> as;
}
I need to find max depth. For example, I can have this:
A firstA = new A();
A secondA = new A();
A thirdA = new A();
firstA.addA(secondA);
firstA.addA(thirdA);
secondA.addA(new A());
secondA.addA(new A());
I need to return 3.
I tried to do recursive method,
Using Java 8 streams:
class A {
List<A> as;
public int getDepth() {
return 1 + as.stream().mapToInt(A::getDepth).max().orElse(0);
}
}
If you're not familiar with streams, this can be interpreted as 'add 1 to maximum depth of all children or 0 if there are no children'.
If you can't change A you can still use this by passing A into the method:
public class MyClass {
public static int getDepth(A a) {
return 1 + a.as.stream().mapToInt(MyClass::getDepth).max().orElse(0);
}
}
Recursive depth-computing:
public static int computeDepth(A a)
{
int maxDepth = 0;
for(A innerA : a.getAs())
{
int depth = computeDepth(innerA);
if(depth > maxDepth)
maxDepth = depth;
}
return maxDepth + 1;
}

Receiving parameter for an array of objects from another class in Java? [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 6 years ago.
Improve this question
I am trying to create one array of objects of my class Percurso for another class Custos, but I don't know how to do this. Here is what is asking in the question:
Receives as parameter an array of path-type objects
My code :
Class Custos :
public class Custos {
public String calcularViagem(Percurso [] p) {
return "";
}
}
Class Percurso :
private double kmPercorrida;
private double valorCombustivel;
private double valorPedagio;
public double getKmPercorrida() {
return kmPercorrida;
}
public void setKmPercorrida(double kmPercorrida) {
this.kmPercorrida = kmPercorrida;
}
public double getValorCombustivel() {
return valorCombustivel;
}
public void setValorCombustivel(double valorCombustivel) {
this.valorCombustivel = valorCombustivel;
}
public double getValorPedagio() {
return valorPedagio;
}
public void setValorPedagio(double valorPedagio) {
this.valorPedagio = valorPedagio;
}
public Percurso() {
this(0,0,0);
}
public Percurso(double kmPercorrida, double valorCombustivel,
double valorPedagio) {
this.kmPercorrida = kmPercorrida;
this.valorCombustivel = valorCombustivel;
this.valorPedagio = valorPedagio;
}
How can I do this ? If someone can help, I will thanks.
PS: Before someone say that this post is similar to other questions about array, it's not,I looked for questions similar that could help and I didn't found any that really could help me.
Creating an array of Percurso objects is the same as creating an array of any object. To create the array, you will need to include a line like this:
Percurso[] percursoArray = new Percurso[LENGTH]; //with your own array name and length
However, that just creates an array; it doesn't put anything in it. To put Percurso objects in the array (or, more accurately references to the objects), you need code like this.
percusoArray[0] = new Percurso(5, 2, 1);
percusoArray[1] = new Percurso(1, 1, 1); //etc
Or, if the array is long, you could create the objects in a for loop:
for (int i = 0; i < LENGTH; i++){
percusoArray[i] = new Percurso(1,2,3); //with your own values
}
Of course, a question remains-- where should you put this code? Is the array of Percurso an attribute of Custos? If so, you might create the array as a class variable of Custos and populate it in the constructor for Custos. If it's not an attribute of Custos, but rather just a parameter for one of Custos methods, you'll need this code in whichever part of your code calls calcularViagem(), whether that is another method in Custos, a method in another class, or from inside your main method.

Is there any functional difference between AtomicInteger.updateAndGet() and AtomicInteger.accumulateAndGet()?

Is there any scenario in which AtomicInteger.accumulateAndGet() can't be replaced with AtomicInteger.updateAndGet(), or is it just a convenience for method references?
Here's a simple example where I don't see any functional difference:
AtomicInteger i = new AtomicInteger();
i.accumulateAndGet(5, Math::max);
i.updateAndGet(x -> Math.max(x, 5));
Obviously, the same goes for getAndUpdate() and getAndAccumulate().
When in doubt, you may look into implementation:
public final int accumulateAndGet(int x,
IntBinaryOperator accumulatorFunction) {
int prev, next;
do {
prev = get();
next = accumulatorFunction.applyAsInt(prev, x);
} while (!compareAndSet(prev, next));
return next;
}
public final int updateAndGet(IntUnaryOperator updateFunction) {
int prev, next;
do {
prev = get();
next = updateFunction.applyAsInt(prev);
} while (!compareAndSet(prev, next));
return next;
}
They differ only in single line and obviously accumulateAndGet could be expressed easily via updateAndGet:
public final int accumulateAndGet(int x,
IntBinaryOperator accumulatorFunction) {
return updateAndGet(prev -> accumulatorFunction.applyAsInt(prev, x));
}
So updateAndGet is somewhat more basic operation and accumulateAndGet is a useful shortcut. Such shortcut might be especially helpful if your x is not effectively final:
int nextValue = 5;
if(something) nextValue = 6;
i.accumulateAndGet(nextValue, Math::max);
// i.updateAndGet(prev -> Math.max(prev, nextValue)); -- will not work
There are cases where an instance creation can be avoided by using accumulateAndGet.
This is not really a functional difference but it might be useful to know about.
Consider the following example:
void increment(int incValue, AtomicInteger i) {
// The lambda is closed over incValue. Because of this the created
// IntUnaryOperator will have a field which contains incValue.
// Because of this a new instance must be allocated on every call
// to the increment method.
i.updateAndGet(value -> incValue + value);
// The lambda is not closed over anything. The same
// IntBinaryOperator instance can be used on every call to the
// increment method.
//
// It can be cached in a field, or maybe the optimizer is able
// to reuse it automatically.
IntBinaryOperator accumulatorFunction =
(incValueParam, value) -> incValueParam + value;
i.accumulateAndGet(incValue, accumulatorFunction);
}
Instance creations are generally not expensive but can be important to get rid of in short operations that are used very frequently in performance sensitive locations.
More information about when lambda instances are reused can be found in this answer.

Categories