I have a class like this
public class TypeUtil {
private static final TypeUtil s_instance = new TypeUtil();
public static TypeUtil getInstance() {
return s_instance;
}
private TypeUtil() {
}
public void metadata() {
// some code here
// and use some_object value here only not in isAlpha
}
public boolean isAlpha(String value) {
}
}
And which I am using to call metadata class like this
TypeUtil util = TypeUtil.getInstance();
util.metadata();
Similarly, I am using above TypeUtil class to call isAlpha method like this -
TypeUtil.getInstance().isAlpha(some_value);
Problem Statement:-
Now what I am trying to do is - I need to pass one object to TypeUtil constructor, and which I need to use in metadata method. With the above code, how can I do that?
Is this ok to do like this? or is there any better way of doing it?
TypeUtil util = TypeUtil.getInstance(some_object);
util.metadata();
And then in the getInstance method of TypeUtil class assign this some_object value to some_variable object?
If yes, then how would I call isAlpha method? Bcoz for that, I don't want to pass any object to the constructor for calling it.
You could add a parameter to metadata() to make it metadata(SomeType name), or just make the TypeUtil constructor public and add a parameter to it:
private final SomeType name;
public TypeUtil(SomeType name) {
this.name = name;
}
Although, considering that you only need some_object for metadata(), I would suggest the first option.
Given my understanding of your question, this is one way of doing what you want to do. Assuming you want your some_object to be static:
public class TypeUtil {
private static final TypeUtil s_instance = new TypeUtil();
private static SomeType some_object = default_Object; // any default value you want
public static TypeUtil getInstance() {
return s_instance;
}
public static TypeUtil getInstance(SomeType some_object) {
this.some_object = some_object;
return s_instance;
}
private TypeUtil() {
}
public void metadata() {
// some code here
// and use some_object value here only not in isAlpha
}
public boolean isAlpha(String value) {
}
}
Related
what do you think would be the best way to manage settings knowing that I have no use for them to be stored in a file.
Is a simple POJO like below with getters and setters enough?
public class Settings {
private int setting1;
private boolean setting2;
private String setting3;
public Settings() {
// Some default values in constructor
setting1 = 12;
setting2 = false;
setting3 = "A setting";
}
public int getSetting1() {
return setting1;
}
public void setSetting1(int setting1) {
this.setting1 = setting1;
}
public boolean isSetting2() {
return setting2;
}
public void setSetting2(boolean setting2) {
this.setting2 = setting2;
}
public String getSetting3() {
return setting3;
}
public void setSetting3(String setting3) {
this.setting3 = setting3;
}
}
Should I use something more advanced? Like a class that would capture the type of the parameter in question like Setting<Integer> setting1 = new Setting(12); ?
I thank you in advance for your answers.
Keep it simple.
Here's an immutable class that does everything you need. No more, no less:
public final class Settings {
public final int setting1;
public final boolean setting2;
public String setting3;
public Settings(int setting1, boolean setting2, String setting3) {
this.setting1 = setting1;
this.setting2 = setting2;
this.setting3 = setting3;
}
}
If you expect to compare Settings objects, then implement hashCode and equals.
Everything else is just ceremony until you actually need it.
If you are using Java 14, then save some key-strokes by using records:
public record Settings(int setting1, boolean setting2, String setting3) {}
If you can get the job done with your Setting class, I don't see any reason why you need to make it complex.
Getters and setters are introduce mutability. Its better you can create this class more immutable fashion. You can achieve this many ways. Here is two ways,
Builder Pattern
Create a static factory method instead of constructor (Static factory method pattern)
public static class One {
#Override
public String interact(String... values) {
String actualTextOne = "test";
return actualTextOne;
}
}
public static class Two {
#Override
public String interact(String... values) {
String actualTextTwo = "test";
/* Here I need to compare actualTextOne and actualTextTwo, but the problem is that I can't find solluction how to use actualTextOne in Two class*/
return actualTextTwo;
}
}
You cannot do that.
Please check variable scope in java.
https://www.codecademy.com/articles/variable-scope-in-java
A possible solution here is to call the method interact from the class One. Something like this
public static class Two {
#Override
public String interact(String... values) {
String actualTextTwo = "test";
One one = new One();
String actualTextOne = one.interact(values);
// compare values here
return actualTextTwo;
}
}
Why in your classes functions have parameters if you dont use it?
You can mark your class with static only if he is nested, else you need do like this:
class Two {
static public String interact(String... values) {
String actualTextTwo = "test";
return actualTextTwo;
}
}
String textOne = One.interact("");
String textTwo = Two.interact("");
System.out.println(textOne==textTwo);
I'm writing a library, which has a predefined set of values for an enum.
Let say, my enum looks as below.
public enum EnumClass {
FIRST("first"),
SECOND("second"),
THIRD("third");
private String httpMethodType;
}
Now the client, who is using this library may need to add few more values. Let say, the client needs to add CUSTOM_FIRST and CUSTOM_SECOND. This is not overwriting any existing values, but makes the enum having 5 values.
After this, I should be able to use something like <? extends EnumClass> to have 5 constant possibilities.
What would be the best approach to achieve this?
You cannot have an enum extend another enum, and you cannot "add" values to an existing enum through inheritance.
However, enums can implement interfaces.
What I would do is have the original enum implement a marker interface (i.e. no method declarations), then your client could create their own enum implementing the same interface.
Then your enum values would be referred to by their common interface.
In order to strenghten the requirements, you could have your interface declare relevant methods, e.g. in your case, something in the lines of public String getHTTPMethodType();.
That would force implementing enums to provide an implementation for that method.
This setting coupled with adequate API documentation should help adding functionality in a relatively controlled way.
Self-contained example (don't mind the lazy names here)
package test;
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<HTTPMethodConvertible> blah = new ArrayList<>();
blah.add(LibraryEnum.FIRST);
blah.add(ClientEnum.BLABLABLA);
for (HTTPMethodConvertible element: blah) {
System.out.println(element.getHTTPMethodType());
}
}
static interface HTTPMethodConvertible {
public String getHTTPMethodType();
}
static enum LibraryEnum implements HTTPMethodConvertible {
FIRST("first"),
SECOND("second"),
THIRD("third");
String httpMethodType;
LibraryEnum(String s) {
httpMethodType = s;
}
public String getHTTPMethodType() {
return httpMethodType;
}
}
static enum ClientEnum implements HTTPMethodConvertible {
FOO("GET"),BAR("PUT"),BLAH("OPTIONS"),MEH("DELETE"),BLABLABLA("POST");
String httpMethodType;
ClientEnum(String s){
httpMethodType = s;
}
public String getHTTPMethodType() {
return httpMethodType;
}
}
}
Output
first
POST
Enums are not extensible. To solve your problem simply
turn the enum in a class
create constants for the predefined types
if you want a replacement for Enum.valueOf: track all instances of the class in a static map
For example:
public class MyType {
private static final HashMap<String,MyType> map = new HashMap<>();
private String name;
private String httpMethodType;
// replacement for Enum.valueOf
public static MyType valueOf(String name) {
return map.get(name);
}
public MyType(String name, String httpMethodType) {
this.name = name;
this.httpMethodType = httpMethodType;
map.put(name, this);
}
// accessors
public String name() { return name; }
public String httpMethodType() { return httpMethodType; }
// predefined constants
public static final MyType FIRST = new MyType("FIRST", "first");
public static final MyType SECOND = new MyType("SECOND", "second");
...
}
Think about Enum like a final class with static final instances of itself. Of course you cannot extend final class, but you can use non-final class with static final instances in your library. You can see example of this kind of definition in JDK. Class java.util.logging.Level can be extended with class containing additional set of logging levels.
If you accept this way of implementation, your library code example can be like:
public class EnumClass {
public static final EnumClass FIRST = new EnumClass("first");
public static final EnumClass SECOND = new EnumClass("second");
public static final EnumClass THIRD = new EnumClass("third");
private String httpMethodType;
protected EnumClass(String name){
this.httpMethodType = name;
}
}
Client application can extend list of static members with inheritance:
public final class ClientEnum extends EnumClass{
public static final ClientEnum CUSTOM_FIRST = new ClientEnum("custom_first");
public static final ClientEnum CUSTOM_SECOND = new ClientEnum("custom_second");
private ClientEnum(String name){
super(name);
}
}
I think that this solution is close to what you have asked, because all static instances are visible from client class, and all of them will satisfy your generic wildcard.
We Fixed enum inheritance issue this way, hope it helps
Our App has few classes and each has few child views(nested views), in order to be able to navigate between childViews and save the currentChildview we saved them as enum inside each Class.
but we had to copy paste, some common functionality like next, previous and etc inside each enum.
To avoid that we needed a BaseEnum, we used interface as our base enum:
public interface IBaseEnum {
IBaseEnum[] getList();
int getIndex();
class Utils{
public IBaseEnum next(IBaseEnum enumItem, boolean isCycling){
int index = enumItem.getIndex();
IBaseEnum[] list = enumItem.getList();
if (index + 1 < list.length) {
return list[index + 1];
} else if(isCycling)
return list[0];
else
return null;
}
public IBaseEnum previous(IBaseEnum enumItem, boolean isCycling) {
int index = enumItem.getIndex();
IBaseEnum[] list = enumItem.getList();
IBaseEnum previous;
if (index - 1 >= 0) {
previous = list[index - 1];
}
else {
if (isCycling)
previous = list[list.length - 1];
else
previous = null;
}
return previous;
}
}
}
and this is how we used it
enum ColorEnum implements IBaseEnum {
RED,
YELLOW,
BLUE;
#Override
public IBaseEnum[] getList() {
return values();
}
#Override
public int getIndex() {
return ordinal();
}
public ColorEnum getNext(){
return (ColorEnum) new Utils().next(this,false);
}
public ColorEnum getPrevious(){
return (ColorEnum) new Utils().previous(this,false);
}
}
you could add getNext /getPrevious to the interface too
#wero's answer is very good but has some problems:
the new MyType("FIRST", "first"); will be called before map = new HashMap<>();. in other words, the map will be null when map.add() is called. unfortunately, the occurring error will be NoClassDefFound and it doesn't help to find the problem. check this:
public class Subject {
// predefined constants
public static final Subject FIRST;
public static final Subject SECOND;
private static final HashMap<String, Subject> map;
static {
map = new HashMap<>();
FIRST = new Subject("FIRST");
SECOND = new Subject("SECOND");
}
private final String name;
public Subject(String name) {
this.name = name;
map.put(name, this);
}
// replacement for Enum.valueOf
public static Subject valueOf(String name) {
return map.get(name);
}
// accessors
public String name() {
return name;
}
In preparing for an interview, someone mentioned knowing how to make a class/method in java read-only. I've been doing a bit of searching, but haven't found anything really concrete.
Maybe this question is simpler to answer than I'm making it out to be, but what would be a way to make a class or method read-only in java?
The following code will ensure that your class is always READ ONLY, but if you find any loop hole, please post it here.
import java.io.Serializable;
final public class ImmutableClass implements Cloneable,Serializable {
private static final long serialVersionUID = 6488148163144293060L;
private static volatile ImmutableClass instance;
private ImmutableClass() {
// no-op
System.out.println("instance created : " + this.hashCode());
}
/**
* Lazy Instantiation
*
* #return
*/
public static ImmutableClass getInstance() {
if (instance == null) {
synchronized (ImmutableClass.class) {
System.out.println("aquired lock");
if (instance == null) {
instance = new ImmutableClass() {
};
}
System.out.println("released lock");
}
}
return instance;
}
public Object readResolve() {
System.out.println("readResolve()");
return getInstance();
}
#Override
public Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
}
The Read-only class means, we are talking about "IMMUTABLE" concept.
The following example depicts the same:
public class ImmutableString {
static String upcase(String s) {
return s.toUpperCase(); // here local variable s vanishes
// it return the value to a new String object
}
public static void main(String[] args) {
String s = new String("abc");
System.out.println(s); //abc
String s1 = upcase(s);
System.out.println(s1); //ABC
System.out.println(s); //abc
}
}
Lets Say you want a read only version of an object,
case 1: if your class contains fields which are not pointers to any other objects eg:
public class Person{
private String name;
//Getters n Setters
}
in this case, you can return a copy of this class, write a constructor that accepts Person, any one who wants to get a Person object will have a copy of this object so any Setter operations wont effect the original object(Strings are immutable)
Case 2: in case your object contains a pointer to another object or list or map
in this case make classes implement an interface which has only read-only methods(Getters) and wherever you are returning the object, change it to return this interface, so client will have access to only read-only methods
eg:
class Person implements ReadOnly{
String name;
.. assume pointers also in here
// Getter n Setters
public PersonReadOnly(){
return this;
}
}
interface PersonReadOnly {
public String getName();
}
Simple rule: Don't have any public fields and No public setter methods.
For example, see class below:
final class AReadOnlyClass
{
private int anInt;
public int GetAnInt()
{
return anInt;
}
}
I have a class UserFunction and it have two method getAudioFunction and getPromptFunction with returning String value, my problem is that i want to return both value in one method
how can i able to do that
UserFunction.java
public class UserFunction{
Map<String,PromptBean> promptObject=new HashMap<String,PromptBean>();
Map<String,AudioBean> audioObject = new HashMap<String,AudioBean>();
XmlReaderPrompt xrpObject=new XmlReaderPrompt();
public String getAudioFunction(String audioTag,String langMode )
{
Map<String, AudioBean> audioObject=xrpObject.load_audio(langMode);
AudioBean audioBean=(AudioBean)audioObject.get(audioTag);
String av=StringEscapeUtils.escapeXml(audioBean.getAudio());
return av;
}
public String getPromptFunction(String promptTag,String langMode )
{
Map<String, PromptBean> promptObject=xrpObject.load(langMode);
PromptBean promptBean= (PromptBean)promptObject.get(promptTag);
String pv=StringEscapeUtils.escapeXml(promptBean.getPrompt());
return pv;
}
}
You need to return an object which holds both values. You could create a class for this purpose. The class can have two getter methods for retrieving the values.
It is not possible to return more than one value from a method in java. You can set multiple value into Map or List or create a custom class and can return that object.
public Map<String,String> getAudioAndPromptFunction(String audioTag,String langMode )
{
Map<String,String> map =new HashMap();
...
map.put("audioBean",StringEscapeUtils.escapeXml(audioBean.getAudio()));
map.put("promptBean",StringEscapeUtils.escapeXml(promptBean.getPrompt());
return map;
}
or you can create a custom bean class like.
public class AudioPrompt{
private String audioBean;
private String promptBean;
...
}
public AudioPrompt getAudioAndPromptFunction(String audioTag,String langMode )
{
AudioPrompt audioPrompt =new AudioPrompt();
...
audioPrompt.set(StringEscapeUtils.escapeXml(audioBean.getAudio()));
audioPrompt.set(StringEscapeUtils.escapeXml(promptBean.getPrompt());
return audioPrompt ;
}
You'll need to return an object that includes both of the values. This could be an array with two elements, a Pair<A,B> class (which holds two generic values, typically from some pan-project utility library), or a method-specific class such as:
public class UserFunctionXmlPairing {
public final String audioBeanXml;
public final String promptBeanXml;
}
Create a new class that holds your two strings and return that.
class AudioPromptPair {
private String audio;
private String prompt;
public AudioPromptPair(String audio, String prompt) {
this.audio = audio;
this.prompt = prompt;
}
// add getters and setters
}
You can wrap all the values you wish into a single object and return that:
public class Prompts {
private Map<String, Object> prompts = new HashMap<String, Object>();
public void addPrompt(String name, Object prompt) {
this.prompts.put(name, prompt);
}
public Object getPrompt(String name) {
this.prompts.get(name);
}
}
It's even easier if your AudioBean and PromptBean have a common super class or interface.
My preference would be to lose the "Bean" in your class names. AudioPrompt and TextPrompt would be preferred.