Методика, используемая здесь, представляет временную задержку при выполнении окончательного действия
static let tapCount = 0
tapButton.addTarget(self, action: #selector(multipleTap(_:event:)), for: UIControl.Event.touchDownRepeat)
// An average user can tap about 7 times in 1 second using 1 finger
DispatchQueue.main.asyncAfter(deadLine: .now() + 1.0 /* We're waiting for a second till executing the target method to observe the total no of taps */ ) {
self.performAction(for: tapCount)
}
@objc func multipleTap(_ sender: UIButton, event: UIEvent) {
tapCount += 1
}
/// Perform the respective action based on the taps
private func performAction(for count: Int) {
// Resetting the taps after 1 second
tapCount = 0
switch (count){
case 2:
// Handle 2 clicks
case 3:
// Handle 3 clicks
case 4:
// Handle 4 clicks
default:
print("Action undefined for count: \(count)")
}
}
public class TEst {
public static void main(String[] args) {
List<Integer> ls=new ArrayList<>();
ls.add(1);
ls.add(2);
List<Integer> ls1=new ArrayList<>();
ls1.add(3);
ls1.add(4);
List<List<Integer>> ls2=new ArrayList<>();
ls2.add(ls);
ls2.add(ls1);
List<List<List<Integer>>> ls3=new ArrayList<>();
ls3.add(ls2);
methodRecursion(ls3);
}
private static void methodRecursion(List ls3) {
for(Object ls4:ls3)
{
if(ls4 instanceof List)
{
methodRecursion((List)ls4);
}else {
System.out.print(ls4);
}
}
}
}
ArrayList<ArrayList<String>> listOLists = new ArrayList<ArrayList<String>>();
ArrayList<String> singleList = new ArrayList<String>();
singleList.add("hello");
singleList.add("world");
listOLists.add(singleList);
ArrayList<String> anotherList = new ArrayList<String>();
anotherList.add("this is another list");
listOLists.add(anotherList);
Если вы действительно хотите знать, что отлично обрабатывают файлы CSV в Java, не стоит пытаться самостоятельно реализовать программу чтения / записи CSV. Проверьте ниже.
http://opencsv.sourceforge.net/
Если ваш CSV-документ содержит двойные кавычки или символы новой строки, вы столкнетесь с трудностями.
Чтобы сначала изучить объектно-ориентированный подход, вам поможет другая реализация (на Java). И я думаю, что это не лучший способ управлять одной строкой в списке. CSV не позволяет вам иметь разный размер столбца.
Вот пример, который считывает список строк CSV в список списков, а затем просматривает этот список списков и выводит строки CSV обратно на консоль.
import java.util.ArrayList;
import java.util.List;
public class ListExample
{
public static void main(final String[] args)
{
//sample CSV strings...pretend they came from a file
String[] csvStrings = new String[] {
"abc,def,ghi,jkl,mno",
"pqr,stu,vwx,yz",
"123,345,678,90"
};
List<List<String>> csvList = new ArrayList<List<String>>();
//pretend you're looping through lines in a file here
for(String line : csvStrings)
{
String[] linePieces = line.split(",");
List<String> csvPieces = new ArrayList<String>(linePieces.length);
for(String piece : linePieces)
{
csvPieces.add(piece);
}
csvList.add(csvPieces);
}
//write the CSV back out to the console
for(List<String> csv : csvList)
{
//dumb logic to place the commas correctly
if(!csv.isEmpty())
{
System.out.print(csv.get(0));
for(int i=1; i < csv.size(); i++)
{
System.out.print("," + csv.get(i));
}
}
System.out.print("\n");
}
}
}
Довольно просто I считать. Еще пара замечаний:
Я рекомендую использовать «Список» вместо «ArrayList» с левой стороны при создании объектов списка. Лучше передать интерфейс «Список», потому что тогда, если позже вам нужно будет использовать что-то вроде вектора (например, теперь вам нужны синхронизированные списки), вам нужно только изменить строку с «новым» оператором. Независимо от того, какую реализацию списка вы используете, например Vector или ArrayList, вы по-прежнему всегда просто передаете List
.
В конструкторе ArrayList, вы можете оставить список пустым, и по умолчанию он будет иметь определенный размер, а затем динамически увеличиваться по мере необходимости. Но если вы знаете, насколько большим может быть ваш список, иногда можно сэкономить на производительности. Например, если вы знали, что в вашем файле всегда будет 500 строк, вы могли бы сделать:
List
> csvList = new ArrayList
> (500);
Таким образом, вы никогда не будете тратить время на обработку, ожидая, когда ваш список будет динамически расти. Вот почему я передаю конструктору "linePieces.length". Обычно не имеет большого значения, но иногда помогает.
Надеюсь, что это поможет!
тогда вы можете сделать: List
> csvList = new ArrayList
> (500);
Таким образом вы никогда не будете тратить время обработки на ожидание динамического роста вашего списка. Вот почему я передаю конструктору "linePieces.length". Обычно не имеет большого значения, но иногда помогает.
Надеюсь, что это поможет!
тогда вы можете сделать: List
> csvList = new ArrayList
> (500);
Таким образом вы никогда не будете тратить время обработки на ожидание динамического роста вашего списка. Вот почему я передаю конструктору "linePieces.length". Обычно не имеет большого значения, но иногда помогает.
Надеюсь, что это поможет!
Пример, предоставленный @tster, показывает, как создать список списка. Я приведу пример перебора такого списка.
Iterator<List<String>> iter = listOlist.iterator();
while(iter.hasNext()){
Iterator<String> siter = iter.next().iterator();
while(siter.hasNext()){
String s = siter.next();
System.out.println(s);
}
}
Что-то вроде этого будет работать для чтения:
String filename = "something.csv";
BufferedReader input = null;
List<List<String>> csvData = new ArrayList<List<String>>();
try
{
input = new BufferedReader(new FileReader(filename));
String line = null;
while (( line = input.readLine()) != null)
{
String[] data = line.split(",");
csvData.add(Arrays.toList(data));
}
}
catch (Exception ex)
{
ex.printStackTrace();
}
finally
{
if(input != null)
{
input.close();
}
}
Я бы поддержал то, что сказал xrath - вам лучше использовать существующую библиотеку для обработки чтения / записи CSV.
Если вы это сделаете, планируете разворачивать собственную структуру, я также предлагаю не использовать List
в качестве своей реализации - вам, вероятно, будет лучше реализовать >
CSVDocument
и CSVRow
классы (которые могут внутренне использовать List
или List
соответственно), хотя для пользователей они предоставляют только неизменяемый список или массив.
Простое использование List
оставляет слишком много непроверенных крайних случаев и полагается на детали реализации - например, заголовки хранятся отдельно от данных? или они находятся в первой строке списка >
List
? Что, если я хочу получить доступ к данным по заголовку столбца из строки, а не по индексу? >
что происходит, когда вы вызываете такие вещи, как:
// reads CSV data, 5 rows, 5 columns
List<List<String>> csvData = readCSVData();
csvData.get(1).add("extraDataAfterColumn");
// now row 1 has a value in (nonexistant) column 6
csvData.get(2).remove(3);
// values in columns 4 and 5 moved to columns 3 and 4,
// attempting to access column 5 now throws an IndexOutOfBoundsException.
Вы можете попытаться проверить все это при записи файла CSV, и это может сработать в некоторых случаях ... но в других вы будете предупреждать пользователя об исключении далеко от того места, где было внесено ошибочное изменение, что затрудняет отладку.