I'm writing a small library.
public class MyClass {
public static String doSomethingWithString(final String s) {
new MyClass().doSomething(s);
}
public String doSomething(final String s) {
return null;
}
}
Or I can do like this.
public class MyClass {
public static String doSomethingWithString(final String s) {
return null;
}
public String doSomething(final String s) {
return doSomethingWithString(s);
}
}
Which style is preferable? Are they same?
UPDATE
Thank you for comments and answers.
Here are two classes.
public class IdEncoder {
private static String block(final long decoded) {
final StringBuilder builder = new StringBuilder(Long.toString(decoded));
builder.append(Integer.toString(
ThreadLocalRandom.current().nextInt(9) + 1)); // 1-9
builder.append(Integer.toString(
ThreadLocalRandom.current().nextInt(9) + 1)); // 1-9
builder.reverse();
return Long.toString(
Long.parseLong(builder.toString()), Character.MAX_RADIX);
}
public static String encodeLong(final long decoded) {
return block(decoded >>> 0x20) + "-" + block(decoded & 0xFFFFFFFFL);
}
public String encode(final long decoded) {
return encodeLong(decoded);
}
}
And another style.
public class IdDecoder {
public static long decodeLong(final String encoded) {
return new IdDecoder().decode(encoded);
}
public long decode(final String encoded) {
final int index = encoded.indexOf('-');
if (index == -1) {
throw new IllegalArgumentException("wrong encoded: " + encoded);
}
return (block(encoded.substring(0, index)) << 32)
| (block(encoded.substring(index + 1)));
}
private long block(final String encoded) {
final StringBuilder builder = new StringBuilder(
Long.toString(Long.parseLong(encoded, Character.MAX_RADIX)));
builder.reverse();
builder.deleteCharAt(builder.length() - 1);
builder.deleteCharAt(builder.length() - 1);
return Long.parseLong(builder.toString());
}
}
If you are just picking between these 2 options, take the second one.
The reason is the first requires you to allocate a new dummy object on the heap just to call a method. If there is truly no other difference, don't waste the time and space and just call the static method from the class.
The second is more akin to a static Utility function, which are a fine coding practice.
When writing a library, ease of use dramatically trumps general best practices. Your method should be static if it doesn't make sense for a user to instantiate something in order to access it. However often it is actually much cleaner and more powerful for a method to be part of an object, because it allows the user (as well as the library writer) to override it in child classes.
In a sense, you aren't actually asking a programming question, but a UX question. Ask yourself how your users would best benefit from accessing your code, and implement it that way. As a good benchmark, look at the Guava API; it consists of many static utility classes, but just as many classes and interfaces designed to be easily extended. Do what you think is best.
Related
I have a java class in which I store an Enum.(shown at the bottom of this question) In this enum, I have a method named toCommaSeperatedString() who returns a comma separated String of the enums values. I am using a StringBuilder after reading some information on performance in this question here.
Is the way I am converting this enum's values into a commaSeperatedString the most efficient way of doing so, and if so, what would be the most efficient way to remove the extra comma at the last char of the String?
For example, my method returns 123, 456, however I would prefer 123, 456. If I wanted to return PROPERTY1, PROPERTY2 I could easily use Apache Commons library StringUtils.join(), however, I need to get one level lower by calling the getValue method when I am iterating through the String array.
public class TypeEnum {
public enum validTypes {
PROPERTY1("123"),
PROPERTY2("456");
private String value;
validTypes(String value) {
this.value = value;
}
public String getValue() {
return value;
}
public static boolean contains(String type) {
for (validTypes msgType : validTypes.values()) {
if (msgType.value.equals(type)) {
return true;
}
}
return false;
}
public static String toCommaSeperatedString() {
StringBuilder commaSeperatedValidMsgTypes = new StringBuilder();
for(validTypes msgType : validTypes.values()) {
commaSeperatedValidMsgTypes.append(msgType.getValue() + ", ");
}
return commaSeperatedValidMsgTypes.toString();
}
}
}
I wouldn't worry much about efficiency. It's simple enough to do this that it will be fast, provided you don't do it in a crazy way. If this is the most significant performance bottleneck in your code, I would be amazed.
I'd do it something like this:
return Arrays.stream(TypeEnum.values())
.map(t -> t.value)
.collect(Collectors.joining(','));
Cache it if you want; but that's probably not going to make a huge difference.
A common pattern for the trailing comma problem I see is something like
String[] values = {"A", "B", "C"};
boolean is_first = true;
StringBuilder commaSeperatedValidMsgTypes = new StringBuilder();
for(String value : values){
if(is_first){
is_first = false;
}
else{
commaSeperatedValidMsgTypes.append(',');
}
commaSeperatedValidMsgTypes.append(value);
}
System.out.println(commaSeperatedValidMsgTypes.toString());
which results in
A,B,C
Combining this with the answers about using a static block to initialize a static final field will probably give the best performance.
The most efficient code is code that doesn't run. This answer can't ever change, so run that code as you have it once when creating the enums. Take the hit once, return the calculated answer every other time somebody asks for it. The savings in doing that would be far greater in the long term over worrying about how specifically to construct the string, so use whatever is clearest to you (write code for humans to read).
For example:
public enum ValidTypes {
PROPERTY1("123"),
PROPERTY2("345");
private final static String asString = calculateString();
private final String value;
private static String calculateString() {
return // Do your work here.
}
ValidTypes(final String value) {
this.value = value;
}
public static String toCommaSeparatedString() {
return asString;
}
}
If you have to call this static method thousand and thousand of times on a short period, you may worry about performance and you should first check that this has a performance cost.
The JVM performs at runtime many optimizations.
So finally you could write more complex code without added value.
Anyway, the actual thing that you should do is storing the String returned by toCommaSeperatedString and returned the same instance.
Enum are constant values. So caching them is not a problem.
You could use a static initializer that values a static String field.
About the , character, just remove it after the loop.
public enum validTypes {
PROPERTY1("123"), PROPERTY2("456");
private static String valueSeparatedByComma;
static {
StringBuilder commaSeperatedValidMsgTypes = new StringBuilder();
for (validTypes msgType : validTypes.values()) {
commaSeperatedValidMsgTypes.append(msgType.getValue());
commaSeperatedValidMsgTypes.append(",");
}
commaSeperatedValidMsgTypes.deleteCharAt
(commaSeperatedValidMsgTypes.length()-1);
valueSeparatedByComma = commaSeperatedValidMsgTypes.toString();
}
public static String getvalueSeparatedByComma() {
return valueSeparatedByComma;
}
I usually add a static method on the enum class itself:
public enum Animal {
CAT, DOG, LION;
public static String possibleValues() {
return Arrays.stream(Animal.values())
.map(Enum::toString)
.collect(Collectors.joining(","));
}
}
So I can use it like String possibleValues = Animal.possibleValues();
How would I create a method that has the input of a string and output of all the strings that were input into it like a super string?
for example in the main class:
a= "fido"
b= "rufus"
c= "dog"
superString(a);
superString(b);
superString(c);
System.out.println(superString()); should be "fidorufusdog"
so far I have=
public static String superString (String sb) {
StringBuilder ssb = new StringBuilder(32);
ssb = ssb.append(sb);
return ssb.toString();
}
My code below is what I am working on for a stock simulator:
public class Operators {
public static void operate(double price, double low, String company){
double percent = (price/low-1)*100;
double rpercent = Math.round(percent * 100.0) / 100.0;
StringBuilder sb = new StringBuilder(32);
if(rpercent <= 10) {
sb.append(company + " is trading at:");
sb.append("the current price is: " + price);
sb.append("the 52 week low is: " + low);
sb.append("percent of 52 week low is: " + rpercent);
}
}
}
The operate method is called in a for loop in my main method 506 times and I would like to take all 506 sb string and create a super string of all the results
I hope I do not underestimate the depth of the question or have your question wrong, but to me it sounds like you are asking for the static keyword?
class SomeClass {
static StringBuilder accumulator = new StringBuilder();
public String superString (String sb) {
SomeClass.accumulator.append(sb);
return ssb.toString();
}
}
This is simple usecase of the Java static keyword. Since accumulator is declared static there will be a single instance of the variable. And this single instance will be accessed by instances of the class SomeClass. For example:
SomeClass a;
SomeClass b;
a.superString("aaa");
b.superString("bbb");
// now accumulator.toString() returns "aaabbb"
Declare that string builder as the static member containing class and initialize it only once
static StringBuilder ssb;
public static String superString (String sb) {
if(ssb == null)
ssb = new StringBuilder(32);
ssb = ssb.append(sb);
return ssb.toString();
}
For this kind of probelm you've two choice :
Simple : create a static variable in the Java class, and manipulate it.
improve : create a design model which support your need.
Ex 1 :
public class Operators {
private static String text ="";
public static String superString(String sb) {
if (sb != null) {
text = text.concat(sb);
}
return text;
}
}
Ex 2 : you can use a Collecion or a List of strings.
This is poor OOP design. You would be much better off creating a class for Stock objects and overriding toString in the Stock class(or creating some other simple output method). Then add each instance of Stock to an array and call the each object's toString (or other output method you defined).
Most people understand the innate benefits that enum brings into a program verses the use of int or String. See here and here if you don't know. Anyway, I came across a problem that I wanted to solve that kind of is on the same playing field as using int or String to represent a constant instead of using an enum. This deals specifically with String.format(...).
With String.format, there seems to be a large opening for programmatic error that isn't found at compile-time. This can make fixing errors more complex and / or take longer.
This was the issue for me that I set out to fix (or hack a solution). I came close, but I am not close enough. For this problem, this is more certainly over-engineered. I understand that, but I just want to find a good compile-time solution to this, that provides the least amount of boiler-plate code.
I was writing some non-production code just to write code with the following rules.
Abstraction was key.
Readability was very important
Yet the simplest way to the above was preferred.
I am running on...
Java 7 / JDK 1.7
Android Studio 0.8.2
These are unsatisfactory
Is there a typesafe alternative to String.format(...)
How to get string.format to complain at compile time
My Solution
My solution uses the same idea that enums do. You should use enum types any time you need to represent a fixed set of constants...data sets where you know all possible values at compile time(docs.oracle.com). The first argument in String.format seems to fit that bill. You know the whole string beforehand, and you can split it up into several parts (or just one), so it can be represented as a fixed set of "constants".
By the way, my project is a simple calculator that you probably seen online already - 2 input numbers, 1 result, and 4 buttons (+, -, ×, and ÷). I also have a second duplicate calculator that has only 1 input number, but everything else is the same
Enum - Expression.java & DogeExpression.java
public enum Expression implements IExpression {
Number1 ("%s"),
Operator (" %s "),
Number2 ("%s"),
Result (" = %s");
protected String defaultFormat;
protected String updatedString = "";
private Expression(String format) { this.defaultFormat = format; }
// I think implementing this in ever enum is a necessary evil. Could use a switch statement instead. But it would be nice to have a default update method that you could overload if needed. Just wish the variables could be hidden.
public <T> boolean update(T value) {
String replaceValue
= this.equals(Expression.Operator)
? value.toString()
: Number.parse(value.toString()).toString();
this.updatedString = this.defaultFormat.replace("%s", replaceValue);
return true;
}
}
...and...
public enum DogeExpression implements IExpression {
Total ("Wow. Such Calculation. %s");
// Same general code as public enum Expression
}
Current Issue
IExpression.java - This is a HUGE issue. Without this fixed, my solution cannot work!!
public interface IExpression {
public <T> boolean update(T Value);
class Update { // I cannot have static methods in interfaces in Java 7. Workaround
public static String print() {
String replacedString = "";
// for (Expression expression : Expression.values()) { // ISSUE!! Switch to this for Expression
for (DogeExpression expression : DogeExpression.values()) {
replacedString += expression.updatedString;
}
return replacedString;
}
}
}
So Why Is This An Issues
With IExpression.java, this had to hacked to work with Java 7. I feel that Java 8 would have played a lot nicer with me. However, the issue I am having is paramount to getting my current implementation working The issue is that IExpression does not know which enum to iterate through. So I have to comment / uncomment code to get it to work now.
How can I fix the above issue??
How about something like this:
public enum Operator {
addition("+"),
subtraction("-"),
multiplication("x"),
division("÷");
private final String expressed;
private Operator(String expressed) { this.expressed = expressed; }
public String expressedAs() { return this.expressed; }
}
public class ExpressionBuilder {
private Number n1;
private Number n2;
private Operator o1;
private Number r;
public void setN1(Number n1) { this.n1 = n1; }
public void setN2(Number n2) { this.n2 = n2; }
public void setO1(Operator o1) { this.o1 = o1; }
public void setR(Number r) { this.r = r; }
public String build() {
final StringBuilder sb = new StringBuilder();
sb.append(format(n1));
sb.append(o1.expressedAs());
sb.append(format(n2));
sb.append(" = ");
sb.append(format(r));
return sb.toString();
}
private String format(Number n) {
return n.toString(); // Could use java.text.NumberFormat
}
}
Given I have the following structure already existing:
private void acceptInner(final Path path) throws IOException {
String newId = FileUtils.readAndModifyFileEntry(StageRename.ID_FILE, "id",
idString -> String.valueOf(Integer.parseInt(idString) + 1));
BaseUtils.moveKeepExtension(path, StageRename.OUTPUT_DIRECTORY, newId);
}
Where FileUtils.readAndModifyFileEntry is declared as:
public static String readAndModifyFileEntry(final Path path, final String entryKey
, final UnaryOperator<String> operator) throws IOException { ... }
Now I want to move the operator that increases a string value as an integer by one, to a new helper class, I have made two proposals:
final public class MapperUtils {
private MapperUtils() {
throw new UnsupportedOperationException();
}
public static String incrementAsInt(final String input) {
return String.valueOf(Integer.parseInt(input) + 1);
}
public static UnaryOperator<String> incrementAsIntOperator() {
return input -> String.valueOf(Integer.parseInt(input) + 1);
}
}
Which one would be better, usages are below:
String newId = FileUtils.readAndModifyFileEntry(StageRename.ID_FILE, "id",
MapperUtils::incrementAsInt);
versus
String newId = FileUtils.readAndModifyFileEntry(StageRename.ID_FILE, "id",
MapperUtils.incrementAsIntOperator());
Or should I keep both?
One of the advantages of the latter is that I can chain the operator with andThen() or compose(), but are there any disadvantages to it?
For more reference, I can use the following:
((UnaryOperator<String>)MapperUtils::incrementAsInt).andThen(/*something*/)
To manually cast it to an operator, but it really looks ugly. However if I provide both, does it then create an unwanted method explosion on the codebase?
If you keep both, then the incrementAsIntOperator() one can be written as
public static UnaryOperator<String> incrementAsIntOperator() {
return input -> incrementAsInt(input);
}
Which tells me that your second one is just a more specialized version of the first one.
I would keep the first method, as that one is more re-usable, and get rid of the second.
Whether or not providing both gives you an "unwanted method explosion" or not is really up to you. Besides that, I can't see any disadvantages of it. Of course you could use this also:
String newId = FileUtils.readAndModifyFileEntry(StageRename.ID_FILE, "id",
input -> MapperUtils.incrementAsInt(input));
i had given the following code in an interview. I want to know whether it is right or not..
public class DataAbstraction
{
public static void main (String args[])
{
MyDetails obj = new MyDetails();
obj.setNumebr(10);
obj.incrementBy(20);
int num = obj.getMumber();
System.out.println(num);
}
}
class MyDetails
{
private int n;
public void setNumebr(int i)
{
n = i;
}
public void incrementBy(int i)
{
n = n + i;
}
public int getMumber()
{
return n;
}
}
So please check it and correct me if i was wrong
There are many forms of abstractions in software. I would say that this is an example of data abstraction (though I would usually call it encapsulation). You could, if you would like to, change the member variable n to be of type... String(!), without changing the public interface of MyDetails.
Put differently: The details in the MyDetails class are hidden from the client code. The fact that MyDetails stores an int is abstracted away and it could be changed, for instance like this:
class MyDetails
{
private String n; // changed internal detail
public void setNumebr(int i)
{
n = "" + i;
}
public void incrementBy(int i)
{
n = "" + getMumber() + i;
}
public int getMumber()
{
return Integer.parseInt(n);
}
}
Have a look at the Wikipedia article on data abstraction for further details:
Abstraction > Data abstraction
Since there aren't enough details in the question its guessing time again:
1) No, its wrong. it contains various spelling errors like "getMumber" and "setNumebr".
2) Yes, if we ignore the spelling errors the methods seem to do what one would expect from their names.
2) No, it doesn't launch the rocket and it doesn't scale to multi processor machines (assuming these where the requirements).