Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > Locale


Автор: Гость_Elena 26.9.2004, 15:11
Пишу на учебном уровне некую программу(JSP), которая конвертирует одну валюту в другую.
В английской системе десятичные отделяются от целых точкой, а во французской запятой. Сервер JSP работает с цифрами в английской ситеме.
Если изобразить из английской во французской, проблемы нет:

Код
double valRelatif = a.getVal();
NumberFormat vLocal = NumberFormat.getNumberInstance(Locale.CANADA_FRENCH);
out.print(vLocal.format(valRelatif));

Теперь, мне нужно считать значение из текстового поля, куда юзер вводит денежную сумму во французской системе, которую он хочет конвертировать. Причем, мне надо проверить во французской ли системе введена сумма, если нет выдать error page с указаниями делать ввод во французской системе. Если же ввод сделан правильно, нужно считать данные в английскую систему для произведения расчетов.
Тут и есть загвозка:
От юзера я получаю String, по идее я должна сделать parseDouble(String s), но для меня абсолютная загадка, как это сделать в нужной локальной системе? Думаю, что идея поменять запятые на точки на уровне стринга, это - не то. Как обычно решаются подобные проблемы. Подскажите, пожалуйста, хотя бы алгоритм.
Заранее благодарна,
Елена

Автор: LSD 26.9.2004, 16:31
У NumberFormat есть метод Number parse(String), который позволяет преобразовать строку в число в соответствии с текущими региональными установками.
И еще есть класс DecimalFormatSymbols, в котором описанны все символы используемые для форматирования чисел.
Добавлено @ 16:32
Чуть не забыл Elena, зарегистрируйтесь и приходите к нам почаще!!!
Велкам smile.gif

Автор: Гость_Elena 26.9.2004, 17:18
Большое спасибо. У меня есть еще одна жуткая проблема:

Юзер выбирает методом select страны, названия которых берутся из текстового файла на французском языке. В кодировке для фр. яз <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> буковки с аксантами передаются специальными кодами. Собственно, чтоб было понятно, сам текстовый файл со странами:
Код
CAD,Dollars - Canada,1
USD,Dollars - &Eacute;tas-Unis, 0.732421
EUR,Euros,0.599565
GBP,Libres - Royamme Uni,0.399594
AUD,Dollars - Australie,0.941839
BRL,Reais - Br&eacute;sil,2.30068

&Eacute; - означает É, &eacute; - é.
Все это я загоняю в массив из объектов, созданного мною класса Деньги (Argent(String abreviature, String argentPays, double valeur;))
Теперь юзер выбирает 2 страны в селекте (из валюты которой в валюту которой), и в виде стринговых переменных эти названия передаются на другую страницу JSP, где уже, в зависимости от выбранного, происходят различные расчеты и выдается ответ.
Считываю переменные:
Код
String valeurInp = request.getParameter("valeurInp");
  String de = request.getParameter("de");
  String dans = request.getParameter("dans");


Теперь мне нужно выловить индексы объектов:
Код
int iDe = 0, iDans = 0;    
  for(int i = 0; i < a.length; i++)
  {  
if (a[i].getArgPays().equals(de)) { iDe = i; }
if (a[i].getArgPays().equals(dans)) { iDans = i; }
  }

В случае с аксантами не работает.
Добавляю под считыванием переменных:
Код
if (de == "Dollars - Étas-Unis") { de = "Dollars - &Eacute;tas-Unis"; }
  if (dans == "Dollars - Étas-Unis") { dans = "Dollars - &Eacute;tas-Unis"; }
  if (de == "Reais - Brésil") { de = "Reais - Br&eacute;sil"; }
  if (dans == "Reais - Brésil") { dans = "Reais - Br&eacute;sil"; }

Опять не работает, и в чем проблема собершенно не представляю.
А как-то надо сделать, чтобы заработало.

P.S.: Спасибо, за приглашение зарегистрироваться, обещаю сделать это в ближайшее будущее.



Автор: LSD 26.9.2004, 18:43
Я честно говоря не особенно разбираюсь в JSP, поэтому не совсем хорошо понял проблему, можно описать проблему поподробнее (тем боле что как я понял она не связанна с особенностями JSP). Единственное что я заметил, это то что String сраниваются ==, а не equals().

Автор: Elene 27.9.2004, 03:00
В данном случае, это не Strings, как String, а members определенного класса, к которым есть доступ только через определенные функции типа getMember() поэтому стравнение типа == в данном случае не работает, работает только equals() (Это чистая Джава). Проблема не в этом.
Попытаюсь объяснить по-подробнее...
Селект выглядит следующим образом:
Код
<select size="1" name="dans">
       <%
  for (int c = 0; c < a.length; c++)
  {
   out.print("<option>" + a[c].getArgPays() + "</option>");
  }
 %>
       </select>


а - это массив объектов выше упомянутого класса Деньги.
a[c].getArgPays() - дает среднию колонку из текстового файла, где как раз a[1].getArgPays() - это "Dollars - &Eacute;tas-Unis", а a[5].getArgPays() - это "Reais - Br&eacute;sil". В коде НТМL, это тоже выглядит аналогично:
Код
<select size="1" name="de">
 <option>Dollars - Canada</option>
                               <option>Dollars - &Eacute;tas-Unis</option>
                              <option>Euros</option>
                               <option>Libres - Royamme Uni</option>
                               <option>Dollars - Australie</option>
                               <option>Reais - Br&eacute;sil</option>        
       </select>

На экране мы видим "Dollars - Étas-Unis" и "Reais - Brésil". Теперь надо передать selected option с одной страницы на другую нажатием кнопки, это все стандартно, как при обработке любой НТМL формы. Я передаю значение "de". Смотрю, что получается в случае с США и с Бразилией:
Код
String de = request.getParameter("de");
out.print(" de = " + de + "<br>");

Смотрю на экран, вижу "Dollars - Étas-Unis".
Открываю код НТМL и опять вижу: de = Dollars - Étas-Unis<br>
Все "&Eacute;" не передались, передались "É", хотя все кодировки те же. А сранивать мне надо с "Dollars - &Eacute;tas-Unis" из текстового файла. Причем, эти "É" как-то так очень хитро передаются, что получается что "É", которая передалась не распознается, как "É", которую я печатаю для сравнения.
Мне смутно помнится, что в PHP, например, существуют какие-то хидеры (header) для encoding при пересылке данных. Существует ли что-то такое в JSP? А, главное, как узнать, что передается на самом деле на уровне Java, и почему не распознаются эти переданные буквы с аксантами.

Автор: Elene 27.9.2004, 05:09
Спасибо, проблема решена. Оказывается нужно было пойти с .equals() до конца и использовать вместо
Код
if (de =="Reais - Brésil") { de = "Reais - Br&eacute;sil"; }

вот это:
Код
if (de.equals("Reais - Brésil")) { de = "Reais - Br&eacute;sil"; }

только, вот, не понятно почему, ведь de это как бы String, а не объект. Или я ошибаюсь... hehe.gif
Поясните, пожалуйста, хочется в механизме разобраться

Автор: Zandr 27.9.2004, 08:21
Да все как-бы просто - есть примитивы: boolean, byte, char, short, int, long, float, double - в переменных этих типов хранятся собственно значения. Например:
Код
int a = 5;

В a будет лежать 5.
String, Integer, Object, StringBuffer, JPanel, и т.д. и т.п. - классы.
Код
String s = "abcdef";

В s будет лежать не строка "abcdef", а адрес этой строки в памяти компьютера. Если вы делаете еще одну строку
Код
String str = "abcdef";

str будет содержать адрес этой новой строки, который не совпадает с адресом предыдущей, поэтому следующий код
Код
str == s

сравнивает не содержимое этих строк, а их адреса. Метод же equals делает как раз то что вам нужно.
Виновником этой путаницы со строками является "усовершенствование" языка, позволяющее в некоторых случаях работать со строками как с примитивами:
Код
// Создание
String s1 = "Новая строчка.";
// Тогда как в "классическом" исполнении это выглядит так:
String s2 = new String("Еще одна.");
// Конкатенация (склеивание):
String s3 = s1 + ' ' + s2;
// Тогда как на самом деле это работает примерно так:
String s4 = new StringBuffer(s1).append(' ').append(s2).toString();

Автор: Elene 27.9.2004, 12:10
Cпасибо, что-то смутно начинает проясняться в голове.
Скажите, мне еще, пожалуйста, а что конкретно получается на уровне адресов значений, когда я в начале страницы запрашиваю то, что я прислала с другой. (valeur по-французски = value по-английски):
Код
String valeurInp = request.getParameter("valeurInp");

Проблема в том, что этот String valeurInp у меня не парсится. Я уже стала на уровне интеджера проверять, не парсится и все тут. Что-то я опять не то делаю.
Парсю я так:
Код
int valeurOut = Integer.parseInt("valeurInp");
  out.print(valeurOut);

Выдается следующая ошибка:
Код
org.apache.jasper.JasperException: valeurInp


Автор: Zandr 27.9.2004, 12:24
Код
int valeurOut = Integer.parseInt(request.getParameter("valeurInp"));

должно быть если я правильно понял...

На какой именно строке ошибка вылетает?

Одинаковы ли имена в коде и в HTML (нет ли очепяток)?

Автор: Elene 27.9.2004, 13:15
Спасибо. Действиетльно, где-то очепяталась. Переписала, стало работать.
Это моя первая программа на JSP, и Java у меня еще только в процессе изучения. Вот бы еще научиться дубль по-французски запарсивать. Насколько я понимаю, в данном случае французский вариант эквивалентен русскому, может кто-то это уже делал...

У NumberFormat я не нашла метод Number parse(String), который позволяет преобразовать строку в число в соответствии с текущими региональными установками. Там есть только
parse(String source)
Parses text from the beginning of the given string to produce a number.
, и
parse(String source, ParsePosition parsePosition)
Returns a Long if possible (e.g., within the range [Long.MIN_VALUE, Long.MAX_VALUE] and with no decimals), otherwise a Double.
, и
parseObject(String source, ParsePosition pos)
Parses text from a string to produce a Number.

Автор: LSD 27.9.2004, 19:37
Цитата(Elene @ 27.9.2004, 05:09)
только, вот, не понятно почему, ведь de это как бы String, а не объект. Или я ошибаюсь... hehe.gif
Поясните, пожалуйста, хочется в механизме разобраться

Zandr правильно написал, что String это объекты и соответсвенно оператор == сравнивает не строки а ссылки на объекты. Но есть одно но, в Java String это особые объекты. Для строк есть такое понятие как пул, это место где находятся все строки которые заданны литералами и константами или помещены туда принудительно. И тогда для двух любых строк из пула оператор == и метод s.equals() возвращают одно и тоже значение. Т.е. объекты не дублируются а используются уже существующие. Для вашего случая код можно было переписать так:
Код

de = intern();
if(de =="Reais - Brésil") { de = "Reais - Br&eacute;sil"; }

Автор: Гость_Elena 29.9.2004, 00:40
A mogno po-podrobnee. Chto takoe intern(), chto konkretno on delaet s adresami ili so znacheniami, chto vozvrschaet i k kakomy klassy otnositsa. Nikogda o nem ne slishala.
(Izvinite za otsytstvie cirillic)

Автор: LSD 29.9.2004, 18:38
Я ошибся в коде, надо было:
Код
de = de.intern();
if(de =="Reais - Brésil") { de = "Reais - Br&eacute;sil"; }


intern() это метод String, который проверяет есть ли уже такая строка в пуле строк, и если она там есть, то возвращает ссылку на строку из пула, если нет то помещает ее туда. Таким образом можно избежать дублирования строк, и заменить equals() на ==. Т.е. s1.intern() == s2.intern() истина, тогда и только тогда когда s1.equals(s2) истина. Константанты и строки заданные непосредственно в коде программы помещаются в пул автоматически.

Автор: Гость_Elene 1.10.2004, 00:14
Spasibo, teper' poniatno

Автор: Elene 1.10.2004, 21:45
Ура!!! Я его(ее) добила!!!

Код
<%! NumberFormat vLocal = NumberFormat.getNumberInstance(Locale.CANADA_FRENCH);%>

<%
  Number n = vLocal.parse(request.getParameter("valeurInp"));  
  double valeurOut = n.doubleValue();
%>


(Вдруг, кому-то тоже пригодится - biggrin.gif ):

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)