This was an exam question which I couldn't complete.
How do you get the following java code to print false by only
editing code within the MyClass constructor?
public class MyClass{
public MyClass(){
}
public static void main(String[] args) {
MyClass m = new MyClass();
System.out.println(m.equals(m));
}
}
You are NOT allowed to override the equals method, or change any of
the code within the main method. The code must run without the program
crashing.
According to my research, you can't set a Java object reference to null when you instantiate a class. So I'm officially stumped.
That was tough!!
public MyClass() {
System.setOut(new PrintStream(new FilterOutputStream(System.out) {
#Override
public void write(byte[] b, int off, int len) throws IOException {
if(new String(b).contains("true")) {
byte[] text = "false".getBytes();
super.write(text, 0, text.length);
}
else {
super.write(b, off, len);
}
}
}, true));
}
Or Paul Boddington's simplified version:
PrintStream p = System.out;
System.setOut(new PrintStream(p) {
#Override
public void println(boolean b) {
p.println(false);
}
});
Or AJ Neufeld's even more simple suggestion:
System.setOut(new PrintStream(System.out) {
#Override
public void println(boolean b) {
super.println(false);
}
});
Something along these lines, I would guess:
public MyClass() {
System.out.println(false);
System.exit(0);
}
EDIT: I found a puzzle very similar to yours in Java Puzzlers, except in that question the only restriction was that you could not override equals, which basically makes the solution to overload it instead and simply return false. Incidentally, my solution above was also given as an alternative answer to that puzzle.
Another solution is
public MyClass() {
new PrintStream(new ByteArrayOutputStream()).println(true);
try {
Field f = String.class.getDeclaredField("value");
f.setAccessible(true);
f.set("true", f.get("false"));
} catch (Exception e) {
}
}
The first line is needed because it is necessary for the string literal "true" to be encountered in the PrintStream class before the backing array is modified. See this question.
This is my solution
public class MyClass {
public MyClass() {
System.out.println("false");
// New class
class NewPrintStream extends PrintStream {
public NewPrintStream(OutputStream out) {
super(out);
}
#Override
public void println(boolean b) {
// Do nothing
}
}
NewPrintStream nps = new NewPrintStream(System.out);
System.setOut(nps);
}
public static void main(String[] args) {
MyClass m = new MyClass();
System.out.println(m.equals(m));
}
}
Basically, this is the variation of #fikes solution.
Related
Hi and hope someone can help. I'm doing a short Java course and need to set up 3 classes that basically communicate between each other but I'm failing.
You'll spot from the code below that I'm trying to split the tasks of reading user's input and doing whatever maths is required into different classes but something's wrong
Any ideas? Thanks for your interest.
Here's the simple Main class:-
public class Main {
public static void main(String[] args) {
Calculator calculator = new Calculator();
calculator.start();
}
}
The Calculator class (or part of it):-
public class Calculator {
private Reader reader;
public void Calculator(Reader reader) {
this.reader = reader;
System.out.println("Calculator set up.");
}
public void start() {
while (true) {
System.out.print("command: ");
String command = reader.readString(); // It fails here:
if (command.equals("end")) {
break;
}
if (command.equals("sum")) {
sum();
} else if (command.equals("difference")) {
difference();
} else if (command.equals("product")) {
product();
}
}
And finally the Reader class:-
public class Reader {
private Scanner input;
public void Reader(Scanner input) {
this.input = input;
System.out.println("Reader set up.");
}
public String readString() {
return input.nextLine();
}
public int readInteger() {
return Integer.parseInt(input.nextLine());
}
}
You have an issue with all the constructors you are using. Constructors are special methods with no return type, so in your case, public void Calculator(Reader reader) needs to be public Calculator(Reader reader) (remove void). The same applies to the other constructors.
Once you do that, you would need to make amendments on how you are instantiating your Calculator class:
Calculator calculator = new Calculator();
Should become:
Calculator calculator = new Calculator(new Reader(new Scanner(System.in)));
provide constructor not mothod.
Calculator(Reader reader) {
this.reader = reader;
System.out.println("Calculator set up.");
}
after that you can change your main method with #subhrajyoti suggested.
apart from above suggestion ,
1> your constructors (Reader and Calculator) is returning void. But constructor cannot return any value. So, remove void keyword.
you have to import Scanner class (i.e. java.util.scanner).
Suppose I have an enumeration:
public enum SomeEnumType implements Writable {
A(0), B(1);
private int value;
private SomeEnumType(int value) {
this.value = value;
}
#Override
public void write(final DataOutput dataOutput) throws IOException {
dataOutput.writeInt(this.value);
}
#Override
public void readFields(final DataInput dataInput) throws IOException {
this.value = dataInput.readInt();
}
}
I want to pass an instance of it as a part of some other class instance.
The equals would not work, because it will not consider the inner variable of enumeration, plus all enum instances are fixed at compile time and could not be created elsewhere.
Does it mean I could not send enums over the wire in Hadoop or there's a solution?
My normal and preferred solution for enums in Hadoop is serializing the enums through their ordinal value.
public class EnumWritable implements Writable {
static enum EnumName {
ENUM_1, ENUM_2, ENUM_3
}
private int enumOrdinal;
// never forget your default constructor in Hadoop Writables
public EnumWritable() {
}
public EnumWritable(Enum<?> arbitraryEnum) {
this.enumOrdinal = arbitraryEnum.ordinal();
}
public int getEnumOrdinal() {
return enumOrdinal;
}
#Override
public void readFields(DataInput in) throws IOException {
enumOrdinal = in.readInt();
}
#Override
public void write(DataOutput out) throws IOException {
out.writeInt(enumOrdinal);
}
public static void main(String[] args) {
// use it like this:
EnumWritable enumWritable = new EnumWritable(EnumName.ENUM_1);
// let Hadoop do the write and read stuff
EnumName yourDeserializedEnum = EnumName.values()[enumWritable.getEnumOrdinal()];
}
}
Obviously it has drawbacks: Ordinals can change, so if you exchange ENUM_2 with ENUM_3 and read a previously serialized file, this will return the other wrong enum.
So if you know the enum class beforehand, you can write the name of your enum and use it like this:
enumInstance = EnumName.valueOf(in.readUTF());
This will use slightly more space, but it is more save to changes to your enum names.
The full example would look like this:
public class EnumWritable implements Writable {
static enum EnumName {
ENUM_1, ENUM_2, ENUM_3
}
private EnumName enumInstance;
// never forget your default constructor in Hadoop Writables
public EnumWritable() {
}
public EnumWritable(EnumName e) {
this.enumInstance = e;
}
public EnumName getEnum() {
return enumInstance;
}
#Override
public void write(DataOutput out) throws IOException {
out.writeUTF(enumInstance.name());
}
#Override
public void readFields(DataInput in) throws IOException {
enumInstance = EnumName.valueOf(in.readUTF());
}
public static void main(String[] args) {
// use it like this:
EnumWritable enumWritable = new EnumWritable(EnumName.ENUM_1);
// let Hadoop do the write and read stuff
EnumName yourDeserializedEnum = enumWritable.getEnum();
}
}
WritableUtils has convenience methods that make this easier.
WritableUtils.writeEnum(dataOutput,enumData);
enumData = WritableUtils.readEnum(dataInput,MyEnum.class);
I don't know anything about Hadoop, but based on the documentation of the interface, you could probably do it like that:
public void readFields(DataInput in) throws IOException {
// do nothing
}
public static SomeEnumType read(DataInput in) throws IOException {
int value = in.readInt();
if (value == 0) {
return SomeEnumType.A;
}
else if (value == 1) {
return SomeEnumType.B;
}
else {
throw new IOException("Invalid value " + value);
}
}
I am making a bukkit plugin, and I am using an API called MCStats, to create the graph, you add Plotters like so...
mobs.addPlotter(new Metrics.Plotter("Player") {
#Override
public int getValue() {
return 0;
}
});
But I want to get the values from a HashMap, and idealy something like this...
for(String mob: mobNames) {
mobs.addPlotter(new Metrics.Plotter(mob) {
#Override
public int getValue() {
return Stats.getValue(mob);
}
});
}
But obviously, it can't access the mob variable, if I set it to final, it still wont be able to change in the loop. How can I work around this problem?
You can, in fact, use final in an enhanced for loop:
for(final String mob: mobNames) {
mobs.addPlotter(new Metrics.Plotter(mob) {
#Override
public int getValue() {
return Stats.getValue(mob);
}
});
}
You can use the final keyword for mob and it still be changed in the loop.
Try to run this code below:
public class Test2 {
public static void main(String args[]) {
String[] data = new String[] {"1", "2"};
List<MyClass> test = new ArrayList<MyClass>();
for (final String word: data) {
test.add(new MyClass() {
#Override
public void testMethod() {
System.out.println(word);
}
});
}
for (MyClass myClass: test) {
myClass.testMethod();
}
}
static class MyClass {
public void testMethod() {
}
}
}
The output will be "1" and "2".
Hey everyone I'm studying for a midterm exam and I'm studying the sample midterm from a previous semester, the answers are given but I'm trying to figure out how the answers came about. Question and answers below, I understand how he got "zero" but not the rest:
Write the 10-lines output of the program Bird.java shown below.
interface Silly {
public void narf();
public void poit(Silly s);
}
public class Bird implements Silly {
public static void main(String args[]) {
System.out.println("zero");
Silly s = new SillyBird(1);
Silly s2 = new Loony();
s.poit(s2);
s2.poit(s);
System.out.println("zymurgy");
}
public Bird() {
this(0);
System.out.println("zircon");
}
public Bird(int i) {
System.out.println("zanzibar");
}
public void narf() {
System.out.println("zort");
}
public void poit(Silly s) {
s.narf();
}
}
class SillyBird extends Bird {
public SillyBird() {
System.out.println("duchess");
}
public SillyBird(int i) {
super(i);
}
public void narf() {
System.out.println("drum");
super.narf();
}
}
class Loony extends SillyBird {
public Loony() {
System.out.println("stupendous");
}
public void narf() {
System.out.println("snark");
}
}
His answers are: zero
zanzibar
zanzibar
zircon
duchess
stupendous
snark
drum
zort
zymurgy
interface Silly {
public void narf();
public void poit(Silly s);
}
public class Bird implements Silly {
public static void main(String args[]) {
System.out.println("zero"); // 1. zero
Silly s = new SillyBird(1); // 2. zanzibar
Silly s2 = new Loony(); // 3. zanzibar zircon duchess stupendous
s.poit(s2); // 4. snark
s2.poit(s); // 5. drum zort
System.out.println("zymurgy");// 6. zymurgy
}
public Bird() {
this(0);
System.out.println("zircon");
}
public Bird(int i) {
System.out.println("zanzibar");
}
public void narf() {
System.out.println("zort");
}
public void poit(Silly s) {
s.narf();
}
}
class SillyBird extends Bird {
public SillyBird() {
System.out.println("duchess");
}
public SillyBird(int i) {
super(i);
}
public void narf() {
System.out.println("drum");
super.narf();
}
}
class Loony extends SillyBird {
public Loony() {
System.out.println("stupendous");
}
public void narf() {
System.out.println("snark");
}
}
I hope this helps... I think the most important one to understand is number 3 where you have implicit super() calls.
WHat you probably don't get is that whan a constructor doesn't explicitely invoke super(), then the compiler adds a super() call anyway, to the very beginning of the constructor. So,
public SillyBird() {
System.out.println("duchess");
}
is equivalent to
public SillyBird() {
super();
System.out.println("duchess");
}
Add the super() calls at the very beginning of the constructors which don't have one, then follow the calls, and you'll find the answer. For example, the call to
Silly s2 = new Loony();
calls the Loony constructor, which calls super(). So the SillyBird no-arg constructor is called, which first calls super(). So the Bird no-arg constructor is called, which calls this(0). SO the 1-arg constructor of Bird is called, etc.
If you don't understand how 'he got the rest' - you need to read a basic tutorial on objects, classes, and interfaces. Start with the one provided by Oracle. In a nutshell, the print statements occur in the same order the constructors and override methods are being executed. For example, the second word 'zanzibar' is printed because the
public SillyBird(int i) {
super(i);
}
constructor is invoked Silly s = new SillyBird(1);, which invokes:
public Bird(int i) {
System.out.println("zanzibar");
}
via the super(i) invocation.
Now try to reason through how the second 'zanzibar' print occurs.
I'm testing out a different sort of pattern. I've already got the code working in a switch statement, but I'd like to try something a little more ecclectic... for research purposes.
Say I have 4 classes, Class1, Class2, Class3, and Class4 that all extend BaseClass. I want to put them into an enum, like so:
enum ClassFactories {
Class1(Class1.class),
Class2(Class2.class),
Class3(Class3.class),
Class4(Class4.class);
private final Class factory;
ClassFactories(Class factory) {
this.factory = factory;
}
public BaseClass generate() {
BaseClass b = null;
try {
b = (BaseClass)this.factory.newInstance();
} catch (Exception e) {
// handle any exceptions
}
return f;
}
}
In a factory method that is passed an int, I want to be able to do something like this:
public void fakeMethod(int type) {
BaseClass someClass = ClassFactories.values()[type].generate();
someClass.doStuff();
}
Is there a cleaner/easier way of doing this? I'm not so much concerned with readability (right now), I'm just curious if this is possible.
Yes, this is possible. Something like a 'Template Method' approach. So for example
public enum ClassFactory {
Class1() {
#Override public void generate() {
System.out.println("I'm in Class 1.");
}
},
Class2() {
#Override public void generate() {
System.out.println("I'm in Class 2.");
}
};
//template method
public abstract void generate();
private static final Map<Integer, ClassFactory > lookup
= new HashMap<Integer, ClassFactory >();
static {
for (ClassFactory s : EnumSet.allOf(ClassFactory.class))
lookup.put(s.getIntValue(), s);
}
public static ClassFactory getValue(int intValue) {
return lookup.get(intValue);
}
}
INVOCATION CODE
With the use of static imports, the client code calling this enumeration would look like:
Class1.generate();
Class2.generate();
//or better...
getClass().generate();
Or
public void fakeMethod(int type) {
ClassFactory.getValue(type).generate();
}