Страницы

Поиск по вопросам

четверг, 11 апреля 2019 г.

Как определить метод для делегата автоматически?

Если заголовок не понятен, то объясню другими словами. Есть, например ExecutedRoutedEventHandler. Как мне быстро получить из него
void FirstPageCommand(object sender, ExecutedRoutedEventArgs e) {
}
? Короче как можно быстро раскрыть хандлер в функцию в коде? Напечатал я такой ExecutedRoutedEventHandler +=, чего нибудь нажал, а функция бы создалась сама. Может есть горячие клавиши для этого? А то приходится возвращаться к хандлеру, наводить на него, чтобы посмотреть типы параметров.


Ответ

Пишете ExecutedRoutedEventHandler +=, потом нажимаете Tab -- добавляется название сгенеренного метода, потом еще раз Tab -- генерится сам метод.

Программно не отображается кнопка Android

Почему-то не отображается кнопка при программном написании кода, хотя тот же TextView исправно отображается. В чем может быть проблема?
import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.view.ViewGroup; import android.widget.Button; import android.widget.LinearLayout; import android.widget.TextView;
public class MainActivity extends Activity { /** * Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
LinearLayout layout = new LinearLayout(this); layout.setOrientation(LinearLayout.VERTICAL); ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
TextView tv = new TextView(this); tv.setText("TextView"); tv.setLayoutParams(params); layout.addView(tv);
Button btn = new Button(this); btn.setText("Button"); btn.setLayoutParams(params);
layout.addView(btn);
setContentView(layout, params); } }


Ответ

Проблема в том, что первая добавленная вами View (TextView) занимает всё пространство контейнера и для кнопки не осталось места. Вы это задали через LayoutParams.MATCH_PARENT
Засим вам надо заменить MATCH_PARENT на WRAP_CONTENT

Некорректный совет среды разработки или я неверно понимаю правила языка?

Есть класс Account обладающий списком ArrayList cardList. В цикле мне требуется искать подходящий объект класса Card, и при соблюдении требуемых параметров обновлять строку и обновлять сам объект класса Card из списка cardList
for (int i = 0; i < cardList.size(); i++) { if (cardList.get(i).multi_parent != null && cardList.get(i).multi_parent.equals(multi_parentEntry)) { outputStr += cardList.get(i).balance; cardList.get(i).multi = true; }
}
Среда разработки Idea предупреждает, что 'for' loop replaceable with 'foreach'.
Поясните, пожалуйста, в чем тут проблема? Если я верно понимаю предупреждение, среда разработки предлагает использовать более компактный способ объявления цикла - foreach, но тут возникает вопрос - разве при объявлении цикла подобным образом
for (Card card: cardList) { if (card.multi_parent != null && card.multi_parent.equals(multi_parentEntry)) { outputStr += card.balance; card.multi = true; } }
разве будет обновляться параметры объектов из списка (в моем случае каждый объект класса Card из списка cardList)?


Ответ

Возьмём следующий код:
ArrayList cardList; for (Card card : cardList) { // . . . card.multi = true; }
Фактически этот код эквивалентен следующему:
ArrayList cardList; for (Iterator iter = cardList.iterator; iter.hasNext(); ) { Card card = iter.next(); // . . . card.multi = true; }
На самом деле цикл foreach будет развёрнут в цикл с итераторами и foreach просто более короткая запись этого цикла. В коде с итераторами видно, что никаких копий элементов списка не создаётся, а в переменной card хранится ссылка на объект из списка. Поэтому изменение переменной card меняет элемент списка.
Тем самым, предложение IntelliJ IDEA абсолютно верно, предложенный ею код эквивалентен исходному.

Анимация ширины StackPanel XAML

Есть скрытый StackPanel, имитирующий нечто вроде выпадающего списка. Он должен появляться аннимируя свою прозрачность от 0 до 1, ширину от 100 до 264 и высоту от 30 до автоматической. Пишу код:





Проблема в том, что прозрачность анимируется нормально, а вот ширина как была 100 так и остается. Значение "Auto" для параметра Height вообще выдает исключение XamlParseException.
UPD. Код немного исправлен, в частности StackPanel обернут в Border для границы и скругления углов. Анимация перенесена на Border. Grid - это подложка под всплывающее окно. Теперь он выглядит так:




Ответ

Проблема решилась добавлением к анимации EnableDependentAnimation="True"

SQL запрос (GROUP BY, HAVING), выборка с одним типом записей

Есть такая таблица воздушных судов:
ak_code bnum craft_type AA RA-85205 T154 AA RA-85162 T154 AA RA-26305 AN26 BB RA-85343 T154 CC RA-96002 IL96 CC RA-96012 IL96 CC RA-96016 IL96
Мне надо одним запросом получить такие авиакомпании (ak_code), у которых есть более одного борта (bnum), но при этом все суда только одного типа (craft_type).
Пока придумал только это:
select ak_code,craft_type from crafts where ak_code in( select ak_code from crafts group by ak_code having count(bnum)>1 ) group by ak_code,craft_type
в результате чего получаем:
ak_code craft_type AA AN26 AA T154 CC IL96
Правильным должно быть
ak_code craft_type CC IL96
Подскажите, я на волоске от правильного решения или совсем не в ту сторону ушел? -_-


Ответ

Что то в этом роде:
select ak_code,craft_type from crafts where ak_code in( select ak_code from crafts group by ak_code having count(bnum)>1 -- Количество бортов более 1 (аналогично count(1)) and count(distinct craft_type)=1 -- Только один уникальный тип ВС ) group by ak_code,craft_type
Но если дословно следовать тексту и нужны только авиакомпании, то внутреннего подзапроса достаточно самого по себе. Внешний запрос уже выводит типы судов по найденным авиакомпаниям.
update: по предложениям pegoopik
select ak_code,max(craft_type) from crafts group by ak_code having count(bnum)>1 and max(craft_type)=min(craft_type)

Как правильно сделать синхронизацию?

Практикуюсь работать с синхронизацией потоков и не получается сделать так, как придумал. У меня есть аккаунт в банке, муж и жена кладут туда деньги. Я хочу сделать так, чтоб они по очереди это делали. Я делаю это так:
public class Main { public static void main(String[] args) { new Wife().start(); new Husband().start(); } }
public class Husband extends Thread{ @Override public void run() { super.run(); for (int i = 0; i < 10; i++) { System.out.println("Husband " + i + " " + Account.deposit()); } } }
public class Wife extends Thread{ @Override public void run() { super.run(); for (int i = 0; i < 10; i++) { System.out.println("Wife " + i + " " + Account.deposit()); } } }
public class Account { public synchronized static int deposit(){ account += 300; return account; } }
Но все равно получается бардак. Может вместо synchronized нужно семафоры использовать? Чтоб была правильная очередность.


Ответ

Сейчас нет возможности обдумать элегантное решение, но я бы приоритеты задавал. Вот решение в лоб:
public class App { public static void main(String[] args) { Account account = new Account(0); new Wife(account).start(); new Husband(account).start(); }
public static abstract class FamilyMember extends Thread {
protected Account mAccount; protected String mId;
public FamilyMember(Account account) { mAccount = account; }
@Override public void run() { super.run(); startMe(); }
protected abstract void startMe(); }
public static class Husband extends FamilyMember {
public Husband(Account account) { super(account); mId = getClass().getName(); mAccount.registerMember(getClass().getName()); }
@Override protected void startMe(){ for (int i = 0; i < 10; i++) { try { while(!mAccount.CheckPriority(mId)) Thread.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Husband " + i + " " + mAccount.deposit(mId)); } } }
public static class Wife extends FamilyMember {
public Wife(Account account) { super(account); mId = getClass().getName(); mAccount.registerMember(getClass().getName()); }
@Override protected void startMe(){ for (int i = 0; i < 10; i++) { try { while(!mAccount.CheckPriority(mId)) Thread.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Wife " + i + " " + mAccount.deposit(mId)); } } }
public static class Account {
private int mAccount = 0;
private List mMembers = new ArrayList();
/** * проверяем имеет ли член семьи максимальный приоритет * @param id * @return */ public synchronized boolean CheckPriority(String id){ Member member = mMembers.stream().max(Comparator.comparingInt(Member::getPriority)).get(); return member.getId().equals(id); }
public void registerMember(String id){ mMembers.add(new Member(id, 0)); }
public Account(int account) { mAccount = account; }
public synchronized int deposit(String id) { mAccount += 300; // понижаем приоритет mMembers.stream().filter(member -> member.mId.equals(id)).findFirst().get().decPriority(); return mAccount; }
public static class Member{
public String mId; public int mPriority;
public Member(String id, int priority){ mId = id; mPriority = priority; }
public void decPriority(){ mPriority--; }
public int getPriority(){ return mPriority; }
public String getId(){ return mId; } } } }
Выведет:
Wife 0 300 Husband 0 600 Wife 1 900 Husband 1 1200 Wife 2 1500 Husband 2 1800 Wife 3 2100 Husband 3 2400 Wife 4 2700 Husband 4 3000 Wife 5 3300 Husband 5 3600 Wife 6 3900 Husband 6 4200 Wife 7 4500 Husband 7 4800 Wife 8 5100 Husband 8 5400 Wife 9 5700 Husband 9 6000
Потоки, перед тем как внести деньги на счёт, проверяют свой приоритет с помощью CheckPriority. Если текущий поток имеет больший приоритет, то вносятся деньги mAccount.deposit(mId) и понижается текущий приоритет
mMembers.stream().filter(member -> member.mId.equals(id)).findFirst().get().decPriority();
Иначе засыпает на 1мс.

Нужна помощь в табуляции треугольника Паскаля

Всем привет! Я только недавно начал учить Java и решил сделать для себя небольшой квест, который поможет мне освоить особенности этого языка. Я переделываю свои лабораторные с C++. Случилась у меня одна загвоздка: я не могу красиво построить треугольник Паскаля. Идея состоит в том, чтобы в цикле при заполнении треугольника писать стринговую переменную из пробелов и в каждой новой строке выводить ее значение, но на один пробел меньше. Код прилагаю. Большое вам спасибо :)
public class Paskal { public static final int LINES = 10;
public static void main(String[] args) { String MySpace = " "; int[][] p = new int [LINES][]; p[0] = new int[1]; System.out.print(MySpace); System. out. println (p[0][0] = 1);
p[1] = new int[2];
p[1][0] = p[1][1] = 1; System.out.print(MySpace + "" ); System.out.println(p[1][0] + " " + p[1][1]);
for (int i = 2; i < LINES; i++){ p[i] = new int[i+1]; System.out.print(MySpace); System.out.print((p[i][0] = 1) + " ");
for (int j = 1; j < i; j++) System.out.print((p[i][j] = p[i-1][j-1] + p[i-1][j]) + " ");
System.out.println(p[i][i] = 1); } } }


Ответ

Можно воспользоваться форматированным выводом (System.out.printf, String.format, java.util.Formatter и компания), тогда каждое число будет занимать фиксированное количество символов, и отступ можно будет просто посчитать. Если еще вынести вывод всей строки в отдельный метод (и заодно отделить вычисления от вывода), то даже не очень страшно выглядит:
static final int LINES = 10;
// шаблон для форматирования числа: число занимает до пяти символов, недостающие // дополняются проблелами слева, затем один пробел // Полный синтаксис: // https://docs.oracle.com/javase/8/docs/api/java/util/Formatter.html#syntax // аналогично printf в С static final String NUMBER_FORMAT = "%5d "; // Длина одного форматированного числа (5 знаков под число и пробел) static final int NUMBER_STRING_LENGTH = 6;
// максимальное количество чисел в строке совпадает с количеством строк // длина этой строки в символах = число строк * длина одного числа static final int MAX_LINE_LENGTH = LINES * NUMBER_STRING_LENGTH;
// запас пробелов static final String SPACES = " "; static void printArray( int[] array ) { // мы знаем количество чисел в строке (array.length), // длину каждого числа в символах и длину самой длинной строки // чтобы отцентрировать нашу строку, нужно отступить на половину // разницы между нашей строкой и самой длинной // SPACES.substring создает строку с нужным количеством пробелов System.out.print( SPACES.substring( 0, (MAX_LINE_LENGTH - NUMBER_STRING_LENGTH * array.length)/2 ) );
for ( int i = 0; i < array.length; i++ ) System.out.printf( NUMBER_FORMAT, array[i] );
System.out.println(); }
public static void main(String[] args) { int[][] p = new int[LINES][]; p[0] = new int[] {1}; printArray( p[0] );
for (int i = 1; i < LINES; i++) { p[i] = new int[i + 1];
p[i][0] = 1;
for (int j = 1; j < i; j++) p[i][j] = p[i - 1][j - 1] + p[i - 1][j];
p[i][i] = 1;
printArray( p[i] ); } }
Вывод:
1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 1 5 10 10 5 1 1 6 15 20 15 6 1 1 7 21 35 35 21 7 1 1 8 28 56 70 56 28 8 1 1 9 36 84 126 126 84 36 9 1

Сменить цвет таба в TabLayout

Есть TabLayout с некоторым количеством табов, добавляемых с помощью ViewPager. Каким образом выделить один таб среди остальных? К примеру, нужно чтобы 2 таб имел отличный от других цвет. Или же проще будет изменить цвет текста в этом табе? Как можно это реализовать? Пока в голову идет только создание customView, что-то такое:
tabLayout.getTabAt(2).setCustomView(...);


Ответ

Попробуйте таким способом:
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabLayout); ViewGroup vg = (ViewGroup) tabLayout.getChildAt(0); ViewGroup vgTab = (ViewGroup) vg.getChildAt(tabCustomNumber); vgTab.setBackgroundColor(tabCustomColor);

java методы и их параметры - влияние передачи через аргументы больших данных на производительность

Как влияет на быстродействие программы то, что я передаю от метода к методу параметр, имеющий большой объем данных. К примеру переменную типа BufferedReader, в которой содержится контент объемом 3 мегабайта?
Или на скорость работы программы это не влияет?


Ответ

В java объекты всегда передаются только по ссылке (за исключением примитивов, т.е. всегда будет прокидываться лишь ссылка объект, передаваемый параметром в метод, которая занимает всего 4 байта, хотя на самом деле зависит от разрядности системы: на 32-разрядной - 4 байта, на 64-разрядной - 8 байт). Таким образом, это абсолютно не критично, по крайней мере, необходимо выполнить просто неимоверное количество передач параметров по ссылке, чтобы это возымело серьезные последствия на современных машинах.
Если, конечно, вы не копируете это объект прямо в теле метода (правда зачем?).
Правда, стоит быть аккуратным при autoboxing'е примитивов при передаче в качестве параметров в функцию и при работе с контейнерами, подробнее можете прочитать здесь

Почему False and str возвращает False, но True and str возвращает str?

Понимаю, что в Python применются ленивые вычисления, но мне кажется это настоящие грабли. Вот реальный пример: (sqlalchemy_migrate)
funcname = upgrade and "upgrade" or "downgrade"
То есть в зависимости от значения upgrade (True или False), переменная получит соответствующее имя. С ходу довольно сложно понять, что вернет такое выражение. Кроме того, bool and str может вернуть как bool, так и str, в зависимости от того, чему равен bool. Считаете ли вы такой подход рациональным?


Ответ

Насколько я понимаю, у Вас нет вопроса, как именно вычисляется выражение в примере, но все же напишу. Т.к. приоритет and и or одинаков, и эти операторы левоассоциативны, то
upgrade and "upgrade" or "downgrade"
эквивалентно
(upgrade and "upgrade") or "downgrade"
Первым вычисляем выражение в скобках, оно равно False если upgrade == False(1), или "upgrade", если upgrade == True(2). В итоге имеем
(1) False or "downgrade" --> "downgrade" (2) "upgrade" or "downgrade" --> "upgrade" (т.к. "upgrade" - истинно)

П.С. Лично мне именно эта строчка также кажется не слишком читаемой. Вообще, здесь явно напрашивается использование тернарного оператора, который имеется в Питоне, хотя и синтаксически отличается от тернарного оператора в большинстве других языков:
funcname = "upgrade" if upgrade else "downgrade"
Это всего на один символ длиннее, но бывают случаи, когда подобная запись действительно удобна и читаема:
do_something() or do_something_else()
do_something_else выполнится только в том случае, если do_something вернет False (например, что-то пошло не так). Это, фактически, стандартная идиома для языка perl, в Питоне я что-то подобное встречал значительно реже.

Запрос в SQL (сортировка)

Есть Таблица CITIES, в которой две колонки ID и City. City - список городов РФ. Надо написать SQL запрос, который вернет из таблицы CITIES список всех городов РФ, отсортированных в следующем порядке
Первое место - Москва Второе место - Санкт-Петербург Все последующие места - остальные города РФ, отсортированные в алфавитном порядке от А до Я
Я Попробовал вот так, но не получается.
Select City From Cities where City = 'Moscow' UNION Select City From Cities where City = 'Sankt-Peterburg' UNION Select City From Cities where City !='Moscow' And City != 'Sankt-Peterburg' Order by City


Ответ

MySQL:
select Id, City from Cities order by -field(City, 'Санкт-Петербург','Москва'), City
Функция field() возвращает порядковый номер строки в списке аргументов, если строка не найдена - возвращает 0. В данном случае мы берем ее отрицательной. В итоге Москва даст -2, Спб -1, любые другие города 0. -2 будет первым в порядке сортировки.
Произвольные SQL:
select Id, City from Cities order by case City when 'Москва' then 1 when 'Санкт-Петербург' then 2 else 3 end, City
UPD: Для MSSQL короткая нотация через функцию поиска позиции строки:
select Id, City from Cities order by -patindex('%$'+City+'$%','$Санкт-Петербург$Москва$'), City
И универсальный вариант, что бы потом, не меняя запроса, можно было выносить города в начало: В ту-же таблицу или в отдельную добавляем колонку с порядком сортировки. Если отдельной таблицей, то так:
create table CitySort(City varchar(100) not null primary key, srt int); -- Хотя конечно по ID было бы более правильно, чем по названию ... insert into CitySort values('Москва',1), ('Санкт-Петербург',2);
select Id, City from Cities a left join CitySort s on s.City=a.City order by coalesce(s.srt,99999), City

делегирование конструкторов в Java

Здравствуйте! Сколько ни разбирался, не могу понять, что значит делегирование конструкторов в Java. Прошу помощи разобраться в этом моменте. Спасибо.


Ответ

Все просто - это когда один конструктор может быть вызван другим конструктором изнутри класса с использованием ключевого слова this и списка аргументов.
Например, есть класс Person и есть конструктор, в котором параметры имя и возраст.
class Person { private String name; private String age; private String email;
public Person(String name, String age) { this.name = name; this.age = age; } }
Допустим мы хотим еще конструктор, но у которого параметры будут имя, возраст и email. Вместо того, чтобы дублировать код из первого конструктора и дописывать еще параметр, типа такого:
public Person(String name, String age, String email) { this.name = name; this.age = age; this.email = email; }
достаточно вызвать другой конструктор с параметрами, а остальное сделать в данном:
class Person { private String name; private String age; private String email;
public Person(String name, String age) { this.name = name; this.age = age; }
public Person(String name, String age, String email) { this(name, age); this.email = email; } }
А вот еще захотел я конструктор добавить)) Сколько тут дубля можно избежать, можно представить.
class Person { private String name; private String age; private String email; private String sex;
public Person(String name, String age) { this.name = name; this.age = age; }
public Person(String name, String age, String email) { this(name, age); this.email = email; }
public Person(String name, String age, String email, String sex) { this(name, age, email); this.sex = sex; } }
Таким образом вместо захламления дублем, копипаста кода в еще один конструктор - мы даем часть обязанностей в конструктор, который уже делает подобные вещи.
Если, например, есть штук 5 конструкторов с разными и множеством параметров - не придется копипастить код везде, а лишь перенаправить некоторые вещи с одного конструктора в другой.

Thread и jdbc одно соединение

Не знаю многих нюансов в Java. Интересует, можно ли создать одно соединение с mysql и работать с ним в потоках, или в каждом потоке, нужно создавать дополнительный экземпляр соединения? Более 30 потоков, приводит к ошибке mysql: Too many connections. Снял ограничение mysql, такким образом:
set global max_connections = 200;
Но это не выход и хотелось бы знать на будущие, как правильно. Вот код:
public class ParserMain { public static void main(String[] args) throws java.io.IOException { // Общее число сообщений int total_entries = 12000; // Кол-во потоков int thread_count = 25; // Кол-во записей на поток int entries_thread = total_entries / thread_count; // Начальный инкремент потока int thread_end; // Конечный инкремент потока int thread_start;
for (int i = 1; i <= thread_count; ++i) { thread_end = i * entries_thread; thread_start = thread_end - entries_thread; new ParserThread(thread_start, thread_end).start(); } } }
public class ParserThread extends Thread { private int jstart; private int jend;
protected Connection conn; protected PreparedStatement ps; protected Statement st; protected ResultSet rs;
public ParserThread(int jstart, int jend) { this.jstart = jstart; this.jend = jend; }
public void run() { String dbDriver = "org.gjt.mm.mysql.Driver"; String dbHost = "jdbc:mysql://localhost/test?autoReconnect=true";
try { Class.forName(dbDriver); conn = DriverManager.getConnection(dbHost, "root", ""); } catch (Exception e) { System.err.println(e.getMessage()); } } }


Ответ

Да можно создать как и многопоточное подключение к БД так и один поток используя синхронизированный метод(Что конечно не рационально с точки зрения производительности) Тут небольшое лирическое отступление:
JDBC Drivers - является набор классов Java, который позволяет подключаться к определенной базе данных. JDBC Drivers реализует много интерфейсов JDBC. Когда ваш код использует данный драйвер JDBC, он на самом деле просто использует стандартные интерфейсы JDBC.Таким образом, вы можете изменять драйвер JDBC не изменяя кода Connections - после того, как Driver JDBC загружается и инициализируется, необходимо подключиться к базе данных. Это можно сделать, получив Connection к базе данных через JDBC API, и загруженный Driver. Вся связь с базой данных происходит через Connection. Приложение может иметь более одного Connection открытого к базе данных одновременно. Statements - используете для выполнения запросов и обновлений в базе данных. Есть несколько различных типов Statements. Каждый Statements соответствует одному запросу или обновлению. ResultSets - при выполнении запроса к базе данных вы получите обратно ResultSet. Вы можете пройти по ResultSet и прочитать результат запроса.
Основной бонус от содержания ConnectionsPool(Пула готовых к работе соеденений) это отсутствие затрат на открытие каждого нового соединения.Такие готовые пулы представляют многие веб контейнеры.Да и написать свою реализацию в общем то обыденная задача.Лимиты с которыми Вы столкнулись вопрос СУБД... А вот минусы от использования многопоточного подключения это возможные неприятности связанные с параллельной записью или обращением в БД...Как то:
потерянное обновление (lost update) — при одновременном изменении одного блока данных разными транзакциями, одно из изменений теряется; «грязное» чтение (dirty read) — чтение данных, добавленных или изменённых транзакцией, которая впоследствии не подтвердится (откатится); неповторяющееся чтение (non-repeatable read) — при повторном чтении в рамках одной транзакции, ранее прочитанные данные оказываются изменёнными; фантомное чтение (phantom reads) — Одна транзакция в ходе своего выполнения несколько раз выбирает множество строк по одним и тем же критериям. Другая транзакция в интервалах между этими выборками добавляет или удаляет строки или изменяет столбцы некоторых строк, используемых в критериях выборки первой транзакции, и успешно заканчивается. В результате получится, что одни и те же выборки в первой транзакции дают разные множества строк.
Все в принципе лечиться уровнями изоляции транзакции.О чем рекомендую почитать отдельно...

Как в Android Studio отметить методы(сделать закладки)?

Погуглил, но не могу найти инфы. Не могу сформулировать, что мне нужно. Но суть такая. Можно ли в студии как то отметить функции в избранное? Вот у меня код на 1000 строк можно ли как то выбрать 3, 4 функции для быстрого поиска, чтоб не скролить код вниз вверх в поисках нужного метода?


Ответ

Я присоединяюсь к комментарию Abrog Petrovich в Android Studio, как и в IDEA есть bookmarks - закладки. Вы можете ставить их находясь на строчке клавишей F11 и открывать окно bookmark сочетанием shift+F11.
Хочу добавить, что их очень удобно добавлять клавишей Ctrl + ЛКлавишаМыши рядом с номером строки и также удобно без окна вызывать их, переключаясь клавишей мыши на черный скролл справа, быстрое перемещение.

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

Как присвоить статическому полю clients результат статического метода makeMassClient?
class GPR extends JFrame implements MouseListener, ListSelectionListener { static Client[] clients=BankingSystem.Parser.makeMassClient("D://clients.out");
Проблема в том, что справа от равно появляется синтаксическая ошибка "Unhandled exception type IOException".
Multiple markers at this line Unhandled exception type IOException Unhandled exception type IOException


Ответ

Используйте, например, статический блок инициализации:
static Client[] clients = null; static { try { clients = BankingSystem.Parser.makeMassClient("D://clients.out"); } catch(IOException e) { // Обработка исключения... } }

Как проверить, пуст ли layout

Есть layout, в который в процессе работы приложения могут быть добавлены view или удалены из него. Может случится так, что все view из layout будут удалены. Можно ли как-то проверить, пуст ли layout?
Примерно так:
if (R.id.layout1 == (пуст ?) ) {что-то там происходит}


Ответ

Просто проверьте кол-во детей вашего контейнера. Если оно 0 - значит он пуст.
long birthTimeInMills = System.currentTimeMillis(); SomeContainerLayoutClassName someLayout = new SomeContainerLayoutClassName(context); int numOfChildren = someLayout.getChildCount(); if(numOfChildren == 0) { long lifeTimeInMills = System.currentTimeMillis() - birthTimeInMills; System.out.println("Контейнеру уже " + lifeTimeInMills + " миллисекунд, а у него всё ещё нет детей"); }

Строковая переменная с одинаковым значениям в двух случаях обрабатывается по разному. Почему? [дубликат]

На данный вопрос уже ответили: Как работает оператор == 1 ответ Почему этот код вызывает блок if?
String word = ""; String push = "push"; Scanner s = new Scanner(System.in); while(true) { word = push; if (word == "push") { n = 3; push(n); System.out.println(""); } }
А этот код нет, хотя через дебаггер проверял что там, что там "word" переменная принимает значение "push".
String word = ""; String push = "push"; Scanner s = new Scanner(System.in); while(true) { word = s.nextLine(); if (word == "push") { n = 3; push(n); System.out.println(""); } }


Ответ

В чем заключается проблема:
Вы сравниваете строки посредством оператора ==, который просто сравнивает на равенство ссылки на объекты, а не их содержимое (за исключением примитивов).
Ссылки на объекты не равны из-за интернирования строк (т.е. из-за использования String pool). В вашем случае строки, получающиеся сложением/присваиванием констант, вычисляются во время компиляции и далее строковые литералы (в одном/разных классе(ах) и в одном/разных пакете(ах)) представляют собой ссылки на один и тот же объект. Именно поэтому в первом случае ссылки оказываются равны, а во втором нет, так как метод nextLine() возвращает ссылку на строку не из пула.
Подробнее о том, как работает оператор == можно посмотреть здесь

Пути решения:
Сравнивайте строки посредством метода equals
if ("push".equals(word))
Причем, в вашем случае, метод применяйте к строковому литералу, так как если применить к переменной word, которая может оказаться null, то вылетит исключение.

Чисто для информации:
Также корректно отработает вариант, при котором вы принудительно засунете второй объект в пул посредством метода intern
if ("push" == word.intern())
Тот факт, что данный метод отработает корректно в вашем случае совсем не означает, что так и следует делать!

Как сохранить app в arr архив?

Почему для модуля можно создвть arr a для app только apk? В чем вообще отличие app от модуля я не вижу в gradle разницы. Но Android Studio как-то их отличает...

apply plugin: 'com.android.application'
android { compileSdkVersion 23 buildToolsVersion "23.0.2" defaultConfig { applicationId "com.android.myapplication" minSdkVersion 16 targetSdkVersion 23 versionCode 1 versionName "1.0" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } productFlavors { } }
dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:23.1.1' }

apply plugin: 'com.android.library'
android { compileSdkVersion 23 buildToolsVersion "23.0.2"
defaultConfig { minSdkVersion 16 targetSdkVersion 23 versionCode 1 versionName "1.0" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } }
dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:23.1.1' }


Ответ

Формат aar - это формат упаковки android-библиотеки (Android Library Format)/ Естественно, что сохранить в этот формат можно библиотеку, а не приложение.
О типе получаемого на выходе файла говорит строка apply plugin, где соответственно указывается библиотека это (library) или приложение (application)
Вы можете сделать из своего приложения библиотеку (заменить apply plugin: 'com.android.application' на apply plugin: 'com.android.library') и собрать ее в aar-формат

Теория по односвязному списку

Здравствуйте.
Довольно часто на собеседованиях или же в тестовых заданиях (для прохождения на стажировку, например) задается вопрос об односвязных списках
Например, дают задачу, в которой необходимо развернуть односвязный список за О(n) времени. Так вот, как это сделать? Можно ли просто переопределить ссылки? Т.е. сделать за 1 итерацию так, чтобы не A->B, а A<-B ?
Можете, пожалуйста, привести пример? Заранее благодарю


Ответ

Первая ссылка из гугла.
void reverse(OneWayList list){ OneWayList.Node node = list.head; OneWayList.Node previous = null; while(node != null){ //next item OneWayList.Node tmp = node.next; //swap items node.next = previous; previous = node; list.head = node; //next item node = tmp; } }
Отсюда

c# блокировка файлов

В php есть возможность одновременного доступа к файлу с блокировками на запись LOCK_EX (экслюзивный доступ для записи) и на чтение LOCK_SH (общий доступ для чтения) Блокировка вызывается после открытия файла через flock
При вызове блокировки поведение зависит от типа блокировки. В общем то оно работает аналогично ReaderWriterLock и в c# для подобного поведения нужно использовать его. Однако ReaderWriterLock в c# работает в рамках одного процесса (и не относится непосредственно к файлам).
Более того windows будет мешать одновременному доступу к файлу с разных процессов.
В c# есть FileShare, но похоже, что это всего лишь разрешение другому процессу открывать файл на такой же тип доступа (из msdn не сильно понятно что но на самом деле)
Приведите пример как в c# сделать такое же поведение блокировки с общим файлом, как в php или его абстрактном аналоге ReaderWriterLock
upd: вижу требуется пояснение какое именно поведение ожидается допустим есть несколько процессов которые почти одновременно хотят
читать читать читать писать читать писать
Первые 3 получат разрешение на одновременное чтение. 4й подождет и получит блок для записи когда первые 3 отпустят файл. 5й будет ждать пока 4й не освободит, а 6й пока не освободит 5й
Так вот варианты FileShare.ReadWrite или FileShare.Write никакой очереди не соблюдают (я проверил 2х писателей и у меня на выходе в файле каша). Они всего лишь указывают, что другой процесс может делать без выброса исключения. Но никак не защищают файлы от одновременной записи.
Если же поставить эксклюзивную блокировку без FileShare, то другие процессы будут получать исключения, что мы и хотим избежать
upd2: и снова никто не понимает в чем проблема.
Проблема: много процессов, которые могут читать и писать в файл.
Цель: защитить общий файл от конкурентного доступа, дабы в один момент только один писатель мог писать. Не "запретить другим доступ",а обеспечить конкурирующий доступ, когда много читателей может много читать одновременно, но писать только один, то есть то, для чего нужен ReaderWriterLock (не вижу я принципиальной разницы между ним и системой блокировки файлов в php)
Вариант "лови исключения и повторяй через 100мс до победного" не выдерживают критики. Писатель, который ждет пока файл освободится, может никогда не дождаться, потому что в эти 100мс куча читателей могут открыть файл для себя. Правильное решение - блокировка для чтения/записи ставится в очередь и в пхп (и не только в нем) это доступно из коробки,но в c# я не нашел как это делается.
Если сказать коротко, то вопрос звучит так: как сделать ReaderWriterLock для файлов, которые шарятся между несколькими процессами?


Ответ

Разобрался в чате, чего же от меня хотелось.
С помощью пары FileAccess/FileShare нужного поведения не добиться. Требуемое поведение в WInAPI доступно через LockFileEx, использование в C# можно увидеть тут: https://stackoverflow.com/questions/1784195/using-lockfileex-in-c-sharp