Автор: vit

  • Удобный небезопасный кастинг

    Удобный автоматический кастинг

    Вещь не новая, но для тех, кто начинал программировать на Java в 90-ые и не очень привык к Generics-ам, это может быть интересно.

    Пример использования. Вам нужен метод, который возвращает объекты разных классов. Это могут быть обычные объекты – String, Integer, List, а могут быть и какие-то “свои” сложные бизнес-объекты вроде – ABController, XYZComponent, QWERTYHelper, FooManager (название зависит от возраста и предпочтений программиста).

    Так писали некоторые до Java 5.

        Helper helper = ....; // Какой-то вспомогательный класс, который хранит всякую ерунду
    
        String  path = (String) helper.get("storage.path");  // да, я знаю, хардкодить константы плохо. 
        Integer maxSize  = (Integer) helper.get("max.size"); 
        MyAwesomeDocumentManager manager = (MyAwesomeDocumentManager) helper.get("manager");

    Сейчас можно писать попроще. Конечно это сахар, но код выглядит полегче:
    (далее…)

  • Scala. Pattern Matching


    Продолжил работу по созданию учебных материалов по Scala.
    Выкладываю черновую версию одной из глав.

    Сопоставление по образцу (pattern matching). Начало.

    (далее…)

  • XMPP (Jabber) + Smack

    Недавно с товарищем начал работу над одним проектом, в котором нужно было написать программу для отправки сообщений пользователям по протоколу XMPP (т.е. через jabber).

    Список библиотек для работы нашли на официальном сайте xmpp.org.
    После серии небольших испытаний решили для интеграции с серверной частью написанной на Java использовать библиотеку Smack. Не факт, что будем использовать ее в продакшн, пытаемся распробовать. Пока продукт внушает доверие.

    1. Подключается к проекту элементарно (т.к. есть maven-овском репозитории): (далее…)

  • Netbeans Scala Maven

    Если вам приходилось работать в связке Netbeans 6.9.1 + Scala + Maven, то вы могли заметить, что компиляция происходит сильно медленнее, чем если бы вы НЕ использовали maven-scala-plugin.
    Дело в том, что по умолчанию компиляция запускается в режиме “компилировать все классы”. Это не очень приятно, учитывая то, что Scala компилятор не очень-то быстрый.
    К счастью, такое поведение можно изменить, указав в настройках для recompileMode значение modified-only (компилировать только измененные). По-умолчанию оно all.
    В некоторых случаях перевод в режим modified-only удобен, например если ваша задача не выпуск финальной версии продукта, а работа над определенным куском кода в режиме “написал, нажал Shift-F6, посмотрел что получилось…”.
    Внимание! Перевод recompileMode в режим modified-only может привести к нежелательным последствиям и побочным эффектам. Как говорится, не уверен – не обгоняй (а уверен – обгоняй).

    Пример возможной (но далеко не оптимальной) модификации pom.xml.

    
        org.scala-tools
        maven-scala-plugin
          
               modified-only
         
    
    
  • Работа с видео и аудио в Java. Xuggle

    Первый раз мне пришлось столкнуться с обработкой видео на Java лет 10-12 назад. Я еще был студентом и работал над проектом, в котором мы пытались сделать видео проигрыватель в виде апплета.
    В те времена, для перекодирования видео мы пробовали использовать JMF (Java Media Framework). Нам нужно было сделать хитрую предварительную обработку видео, т.к. показ видео осуществлялся апплетом с помощью самописного алгоритма. В итоге пришлось отказаться от JMF в пользу приложения написанного на С++, т.к. JMF оказался не особо функциональным…

    С тех пор прошло много времени, я участвовал в различных более масштабных и менее сумасшедших (и наоборот) Java-проектах (никак не связанных с видео), а тот проект проект был благополучно сдан и забыт. При этом какие-то знания по способам хранения и сжатия мультимедийной информации оказалось прочно засели у меня в голове (и даже некоторое время мучили ночными кошмарами)…


    Говорят история развивается по спирали. В прошлом году взялся за проект, в котором опять-таки требуется работа с видео/аудио потоками. Небольшие исследования показали, что JMF с тех пор особо не прогрессировал. Нельзя сказать, что этот фреймворк стоял на месте, но прогресс шел явно медленней, чем развитие технологий работы с видео в целом.
    К счастью спасение пришло от проекта (далее…)

  • Быстрый обратный корень на Java

    Fast Inverse Square Root, он же Fast InvSqrt() или 0x5f3759d5 – способ вычисления обратного квадратного корня из числа = 1/sqrt(x). Изобретен еще в 90-х годах.
    Если верить википедии, то этот алгоритм использовался в Quake III.
    Главная фишка метода в использовании “магической” константы – 0x5f3759d5, с помощью которой можно получить первое приближенное значение.
    Затем обычным методом Ньютона получаем улучшенное приближение.
    Подробнее можно прочитать здесь и здесь.

    public static float invSqrt(float x) {
        float xhalf = 0.5f*x; // x пополам
        int i = Float.floatToIntBits(x); // битовое представление числа. 
        i = 0x5f3759d5 - (i >> 1); //  отрицательные x не волнуют, т.к. из отриц. корень брать нельзя
        x = Float.intBitsToFloat(i); // вот оно, первое прибл. значение
        x = x*(1.5f - xhalf*x*x);
         // x = x*(1.5f - xhalf*x*x);
        return x;
    }
    
  • Принцип работы FFT и Scala

    Разбор алгоритма быстрого преобразования фурье (он же Fast Fourier transform, он же FFT).

    Целью публикации является отобразить суть алгоритма, а не создание быстрой по скорости работы реализации.
    Т.к. в этой программе я буду интенсивно использовать объекты вместо примитивных типов, а также рекурсию,
    скорость работы будет заведомо уступать многим другим реализациям FFT, которые можно сейчас найти
    в интернете в огромном количестве в открытом доступе.
    (далее…)

  • printf

    Небольшой справочник “для себя” по работе с джавным printf().

    Для простоты текста заменил System.out.printf() на printf().

    Базовые конструкции.

    %s → String или toString().

    printf("Hello %s!", "World"); //  "Hello World!"
    

    %n → Перенос строки.

    Byte, Short, Int, Long.

    %d → В десятеричном.
    %x → В шестнадцатеричном.

    %7d → В десятеричном. Минимальная ширина строки 7 знаков.

    printf("%7d", 1); //  "      1"

    %07d → Минимальная ширина строки 7 знаков. Начало забить нулями.

    printf("%07d", 1); //  "0000001"

    Float, Double.

    %f → Десятичное  число с точкой.
    %e → Десятичное  число с точкой и экспонентой.

    %.10f → С точностью 10 знаков после запятой.

    printf("%.10f", Math.PI); //  "3,1415926536"

    Date, Calendar.

    %tF → Дата в формате “год-месяц-день”.

    printf("%tF", new Date()); //  "2011-01-27"

    %tT → Время в формате “час:минута:секунда”.

    
    
    printf("%tT", new Date()); //  "22:42:37"
    
  • Поиск. КМП-алгоритм

    Недавно на досуге решил написать алгоритм КМП  (КнутаМорриса — Пратта) для Scala.

    Изначально, мне нужно было решить простенькую задачку – найти последовательность байт в потоке байтов. Сделал на Java. Потом, решил сделать тоже самое на Scala. Занятно, но в стандартной библиотеке коллекций Scala используется именно КМП поиск.

    Вот мой вариант.
    (далее…)

  • GWT. Обработка серверных исключений на клиенте.

    В целом обработка исключений при работе в GWT через RPC довольно детально описана в разделе документации DevGuideHandlingExceptions

    Важный момент на который следуют обратить внимание – throws для метода.

    Например, вот Ваш интерфейс:

    public interface MyService extends RemoteService {
      public String myMethod(String s);
    }

    Допустим Вы сделали класс MyException который наследуется от RuntimeException. Например, это исключение вы создали для своих прикладных нужд и хотите чтобы оно могло быть перекинуто и обработано на клиенте.

    Это конечно удобно, т.к. полученный тип исключений является Unchecked Exception. Таким образом его не нужно явно декларировать, оно может произойти где угодно (не надо прописывать везде throws) и такое исключение Вы не обязаны явно отлавливать. 

    Другими словами,  мы же не пишем для каждого метода throws RuntimeException!

    Тем не менее, если где-то у Вас в программе произойдет это исключение:

    public class MyServiceImpl extends RemoteServiceServlet implements
        MyService {
    
      public String myMethod(String s) {
        // Do something interesting with 's' here on the server.
        if (isError() ) { throw new MyException("ups");  
        // 
        return s;
      }
    }

    То это исключение в методе onFailure(Throwable caught) будет передано просто как InvocationException, а не как MyException!
    Дело в том, что если заглянуть в реализацию метода обработки вызова RPC-вызовов:

    RemoteServiceServlet. processCall() → RPC.invokeAndEncodeResponse() → RPC.encodeResponseForFailure() → RPCServletUtils.isExpectedException()
    мы найдем использование следующей конструкции:

    Class< ?>[] exceptionsThrown = serviceIntfMethod.getExceptionTypes();
    

    Другими словами, если Вы хотите чтобы Ваше исключение попадало в onFailure(Throwable caught) как MyException, то нужно обязательно декларировать throws, даже если Ваше исключение extends RuntimeException!

    В нашем примере это будет выглядеть так:

    public interface MyService extends RemoteService {
      public String myMethod(String s) throws MyException;
    }
    

    Вот такая вроде мелочь, но если ее не знать, могут возникнуть определенные неудобства.