Java Fast Scanner Template

This is a fast scanner for Java using Petr’s java template. I have changed a bit to read (remaining) line.

import java.io.*;
import java.util.StringTokenizer;

/**
 * Created by sabbir on 01/14/16.
 */
public class Main {

    public static void main(String[] args) throws Exception {
        FastScanner scanner = new FastScanner(System.in);
        long val = scanner.nextLong();
        String str = scanner.nextLine();

        PrintWriter printWriter = new PrintWriter(System.out);
        printWriter.printf("%d\n", val);
        printWriter.printf("%d\n", str);
        printWriter.close();
    }

    static class FastScanner {
        private BufferedReader reader = null;
        private StringTokenizer tokenizer = null;

        public FastScanner(InputStream in) {
            reader = new BufferedReader(new InputStreamReader(in));
            tokenizer = null;
        }

        public String next() {
            if (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public String nextLine() {
            if (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    return reader.readLine();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }

            return tokenizer.nextToken("\n");
        }

        public long nextLong() {
            return Long.parseLong(next());
        }
        
        public long nextInt() {
            return Integer.parseInt(next());
        }

    }
}

Java Fast Scanner Template

Java Enum and Android IntDef/StringDef annotation

When we want a variable x to have values from some predefined constants then what can we do. We can declare the constant variables and set x from these constants. Lets assume x is currentDay and it can have any value from sunday to friday. We can code like this in java using integer constants.

public class Main {

    public static final int SUNDAY = 0;
    public static final int MONDAY = 1;
    public static final int TUESDAY = 2;
    public static final int WEDNESDAY = 3;
    public static final int THURSDAY = 4;
    public static final int FRIDAY = 5;
    public static final int SATURDAY = 6;

    private int currentDay = SUNDAY;

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Main obj = new Main();
        obj.setCurrentDay(WEDNESDAY);

        int today = obj.getCurrentDay();

        switch (today) {
        case SUNDAY:
            System.out.println("Today is SUNDAY");
            break;
        case MONDAY:
            System.out.println("Today is MONDAY");
            break;
        case TUESDAY:
            System.out.println("Today is TUESDAY");
            break;
        case WEDNESDAY:
            System.out.println("Today is WEDNESDAY");
            break;
        case THURSDAY:
            System.out.println("Today is THURSDAY");
            break;
        case FRIDAY:
            System.out.println("Today is FRIDAY");
            break;
        case SATURDAY:
            System.out.println("Today is SATURDAY");
            break;

        default:
            break;
        }
    }

    public void setCurrentDay(int currentDay) {
        this.currentDay = currentDay;
    }

    public int getCurrentDay() {
        return currentDay;
    }

}

Problem with this code is I can set any integer value to currentDay.

obj.setCurrentDay(100);

and compiler will not give me any error. Then in switch/case we will miss that value. So Java gives us a solution that is Enumeration or Enum. If We rewrite the code with Enum in Java.

public class Main {

    public enum WeekDays {
        SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY
    }

    private WeekDays currentDay = WeekDays.SUNDAY;

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Main obj = new Main();
        obj.setCurrentDay(WeekDays.WEDNESDAY);

        WeekDays today = obj.getCurrentDay();

        switch (today) {
        case SUNDAY:
            System.out.println("Today is SUNDAY");
            break;
        case MONDAY:
            System.out.println("Today is MONDAY");
            break;
        case TUESDAY:
            System.out.println("Today is TUESDAY");
            break;
        case WEDNESDAY:
            System.out.println("Today is WEDNESDAY");
            break;
        case THURSDAY:
            System.out.println("Today is THURSDAY");
            break;
        case FRIDAY:
            System.out.println("Today is FRIDAY");
            break;
        case SATURDAY:
            System.out.println("Today is SATURDAY");
            break;

        default:
            break;
        }
    }

    public void setCurrentDay(WeekDays currentDay) {
        this.currentDay = currentDay;
    }

    public WeekDays getCurrentDay() {
        return currentDay;
    }

}

Now we have type safety. I can not have any value other then WeekDays in currentDay variable. That is a great improvement, and we should use it. But in Android there is a problem.

Enum in Android: Enum is a full fledged class in Java. Every value of Enum is an object of that Enum class. So Enum values will take more memory then int constant we used earlier. Even in old android devices (<=2.2), there were some performance issue related to Enum which were solved in JIT compiler. Now we can use Enum in Android Application, but if our application is a memory hungry application or a game application then we better use integer constants instead of Enum. But then problem remains.

There is a solution. Android support annotation library has some good annotation helper which can be used to find bug earlier (in compile time). IntDef and StringDef are two Magic Constant Annotation which can be used instead of Enum. These will help us to check variable assignment like Enum in compile time. Following code showed how to use IntDef instead of Enum.

public class MainActivity extends Activity {

    public static final int SUNDAY = 0;
    public static final int MONDAY = 1;
    public static final int TUESDAY = 2;
    public static final int WEDNESDAY = 3;
    public static final int THURSDAY = 4;
    public static final int FRIDAY = 5;
    public static final int SATURDAY = 6;

    @IntDef({SUNDAY, MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY})
    @Retention(RetentionPolicy.SOURCE)
    public @interface WeekDays {}

    @WeekDays int currentDay = SUNDAY;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setCurrentDay(WEDNESDAY);

        @WeekDays int today = getCurrentDay();

        switch (today){
            case SUNDAY:
                break;
            case MONDAY:
                break;
            case TUESDAY:
                break;
            case WEDNESDAY:
                break;
            case THURSDAY:
                break;
            case FRIDAY:
                break;
            case SATURDAY:
                break;
            default:
                break;
        }

    }

    public void setCurrentDay(@WeekDays int currentDay) {
        this.currentDay = currentDay;
    }

    @WeekDays
    public int getCurrentDay() {
        return currentDay;
    }
}

Now we can not set any value other than WeekDays in currentDay or today variable. Compiler will check it and will give error. And if we use Android Studio, IDE will give suggestion about the value. So how to use it. At first declare the constants.

    public static final int SUNDAY = 0;
    public static final int MONDAY = 1;
    public static final int TUESDAY = 2;
    public static final int WEDNESDAY = 3;
    public static final int THURSDAY = 4;
    public static final int FRIDAY = 5;
    public static final int SATURDAY = 6;

Then declare the @IntDef for these constants,

    @IntDef({SUNDAY, MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY})
    @Retention(RetentionPolicy.SOURCE)
    public @interface WeekDays {}

To set a variable of WeekDays type, so that no value other than weekdays can be set to that variable, we declare it like following,

@WeekDays int currentDay ;

Now if there is any assignment which set currentDay to any other value than WeekDays, compiler will give a error. To set function parameter and function return type with WeekDays type,

    public void setCurrentDay(@WeekDays int currentDay) {
        this.currentDay = currentDay;
    }

    @WeekDays
    public int getCurrentDay() {
        return currentDay;
    }

@StringDef can be used in same manner.

public class MainActivity extends Activity {

    public static final String SUNDAY = "sunday";
    public static final String MONDAY = "monday";
    public static final String TUESDAY = "tuesday";
    public static final String WEDNESDAY = "wednesday";
    public static final String THURSDAY = "thursday";
    public static final String FRIDAY = "friday";
    public static final String SATURDAY = "saturday";


    @StringDef({SUNDAY, MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY})
    @Retention(RetentionPolicy.SOURCE)
    public @interface WeekDays {}


    @WeekDays String currentDay = SUNDAY;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setCurrentDay(WEDNESDAY);

        @WeekDays String today = getCurrentDay();


        switch (today){
            case SUNDAY:
                break;
            case MONDAY:
                break;
            case TUESDAY:
                break;
            case WEDNESDAY:
                break;
            case THURSDAY:
                break;
            case FRIDAY:
                break;
            case SATURDAY:
                break;
            default:
                break;
        }

    }

    public void setCurrentDay(@WeekDays String currentDay) {
        this.currentDay = currentDay;
    }

    @WeekDays
    public String getCurrentDay() {
        return currentDay;
    }
}

To use this feature, you have to add support-annotations library to your project. If you use Android Studio, then add following in your Gradle dependency.

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    ...
    compile 'com.android.support:support-annotations:22.0.0'
}

You can learn more about support annotation library here.  And below is android performance patterns video about price of Enum.

Java Enum and Android IntDef/StringDef annotation

Android Forground Service for device Orientation and surfaceview

This service start in foreground with a view in windowmanager which change the orientation of the device and a surfaceview which can be used by camera for recording even when phone locked and screen off. Thanks to pallab.


public class SurfaceViewService extends Service {
    private WindowManager windowManager;
    final WindowManager.LayoutParams myParams = new WindowManager.LayoutParams(
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.TYPE_SYSTEM_ERROR,
            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
            PixelFormat.TRANSLUCENT);
    private static SurfaceView mSurfaceView = null;
    
    @Override
    public void onCreate() {
        super.onCreate();
  
        windowManager = (WindowManager) getApplicationContext().getSystemService(WINDOW_SERVICE);
        myParams.gravity = Gravity.TOP | Gravity.CENTER;
        myParams.height=1;
        myParams.width=1;
        myParams.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
        mSurfaceView = new SurfaceView(this);
        windowManager.addView(mSurfaceView, myParams);
        
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
        builder.setContentTitle("gg")
                .setTicker("gg")
                .setContentText("gg is running")
                .setWhen(System.currentTimeMillis())
                .setSmallIcon(R.drawable.logo);
        
        Notification cur_notification = builder.build();
        
        startForeground(1, cur_notification);

        
    }
    
    public static SurfaceView getSurfaceView(){
        if(mSurfaceView==null) {
            mLogger.error("surfaceview service not started");
        }
        return mSurfaceView;
    }
    
    @Override
    public void onDestroy() {
        super.onDestroy();
        windowManager.removeView(mSurfaceView);
    }
    
    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        return null;
    }

}
Android Forground Service for device Orientation and surfaceview