2013-07-09 4 views
23

Я, в Java, ArrayList с этими значениями (количество строк, это просто экстракт)Создание Список_массивов уникальных значений

20/03/2013 23:31:46 6870 6810 6800 6720 6860 6670 6700 6650 6750 6830 34864 34272 20/03/2013 23:31:46 6910 6780 6800 6720 6860 6680 6620 6690 6760 6790 35072 34496

в случае, если первые два значения являются строками, которые containes данные и сохраненные в одном элементе.

Что я хочу сделать, это сравнить элементы строковых данных и удалить, например, второй и все элементы, относящиеся к этой строке.

В настоящем время, я использовал для цикла, каждые 13 элементов сравнивают строку (для сравнения только строк данных)

Моего вопроса: могу ли я реализовать другие лучшие решения?

Это мой код:

import java.util.Scanner; 
import java.util.List; 
import java.util.ArrayList; 
import java.io.*; 
import java.text.SimpleDateFormat; 
import java.util.Date; 

public class Downsampler { 
    public static void main(String[] args) throws Exception{ 

    //The input file 
    Scanner s = new Scanner(new File("prova.txt")); 


    //Saving each element of the input file in an arraylist 
    ArrayList<String> list = new ArrayList<String>(); 
    while (s.hasNext()){ 
     list.add(s.next()); 
    } 
    s.close(); 

    //Arraylist to save modified values 
    ArrayList<String> ds = new ArrayList<String>(); 

    // 
    int i; 
    for(i=0; i<=list.size()-13; i=i+14){ 

      //combining the first to values to obtain data 
      String str = list.get(i)+" "+list.get(i+1); 
      ds.add(str); 
      //add all the other values to arraylist ds 
      int j; 
      for(j=2; j<14; j++){ 
       ds.add(list.get(i+j)); 
      } 

      //comparing data values 
      int k; 
      for(k=0; k<=ds.size()-12; k=k+13){ 
       ds.get(k); //first data string element 
       //Comparing with other strings and delete 
       //TODO 
      } 
    } 
    } 
} 
+2

Вы должны опубликовать свой вопрос здесь: http://codereview.stackexchange.com/ – JREN

+0

код не завершен 1 брекеты отсутствует, так пожалуйста, напишите complte код –

+0

@AshishAggarwal, теперь должно быть в порядке, хотя сравнение значений часть не реализовано вообще – alessandrob

ответ

35

Создание Список_массивов уникальных значений

Вы можете использовать Set.toArray() метод.

Коллекция, которая не содержит повторяющихся элементов. Более формально наборы не содержат пары элементов e1 и e2, таких, что e1.equals (e2), и в наиболее один нулевой элемент. Как видно из его названия, этот интерфейс моделирует математическую абстрактную абстракцию.

http://docs.oracle.com/javase/6/docs/api/java/util/Set.html

+0

Хорошо, но как я могу сделать, чтобы удалить все значения, связанные с строкой данных? Я имею в виду, если я найду строку данных, равную другой, я должен удалить все значения, связанные с этим – alessandrob

+5

'Set.toArray()' не сохраняет порядок элементов. Есть ли способ сохранить порядок? –

+0

@italo Почему -1? пожалуйста, объясните –

1

Если вам нужны уникальные значения, вы должны использовать реализацию интерфейса SET

2

Вы можете легко сделать это с помощью Hashmap. У вас, очевидно, есть ключ (который является строковыми данными) и некоторые значения.

Петля на всех ваших линиях и добавьте их на свою карту.

Map<String, List<Integer>> map = new HashMap<>(); 
... 
while (s.hasNext()){ 
    String stringData = ... 
    List<Integer> values = ... 
    map.put(stringData,values); 
} 

Обратите внимание, что в этом случае вы будете держать последний вхождение дублирующих линий. Если вы предпочитаете держать в начале и удалять остальные, вы можете добавить чек с Map.containsKey(String stringData); перед тем, как положить карту.

4

Вы можете использовать Set. Это коллекция, которая не принимает дубликаты.

3

Использование Set

 ... 
     Set<String> list = new HashSet<>(); 
     while (s.hasNext()){ 
     list.add(s.next()); 
     } 
     ... 
0

Вы можете прочитать из файла на карту, где ключ является дата и пропустить, если весь ряд, если дата уже на карте

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

     int i = 0; 
     String lastData = null; 
     while (s.hasNext()) { 
      String str = s.next(); 
      if (i % 13 == 0) { 
       if (map.containsKey(str)) { 
        //skip the whole row 
        lastData = null; 
       } else { 
        lastData = str; 
        map.put(lastData, new ArrayList<String>()); 
       } 
      } else if (lastData != null) { 
       map.get(lastData).add(str); 
      } 


      i++; 
     } 
40

Попробуйте проверить для дубликатов с методом .contains() в ArrayList перед добавлением нового элемента.

Это будет выглядеть как этот

if(!list.contains(data)) 
     list.add(data); 

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

+5

Это будет работать, но не забудьте сделать это синхронизированным, иначе вы просите о неприятностях – Dmitri

+1

Это влияет на производительность, если у него большие данные? Думаю, так и будет. – Amt87

+1

@ Amt87 Это тест на членство. Должен быть вызов O (log n) не более. Если вы хотите сохранить порядок элементов, я не думаю, что мы можем это сделать лучше. –

1

Просто переопределить метод boolean equals() настраиваемого объекта. Скажем, у вас есть ArrayList с настраиваемым полем f1, f2, ... переопределить

@Override 
public boolean equals(Object o) { 
    if (this == o) return true; 
    if (!(o instanceof CustomObject)) return false; 

    CustomObject object = (CustomObject) o; 

    if (!f1.equals(object.dob)) return false; 
    if (!f2.equals(object.fullName)) return false; 
    ... 
    return true; 
} 

и проверить с помощью метода ArrayList экземпляра содержит(). Вот и все.

12
HashSet hs = new HashSet(); 
       hs.addAll(arrayList); 
       arrayList.clear(); 
       arrayList.addAll(hs); 
3
//Saving each element of the input file in an arraylist 
    ArrayList<String> list = new ArrayList<String>(); 
    while (s.hasNext()){ 
     list.add(s.next()); 
    } 

//That's all you need 
list = (ArrayList) list.stream().distinct().collect(Collectors.toList());