2013-12-20 3 views
1

У меня есть список строки с некоторыми строками в моей Java программе, как показано ниже:перебор вертикальных значений в коллекции горизонтальных значений в другой коллекции

List<String> input = new ArrayList<String>(); 

    input.add("2013-07-31,A,47"); 
    input.add("2013-06-28,A,52"); 
    input.add("2013-05-31,A,63"); 

    input.add("2013-07-31,B,47"); 
    input.add("2013-06-28,B,54"); 
    input.add("2013-05-31,B,91"); 

    input.add("2013-07-31,C,78"); 
    input.add("2013-06-28,C,24"); 

    input.add("2013-07-31,D,99"); 
    input.add("2013-05-31,D,82"); 

Здесь в каждой строке, разделенная запятая первого маркер представляет дату , второй токен - это имя продукта, а третий токен - цена.

Я хочу, чтобы произвести отчет первенствовать с ниже формате таблицы, используя приведенный выше список:

Prod |   Price 
--------------------------------------------- 
    XXX | M1  M2  M3 
--------------------------------------------- 
    A  | 47  52  63 
    B  | 47  54  91 
    C  | 78  24  00 
    D  | 99  00  82 
--------------------------------------------- 

Где М1 2013-07-31, М2 2013-06-28 в то время как М3 2013-05-31 ,

Для достижения этой цели моей коллекции вывод должен быть список строки с членом Струны, как показано ниже:

A, 47, 52, 63 
    B, 47, 54, 91 
    C, 78, 24, 00 
    D, 99, 00, 82 

Обратите внимание, что во входных строк, где нет никакой ценности присутствуют на сегодняшний день, например, для 2013-05-31 для продукта C и 2013-06-28 для продукта D, значение должно быть по умолчанию равным 00 в выходных строках.

Таким образом, в выходных строках таких отсутствующие значения берутся как 00.

Как перебирать свою коллекцию ввода, который имеет datewise вертикальных значений для продукта, чтобы получить коллекцию выходной зависящие мудрых горизонтальных значений для 3 дат ?

Спасибо за чтение!

+0

разделил строку и создал объекты продукта, что было бы намного проще. – kai

+0

@peeskillet: Создание итератора для первой строки .. :) следует ли вставить это? Это не вопрос домашней работы ... – Nik

+0

Вы хотите полностью исключить даты из нового списка? –

ответ

1

Попробуйте этот код. Вы можете легко адаптировать его в соответствии с вашими конкретными потребностями.

import java.text.SimpleDateFormat; 
    import java.util.ArrayList; 
    import java.util.Date; 
    import java.util.HashMap; 
    import java.util.HashSet; 
    import java.util.List; 


    public class Test002 { 

     public static void main(String[] args) throws Exception { 
      List<String> input = new ArrayList<String>(); 

      input.add("2013-07-31,A,47"); 
      input.add("2013-06-28,A,52"); 
      input.add("2013-05-31,A,63"); 

      input.add("2013-07-31,B,47"); 
      input.add("2013-06-28,B,54"); 
      input.add("2013-05-31,B,91"); 

      input.add("2013-07-31,C,78"); 
      input.add("2013-06-28,C,24"); 

      input.add("2013-07-31,D,99"); 
      input.add("2013-05-31,D,82"); 

      HashSet<Date> dates = new HashSet<Date>(); 
      HashSet<String> products = new HashSet<String>(); 
      SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); 
      HashMap<String, Integer> counts = new HashMap<String, Integer>(); 

      for (String s : input){ 
       String[] str = s.split(","); 
       dates.add(sdf.parse(str[0])); 
       products.add(str[1]); 
       counts.put(str[0] + "#" + str[1], Integer.parseInt(str[2])); 
      } 

      for (String p : products){ 
       for (Date dt : dates){ 
        Integer cnt = counts.get(sdf.format(dt) + "#" + p); 
        if (cnt == null){ 
         System.out.print("00 "); 
        }else{ 
         System.out.printf("%2d ", cnt); 
        } 
       } 
       System.out.println(); 
      } 
     } 

    } 
+0

+1 для counts.put (str [0] + "#" + str [1], Integer.parseInt (str [2])); эта линия ... сохранен день! :) – Nik

+0

@Vicky Просто тривиальный трюк-разделитель, так как у вас не будет # нигде в вычислениях вашей программы. Поэтому я поставил его там, чтобы избежать неприятностей. –

0

Я думаю, что список - это правильная структура данных для хранения ваших значений, потому что она плоская. Мы не очень-то знаем о вашем домене, но если вам разрешено более трех дат, вы можете получить лист с миллионными столбцами.

Фактически, если это временный ряд, то наилучшее представление представляет собой серия листов и, возможно, лист с периодами агрегации (кварталы, недели, месяцы) и средние значения. Так что я бы моделировать свой домен следующим образом:

class TimeSeries { 
    String itemDescription; 
    Collection<Sample> samples; 
} 

class Sample { 
    Date date; 
    BigInteger price; 
} 

Тогда я преобразовать список входных строк в список TimeSeries объектов, которые вы впоследствии агрегат по дате, возможно, делая в среднем, когда несколько образцов доступны за тот же период и пропускают пустые. И, наконец, нарисуйте переваренный результат на лист Excel.

+0

Nopes. Даты будут либо 3, либо меньше. – Nik

0

Попробуйте это.Это даст вам желаемый результат первого использования карты затем преобразовать обратно в список

import java.util.ArrayList; 
import java.util.Collections; 
import java.util.HashMap; 
import java.util.List; 
import java.util.Map; 

public class test1 { 

    public static void main(String[] args) { 
     List<String> input = new ArrayList<String>(); 

     input.add("2013-07-31,A,47"); 
     input.add("2013-06-28,A,52"); 
     input.add("2013-05-31,A,63"); 

     input.add("2013-07-31,B,47"); 
     input.add("2013-06-28,B,54"); 
     input.add("2013-05-31,B,91"); 

     input.add("2013-07-31,C,78"); 
     input.add("2013-06-28,C,24"); 

     input.add("2013-07-31,D,99"); 
     input.add("2013-05-31,D,82"); 

     Map<String, ArrayList<String>> map = new HashMap<String, ArrayList<String>>(); 

     for (String s : input) { 
      String[] tokens = s.split(","); 
      if (!map.containsKey(tokens[1])) { 
       ArrayList<String> list = new ArrayList<String>(); 
       list.add(tokens[2]); 
       map.put(tokens[1], list); 
      } else { 
       ArrayList<String> list = map.get(tokens[1]); 
       list.add(tokens[2]); 
       map.put(tokens[1], list); 
      } 
     } 

     ArrayList<String> newList = new ArrayList<String>(); 
     for (Map.Entry<String, ArrayList<String>> entry : map.entrySet()) { 
      StringBuilder sb = new StringBuilder(); 
      sb.append(entry.getKey() + ","); 
      for (String s : entry.getValue()) { 
       sb.append(s + ","); 
      } 
      newList.add(sb.toString()); 
     } 

     Collections.sort(newList); 

     for (String s : newList) { 
      System.out.println(s); 
     } 
    } 
} 

Выход

A,47,52,63, 
B,47,54,91, 
C,78,24, 
D,99,82, 

К сожалению, я просто замечает вашу записку, но я не был в состоянии понять, то, что вы имели в виду это, так что я не совсем уверен, о том, как идти о производстве нули

+0

В части else 'map.put (tokens [1], list);' не требуется. –

0

Это, как я хотел бы сделать это в предположении, что

  • максимум один образец на сегодняшний день разрешено
  • код рендеринга решает, что даты, чтобы выбрать

Этот подход не создает промежуточную структуру данных до рендеринга, но сразу же рисует клетки, когда они читают из входного списка:.

// Maps items IDs to the row index in the excel sheet 
Map<String, Integer> items = new HashMap<>(); 
// Maps the string representation of the date to the column index in the sheet 
Map<String, Integer> columns = new HashMap<>(); 

public void process(List<String> input) { 
    for (String line: input) { 
    String[] desc = input.split(","); 
    Integer rowIdx = items.get(desc[1]); 
    if (rowIdx == null) { 
     rowIdx = drawNewItemAndGetRowIndex(desc[1]); 
    } 
    drawPrice(rowIdx, columns.get(desc[0]), desc[2]); 
    } 
} 

Перед выполнением этого кода необходимо инициализировать таблицу Excel и columns карту, поставив даты вы заинтересованы в Обратите внимание, я использовал строковое представление дАТ es вместо фактических Date объектов, потому что разбор не нужен для ваших целей.

Я оставил вам реализацию drawNewItemAndGetRowIndex, но в основном создает новые строки на листе Excel, регистрирует индекс на карте items, рисует заголовок и возвращает индекс строки.

Смежные вопросы