Is it bad to use "return" to escape from the main method? - return

So this might be an exceptionally dumb question, but before you burn this post to smolders, please hear me out XD. Below I've written three basic classes, all of which accomplish the same thing, but through various means:
Class A ( break ) -
import java.util.Scanner;
public class ClassA
{
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
while(true)
{
System.out.print("Enter a sentence (/q to quit): ");
String sentence = in.nextLine();
if(sentence.equals("/q"))
break;
else
System.out.println("Thank you!");
}
}
}
Class B ( return ) -
import java.util.Scanner;
public class ClassB
{
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
while(true)
{
System.out.print("Enter a sentence (/q to quit): ");
String sentence = in.nextLine();
if(sentence.equals("/q"))
return;
else
System.out.println("Thank you!");
}
}
}
Class C ( System.exit(0) ) -
import java.util.Scanner;
public class ClassC
{
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
while(true)
{
System.out.print("Enter a sentence (/q to quit): ");
String sentence = in.nextLine();
if(sentence.equals("/q"))
System.exit(0);
else
System.out.println("Thank you!");
}
}
}
While I prefer Classes A and C, is there anything wrong with B? More specifically, is it bad practice to use a return statement to exit from the main method of a program? If so, why?
Thanks in advance!

Using return is exactly the right thing to do, because it makes your main easier to test -- your test framework doesn't need to intercept exit attempts.

Related

Why will this code not print anything to the console?

I am very new to java as I have only started yesterday and I am trying to make a little game where a random number is generated and you have to try to guess that number. The problem I am having right now is nothing will come out of the console. I am not sure what is causing this as it might be the code or the interpreter I am using. Here is the code for you guys to check over. Let me know what I did wrong and if you can find a fix, thanks.
import java.util.Scanner;
public class Random
{
int Ran = (int) Math.floor(Math.random() * 9);
Scanner input = new Scanner(System.in);
int Num = input.nextInt();
public static void main(String[] args){}
{System.out.println("Geuss a number and see if it is correct!");
}
{
if (Num == Ran)
{System.out.println("Correct! The number was " + Ran);
}
else{
System.out.println("You are wrong!");
}
}
public void If(boolean b) {}
}
you have empty{}
public static void main(String[] args){
System.out.println("Geuss a number and see if it is correct!");
}
Also do not write IF as a function. If is native expression in native coding.
There is already if clause so try to give unique names.
import java.util.Scanner;
public class Random
{
int Ran = (int) Math.floor(Math.random() * 9);
Scanner input = new Scanner(System.in);
int Num = input.nextInt();
public static void main(String[] args)
{
System.out.println("Geuss a number and see if it is correct!");
if (Num == Ran)
{System.out.println("Correct! The number was " + Ran);
}
else{
System.out.println("You are wrong!");
}
}
}
try this.
import java.util.Scanner;
public class Random
{
int Ran = (int) Math.floor(Math.random() * 9);
Scanner input = new Scanner(System.in);
int Num = input.nextInt();
public static void main(String[] args){
System.out.println("Geuss a number and see if it is correct!");
if (Num == Ran)
{System.out.println("Correct! The number was " + Ran);
}
else{
System.out.println("You are wrong!");
}
}
public void If(boolean b) {}
}
}

Java 8 Streams: List to Map with mapped values

I'm trying to create a Map from a List using Streams.
The key should be the name of the original item,
The value should be some derived data.
After .map() the stream consists of Integers and at the time of .collect() I can't access "foo" from the previous lambda. How do I get the original item in .toMap()?
Can this be done with Streams or do I need .forEach()?
(The code below is only for demonstration, the real code is of course much more complex and I can't make doSomething() a method of Foo).
import java.util.ArrayList;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
public class StreamTest {
public class Foo {
public String getName() {
return "FOO";
}
public Integer getValue() {
return 42;
}
}
public Integer doSomething(Foo foo) {
return foo.getValue() + 23;
}
public Map<String, Integer> run() {
return new ArrayList<Foo>().stream().map(foo -> doSomething(foo)).collect(Collectors.toMap(foo.getName, Function.identity()));
}
public static void main(String[] args) {
StreamTest streamTest = new StreamTest();
streamTest.run();
}
}
It appears to me it’s not that complicated. Am I missing something?
return Stream.of(new Foo())
.collect(Collectors.toMap(Foo::getName, this::doSomething));
I’m rather much into method references. If you prefer the -> notation, use
return Stream.of(new Foo())
.collect(Collectors.toMap(foo -> foo.getName(), foo -> doSomething(foo)));
Either will break (throw an exception) if there’s more than one Foo with the same name in your stream.

connecting vertices in jung by edges results in another extra vertex being created

I am implementing an interface for taking commands for creating , connecting and coloring vertices in JUNG when I want to connect two already existing vertices JUNG connects to vertices and creates an extra vertex , why?
Here is my code for connect method:
public class Connect extends Command {
private CommandMaster cm;
private BehGraphUndirected behGraph;
private static int edgenumber=0;
#Override
public Object run(BehGraphUndirected behGraph, VisualizationImageServer panel, InterpretMaster interpretMaster, String... args) {
System.out.print("connect Runs\n");
this.cm = new CommandMaster();
this.behGraph = behGraph;
if(cm.exists(args[0]))
{
//got to another command
}else
{
switch (args[0]) {
case "edge":
this.createEdge(args[1] , args[2]);
break;
}
}
interpretMaster.refreshAndRepaint();
return null;
}
public void createEdge(String nodeName1 , String nodeName2)
{
this.behGraph.addEdge(edgenumber++,nodeName1, nodeName2);
System.out.println(this.behGraph.getVertexCount());
System.out.println("edge between: "+nodeName1+" and "+ nodeName2+" added");
}
And it's the create method just in case you want to know the way I implemented the code:
package interpreter.command;
import GraphHandling.BehGraphUndirected;
import edu.uci.ics.jung.visualization.VisualizationImageServer;
import interpreter.Command;
import interpreter.CommandMaster;
import interpreter.InterpretMaster;
/**
*
* #author Administrator
*/
public class Create extends Command{
private CommandMaster cm;
private BehGraphUndirected behGraph;
#Override
public Object run(BehGraphUndirected behGraph, VisualizationImageServer panel, InterpretMaster interpretMaster, String... args) {
System.out.print("create Runs \n");
this.cm = new CommandMaster();
this.behGraph = behGraph;
if(cm.exists(args[0]))
{
//got to another command
}else
{
switch (args[0]) {
case "node":
this.createNode(args[1]);
break;
case "label":
this.createLabel(args[1]);
break;
}
}
interpretMaster.refreshAndRepaint();
return null;
}
public void createNode(String nodeName)
{
this.behGraph.addVertex(nodeName);
System.out.print("vertex: "+nodeName+" added");
}
private void createLabel(String string) {
}
class str
{
int i;
long j;
}
}
Graph images before and after connecting two nodes:
and Here is my BehGraphUndirected class:
package GraphHandling;
import edu.uci.ics.jung.graph.UndirectedSparseGraph;
import java.util.LinkedList;
/**
*
* #author Administrator
*/
public class BehGraphUndirected extends UndirectedSparseGraph{
private final LinkedList<Node> nodeList;
public BehGraphUndirected()
{
this.nodeList = new LinkedList<>();
}
public void addNode(Node newNode)
{
this.nodeList.add(newNode);
}
}
You should look at what BehGraphUndirected is doing; it's not a JUNG class or interface.
What is the name of the vertex that's being created, and how does that relate to what's being passed to the create method?
I have compiled and tested your code , The Jung library seems working right and It extinguishes the different nodes by the different object that was given to it It seems you have some other problem , Like a problem in processing the input strings that are used as objects that create nodes.

Creating an instance of a generic type in DART

I was wondering if is possible to create an instance of a generic type in Dart. In other languages like Java you could work around this using reflection, but I'm not sure if this is possible in Dart.
I have this class:
class GenericController <T extends RequestHandler> {
void processRequest() {
T t = new T(); // ERROR
}
}
I tried mezonis approach with the Activator and it works. But it is an expensive approach as it uses mirrors, which requires you to use "mirrorsUsed" if you don't want to have a 2-4MB js file.
This morning I had the idea to use a generic typedef as generator and thus get rid of reflection:
You define a method type like this: (Add params if necessary)
typedef S ItemCreator<S>();
or even better:
typedef ItemCreator<S> = S Function();
Then in the class that needs to create the new instances:
class PagedListData<T>{
...
ItemCreator<T> creator;
PagedListData(ItemCreator<T> this.creator) {
}
void performMagic() {
T item = creator();
...
}
}
Then you can instantiate the PagedList like this:
PagedListData<UserListItem> users
= new PagedListData<UserListItem>(()=> new UserListItem());
You don't lose the advantage of using generic because at declaration time you need to provide the target class anyway, so defining the creator method doesn't hurt.
You can use similar code:
import "dart:mirrors";
void main() {
var controller = new GenericController<Foo>();
controller.processRequest();
}
class GenericController<T extends RequestHandler> {
void processRequest() {
//T t = new T();
T t = Activator.createInstance(T);
t.tellAboutHimself();
}
}
class Foo extends RequestHandler {
void tellAboutHimself() {
print("Hello, I am 'Foo'");
}
}
abstract class RequestHandler {
void tellAboutHimself();
}
class Activator {
static createInstance(Type type, [Symbol constructor, List
arguments, Map<Symbol, dynamic> namedArguments]) {
if (type == null) {
throw new ArgumentError("type: $type");
}
if (constructor == null) {
constructor = const Symbol("");
}
if (arguments == null) {
arguments = const [];
}
var typeMirror = reflectType(type);
if (typeMirror is ClassMirror) {
return typeMirror.newInstance(constructor, arguments,
namedArguments).reflectee;
} else {
throw new ArgumentError("Cannot create the instance of the type '$type'.");
}
}
}
I don't know if this is still useful to anyone. But I have found an easy workaround. In the function you want to initialize the type T, pass an extra argument of type T Function(). This function should return an instance of T. Now whenever you want to create object of T, call the function.
class foo<T> {
void foo(T Function() creator) {
final t = creator();
// use t
}
}
P.S. inspired by Patrick's answer
2022 answer
Just came across this problem and found out that although instantiating using T() is still not possible, you can get the constructor of an object easier with SomeClass.new in dart>=2.15.
So what you could do is:
class MyClass<T> {
final T Function() creator;
MyClass(this.creator);
T getGenericInstance() {
return creator();
}
}
and when using it:
final myClass = MyClass<SomeOtherClass>(SomeOtherClass.new)
Nothing different but looks cleaner imo.
Here's my work around for this sad limitation
class RequestHandler {
static final _constructors = {
RequestHandler: () => RequestHandler(),
RequestHandler2: () => RequestHandler2(),
};
static RequestHandler create(Type type) {
return _constructors[type]();
}
}
class RequestHandler2 extends RequestHandler {}
class GenericController<T extends RequestHandler> {
void processRequest() {
//T t = new T(); // ERROR
T t = RequestHandler.create(T);
}
}
test() {
final controller = GenericController<RequestHandler2>();
controller.processRequest();
}
Sorry but as far as I know, a type parameter cannot be used to name a constructor in an instance creation expression in Dart.
Working with FLutter
typedef S ItemCreator<S>();
mixin SharedExtension<T> {
T getSPData(ItemCreator<T> creator) async {
return creator();
}
}
Abc a = sharedObj.getSPData(()=> Abc());
P.S. inspired by Patrick
simple like that.
import 'dart:mirrors';
void main(List<String> args) {
final a = A<B>();
final b1 = a.getInstance();
final b2 = a.getInstance();
print('${b1.value}|${b1.text}|${b1.hashCode}');
print('${b2.value}|${b2.text}|${b2.hashCode}');
}
class A<T extends B> {
static int count = 0;
T getInstance() {
return reflectClass(T).newInstance(
Symbol(''),
['Text ${++count}'],
{Symbol('value'): count},
).reflectee;
}
}
class B {
final int value;
final String text;
B(this.text, {required this.value});
}
Inspired by Patrick's answer, this is the factory I ended up with.
class ServiceFactory<T> {
static final Map<Type, dynamic> _cache = <String, dynamic>{};
static T getInstance<T>(T Function() creator) {
String typeName = T.toString();
return _cache.putIfAbsent(typeName, () => creator());
}
}
Then I would use it like this.
final authClient = ServiceFactory.getInstance<AuthenticationClient>(() => AuthenticationClient());
Warning: Erik made a very good point in the comment below that the same type name can exist in multiple packages and that will cause issues. As much as I dislike to force the user to pass in a string key (that way it's the consumer's responsibility to ensuring the uniqueness of the type name), that might be the only way.

a last in, first out (LIFO) abstract data type and data structure. Perhaps the most common use of stacks is to store

MyStack()
{
Vector<Integer> v=new Vector<Integer>(10,2);
}
void push(int n)
{
v.addElement(n);
}
void pop()
{
if(v.isEmpty())
System.out.println("Stack underflow!");
else
System.out.println(v.elementAt(0));
}
void display()
{
for(int i=0;i<v.size();i++)
System.out.print(v.elementAt(i) +" ");
}
}
class StackDemo
{
public static void main(String args[])
{
Scanner in=new Scanner(System.in);
MyStack s=new MyStack();
int option=0;
do
{
System.out.println("1: Push\n2:Pop\n3:Display\n4:Quit");
System.out.println("Enter your option: ");
option=in.nextInt();
switch(option)
{
case 1:
{
System.out.println("Enter an integer:");
int n=in.nextInt();
s.push(n);break;
}
case 2:s.pop();break;
case 3:s.display();break;
}
}
while(option!=4);
}
}
// throws an error: variable v not found. Any help would be much appreciated.Thanks.
It looks like v is being created locally in your constructor instead of as a member of your class.
Try defining v as a class member and then simply assign it in your constructor.
class MyStack {
Vector<Integer> v;
public MyStack() {
v = new Vector<Integer>(10,2);
}
}
Or just assign it when you define it:
class MyStack {
Vector<Integer> v = new Vector<Integer>(10,2);
}
Check out the Java tutorial on class members.

Resources